|
- #!/bin/bash
- #
- # Script to make a proxy (ie HAProxy) capable of monitoring MySQL Cluster nodes properly
- #
- # Author: Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
- # Author: Raghavendra Prabhu <raghavendra.prabhu@percona.com>
- # Author: Petr Michalec <pmichalec@mirantis.com>
- #
- # Documentation and download: https://github.com/epcim/percona-clustercheck
- #
- # Based on the original script from Unai Rodriguez
- #
-
- function httpReply(){
- HTTP_STATUS="${1}"
- RESPONSE_CONTENT="${2}"
-
- # https://serverfault.com/questions/504756/curl-failure-when-receiving-data-from-peer-using-percona-xtradb-cluster-check
- sleep 0.1
- if [[ "${HTTP_STATUS}" == "503" ]]
- then
- echo -en "HTTP/1.1 503 Service Unavailable\r\n"
- elif [[ "${HTTP_STATUS}" == "404" ]]
- then
- echo -en "HTTP/1.1 404 Not Found\r\n"
- elif [[ "${HTTP_STATUS}" == "401" ]]
- then
- echo -en "HTTP/1.1 401 Unauthorized\r\n"
- elif [[ "${HTTP_STATUS}" == "200" ]]
- then
- echo -en "HTTP/1.1 200 OK\r\n"
- else
- echo -en "HTTP/1.1 ${HTTP_STATUS}\r\n"
- fi
-
- echo -en "Content-Type: text/plain\r\n"
- echo -en "Connection: close\r\n"
- echo -en "Content-Length: ${#RESPONSE_CONTENT}\r\n"
- echo -en "\r\n"
- echo -en "${RESPONSE_CONTENT}"
- echo -en "\r\n"
- sleep 0.1
- }
-
- if [[ $1 == '-h' || $1 == '--help' ]];then
- echo "Usage: $0 <user> <pass> <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file> <timeout>"
- exit
- fi
-
- # if the disabled file is present, return 503. This allows
- # admins to manually remove a node from a cluster easily.
- if [ -e "/var/tmp/clustercheck.disabled" ]; then
- # Shell return-code is 1
- httpReply "503" "MySQL Cluster Node is manually disabled.\r\n"
- exit 1
- fi
-
- MYSQL_USERNAME="${1-clustercheckuser}"
- MYSQL_PASSWORD="${2-clustercheckpassword!}"
- AVAILABLE_WHEN_DONOR=${3:-0}
- ERR_FILE="${4:-/dev/null}"
- AVAILABLE_WHEN_READONLY=${5:-1}
- DEFAULTS_EXTRA_FILE=${6:-/etc/my.cnf}
- # Timeout exists for instances where mysqld may be hung
- # Default value considers the Galera timeouts
- TIMEOUT=${7:-18}
-
- EXTRA_ARGS=""
- if [[ -n "$MYSQL_USERNAME" ]]; then
- EXTRA_ARGS="$EXTRA_ARGS --user=${MYSQL_USERNAME}"
- fi
- if [[ -n "$MYSQL_PASSWORD" ]]; then
- EXTRA_ARGS="$EXTRA_ARGS --password=${MYSQL_PASSWORD}"
- fi
- if [[ -r $DEFAULTS_EXTRA_FILE ]];then
- MYSQL_CMDLINE="mysql --defaults-extra-file=$DEFAULTS_EXTRA_FILE -nNE --connect-timeout=$TIMEOUT \
- ${EXTRA_ARGS}"
- else
- MYSQL_CMDLINE="mysql -nNE --connect-timeout=$TIMEOUT ${EXTRA_ARGS}"
- fi
- #
- # Perform the query to check the wsrep_local_state
- #
- WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state';" \
- 2>${ERR_FILE} | tail -1 2>>${ERR_FILE}; exit ${PIPESTATUS[0]})
- mysql_ret=$?
-
- if [[ $mysql_ret -eq 1 || $mysql_ret -eq 127 ]]; then
- # hash or command can be used here, but command is POSIX
- command -v "$MYSQL_CMD"; mysql_ret=$?
- if [[ $mysql_ret -eq 1 ]]; then
- # mysql program not found
- # => return HTTP 404
- # Shell return-code is 3
- httpReply "404" "Mysql command not found or service is not running.\r\n"
- exit 2
- fi
-
- # Failed mysql login
- # => return HTTP 401
- # Shell return-code is 2
- httpReply "401" "Access denied to database.\r\n"
- exit 2
- fi
-
-
-
- if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]
- then
- # Check only when set to 0 to avoid latency in response.
- if [[ $AVAILABLE_WHEN_READONLY -eq 0 ]];then
- READ_ONLY=$($MYSQL_CMDLINE -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" \
- 2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
-
- if [[ "${READ_ONLY}" == "ON" ]];then
- # MySQL Cluster node local state is 'Synced', but it is in
- # read-only mode. The variable AVAILABLE_WHEN_READONLY is set to 0.
- # => return HTTP 503
- # Shell return-code is 1
- httpReply "503" "MySQL Cluster Node is read-only.\r\n"
- exit 1
- fi
- fi
- # MySQL Cluster node local state is 'Synced' => return HTTP 200
- # Shell return-code is 0
- httpReply "200" "MySQL Cluster Node is synced.\r\n"
- exit 0
- else
- # MySQL Cluster node local state is not 'Synced' => return HTTP 503
- # Shell return-code is 1
- if [[ -z "${WSREP_STATUS}" ]]
- then
- httpReply "503" "Received empty reply from MySQL Cluster Node.\r\nMight be a permission issue, check the credentials used by ${0}\r\n"
- else
- httpReply "503" "MySQL Cluster Node is not synced.\r\n"
- fi
- exit 1
- fi
|