Saltstack Official Galera Formula
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

139 lines
4.5KB

  1. #!/bin/bash
  2. #
  3. # Script to make a proxy (ie HAProxy) capable of monitoring MySQL Cluster nodes properly
  4. #
  5. # Author: Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
  6. # Author: Raghavendra Prabhu <raghavendra.prabhu@percona.com>
  7. # Author: Petr Michalec <pmichalec@mirantis.com>
  8. #
  9. # Documentation and download: https://github.com/epcim/percona-clustercheck
  10. #
  11. # Based on the original script from Unai Rodriguez
  12. #
  13. function httpReply(){
  14. HTTP_STATUS="${1}"
  15. RESPONSE_CONTENT="${2}"
  16. # https://serverfault.com/questions/504756/curl-failure-when-receiving-data-from-peer-using-percona-xtradb-cluster-check
  17. sleep 0.1
  18. if [[ "${HTTP_STATUS}" == "503" ]]
  19. then
  20. echo -en "HTTP/1.1 503 Service Unavailable\r\n"
  21. elif [[ "${HTTP_STATUS}" == "404" ]]
  22. then
  23. echo -en "HTTP/1.1 404 Not Found\r\n"
  24. elif [[ "${HTTP_STATUS}" == "401" ]]
  25. then
  26. echo -en "HTTP/1.1 401 Unauthorized\r\n"
  27. elif [[ "${HTTP_STATUS}" == "200" ]]
  28. then
  29. echo -en "HTTP/1.1 200 OK\r\n"
  30. else
  31. echo -en "HTTP/1.1 ${HTTP_STATUS}\r\n"
  32. fi
  33. echo -en "Content-Type: text/plain\r\n"
  34. echo -en "Connection: close\r\n"
  35. echo -en "Content-Length: ${#RESPONSE_CONTENT}\r\n"
  36. echo -en "\r\n"
  37. echo -en "${RESPONSE_CONTENT}"
  38. echo -en "\r\n"
  39. sleep 0.1
  40. }
  41. if [[ $1 == '-h' || $1 == '--help' ]];then
  42. echo "Usage: $0 <user> <pass> <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file> <timeout>"
  43. exit
  44. fi
  45. # if the disabled file is present, return 503. This allows
  46. # admins to manually remove a node from a cluster easily.
  47. if [ -e "/var/tmp/clustercheck.disabled" ]; then
  48. # Shell return-code is 1
  49. httpReply "503" "MySQL Cluster Node is manually disabled.\r\n"
  50. exit 1
  51. fi
  52. MYSQL_USERNAME="${1-clustercheckuser}"
  53. MYSQL_PASSWORD="${2-clustercheckpassword!}"
  54. AVAILABLE_WHEN_DONOR=${3:-0}
  55. ERR_FILE="${4:-/dev/null}"
  56. AVAILABLE_WHEN_READONLY=${5:-1}
  57. DEFAULTS_EXTRA_FILE=${6:-/etc/my.cnf}
  58. # Timeout exists for instances where mysqld may be hung
  59. # Default value considers the Galera timeouts
  60. TIMEOUT=${7:-18}
  61. EXTRA_ARGS=""
  62. if [[ -n "$MYSQL_USERNAME" ]]; then
  63. EXTRA_ARGS="$EXTRA_ARGS --user=${MYSQL_USERNAME}"
  64. fi
  65. if [[ -n "$MYSQL_PASSWORD" ]]; then
  66. EXTRA_ARGS="$EXTRA_ARGS --password=${MYSQL_PASSWORD}"
  67. fi
  68. if [[ -r $DEFAULTS_EXTRA_FILE ]];then
  69. MYSQL_CMDLINE="mysql --defaults-extra-file=$DEFAULTS_EXTRA_FILE -nNE --connect-timeout=$TIMEOUT \
  70. ${EXTRA_ARGS}"
  71. else
  72. MYSQL_CMDLINE="mysql -nNE --connect-timeout=$TIMEOUT ${EXTRA_ARGS}"
  73. fi
  74. #
  75. # Perform the query to check the wsrep_local_state
  76. #
  77. WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state';" \
  78. 2>${ERR_FILE} | tail -1 2>>${ERR_FILE}; exit ${PIPESTATUS[0]})
  79. mysql_ret=$?
  80. if [[ $mysql_ret -eq 1 || $mysql_ret -eq 127 ]]; then
  81. # hash or command can be used here, but command is POSIX
  82. command -v "$MYSQL_CMD"; mysql_ret=$?
  83. if [[ $mysql_ret -eq 1 ]]; then
  84. # mysql program not found
  85. # => return HTTP 404
  86. # Shell return-code is 3
  87. httpReply "404" "Mysql command not found or service is not running.\r\n"
  88. exit 2
  89. fi
  90. # Failed mysql login
  91. # => return HTTP 401
  92. # Shell return-code is 2
  93. httpReply "401" "Access denied to database.\r\n"
  94. exit 2
  95. fi
  96. if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]
  97. then
  98. # Check only when set to 0 to avoid latency in response.
  99. if [[ $AVAILABLE_WHEN_READONLY -eq 0 ]];then
  100. READ_ONLY=$($MYSQL_CMDLINE -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" \
  101. 2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
  102. if [[ "${READ_ONLY}" == "ON" ]];then
  103. # MySQL Cluster node local state is 'Synced', but it is in
  104. # read-only mode. The variable AVAILABLE_WHEN_READONLY is set to 0.
  105. # => return HTTP 503
  106. # Shell return-code is 1
  107. httpReply "503" "MySQL Cluster Node is read-only.\r\n"
  108. exit 1
  109. fi
  110. fi
  111. # MySQL Cluster node local state is 'Synced' => return HTTP 200
  112. # Shell return-code is 0
  113. httpReply "200" "MySQL Cluster Node is synced.\r\n"
  114. exit 0
  115. else
  116. # MySQL Cluster node local state is not 'Synced' => return HTTP 503
  117. # Shell return-code is 1
  118. if [[ -z "${WSREP_STATUS}" ]]
  119. then
  120. httpReply "503" "Received empty reply from MySQL Cluster Node.\r\nMight be a permission issue, check the credentials used by ${0}\r\n"
  121. else
  122. httpReply "503" "MySQL Cluster Node is not synced.\r\n"
  123. fi
  124. exit 1
  125. fi