114 lines
3.6 KiB
Django/Jinja
114 lines
3.6 KiB
Django/Jinja
#!/bin/bash
|
|
#
|
|
# Script to make a proxy (ie HAProxy) capable of monitoring Percona XtraDB
|
|
# Cluster nodes properly
|
|
#
|
|
# Authors:
|
|
# Raghavendra Prabhu <raghavendra.prabhu@percona.com>
|
|
# Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
|
|
#
|
|
# Based on the original script from Unai Rodriguez and Olaf
|
|
# (https://github.com/olafz/percona-clustercheck)
|
|
#
|
|
# Grant privileges required:
|
|
# GRANT PROCESS ON *.* TO 'clustercheckuser'@'localhost' IDENTIFIED BY
|
|
# 'clustercheckpassword!';
|
|
set -e
|
|
|
|
# Forward logs to docker log collector
|
|
exec 1>/proc/1/fd/2 2>/proc/1/fd/2
|
|
|
|
if [[ $1 == '-h' || $1 == '--help' ]];then
|
|
echo "Usage: $0 <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file>"
|
|
exit
|
|
fi
|
|
|
|
MYSQL_USERNAME=monitor
|
|
MYSQL_PASSWORD={{ percona.monitor_password }}
|
|
DISCOVERY_SERVICE={{ address("etcd", etcd.client_port) }}
|
|
CLUSTER_NAME={{ percona.cluster_name }}
|
|
AVAILABLE_WHEN_DONOR=${1:-0}
|
|
AVAILABLE_WHEN_READONLY=${2:-1}
|
|
DEFAULTS_EXTRA_FILE=${3:-/etc/my.cnf}
|
|
CURL="curl -sS"
|
|
FIRST_RUN=1
|
|
|
|
# CLUSTER_NAME to be set in enviroment
|
|
# DISCOVERY_SERVICE to be set in enviroment
|
|
|
|
#Timeout exists for instances where mysqld may be hung
|
|
TIMEOUT=10
|
|
|
|
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
|
|
|
|
ipaddr=$(hostname -i | awk ' { print $1 } ')
|
|
hostname=$(hostname)
|
|
|
|
while true
|
|
do
|
|
|
|
if [ $FIRST_RUN -eq 1 ]; then
|
|
sleep 30
|
|
FIRST_RUN=0
|
|
fi
|
|
#
|
|
# Perform the query to check the wsrep_local_state
|
|
#
|
|
|
|
# Race cond, we need to wait 'till mysql is ready, kek
|
|
|
|
WSREP_STATUS=($($MYSQL_CMDLINE -e "SHOW GLOBAL STATUS LIKE 'wsrep_%';" \
|
|
| grep -A 1 -E 'wsrep_local_state$|wsrep_cluster_status$' \
|
|
| sed -n -e '2p' -e '5p' | tr '\n' ' '))
|
|
|
|
if [[ ${WSREP_STATUS[1]} == 'Primary' && ( ${WSREP_STATUS[0]} -eq 4 || \
|
|
( ${WSREP_STATUS[0]} -eq 2 && $AVAILABLE_WHEN_DONOR -eq 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';")
|
|
|
|
if [[ "${READ_ONLY}" == "ON" ]];then
|
|
# Percona XtraDB 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
|
|
date
|
|
echo "Read-only node. Destroying"
|
|
$CURL http://$DISCOVERY_SERVICE/v2/keys/pxc-cluster/$CLUSTER_NAME/$ipaddr/?recursive=true -XDELETE
|
|
fi
|
|
|
|
fi
|
|
# Percona XtraDB Cluster node local state is 'Synced' => return HTTP 200
|
|
# Shell return-code is 0
|
|
date
|
|
echo "Node is fine. Updating TTL"
|
|
$CURL http://$DISCOVERY_SERVICE/v2/keys/pxc-cluster/$CLUSTER_NAME/$ipaddr/ipaddr -XPUT -d value="$ipaddr" -d ttl=30
|
|
$CURL http://$DISCOVERY_SERVICE/v2/keys/pxc-cluster/$CLUSTER_NAME/$ipaddr/hostname -XPUT -d value="$hostname" -d ttl=30
|
|
$CURL http://$DISCOVERY_SERVICE/v2/keys/pxc-cluster/$CLUSTER_NAME/$ipaddr -XPUT -d ttl=30 -d dir=true -d prevExist=true
|
|
else
|
|
# Percona XtraDB Cluster node local state is not 'Synced' => return HTTP
|
|
# 503
|
|
# Shell return-code is 1
|
|
date
|
|
echo "Node state is not Synced. Destroying."
|
|
$CURL http://$DISCOVERY_SERVICE/v2/keys/pxc-cluster/$CLUSTER_NAME/$ipaddr/?recursive=true -XDELETE
|
|
fi
|
|
|
|
sleep 5
|
|
|
|
done
|