Skip to content

Instantly share code, notes, and snippets.

@abg
Last active June 18, 2018 13:33
Show Gist options
  • Save abg/11063323 to your computer and use it in GitHub Desktop.
Save abg/11063323 to your computer and use it in GitHub Desktop.
Script to serve as a master_ip_{failover,online_change}_script for MHA
#!/bin/bash
# Source the user config - Mostly useful for setting interface, vip, label as desired
# Example:
# # cat /etc/mha/switch.conf
# vip=172.16.3.1
# interface=eth2
# label=eth2:0
config=/etc/mysql-masterha/vip.conf
[ -e "${config}" ] && . "${config}"
# default interface to eth0 if unset
interface=${interface:-eth0}
# default label to $interface:0 if unset
# largely cosematic - label ensure something shows up in ifconfig
label=${label:-${interface}:0}
# Default to some unroutable ip if a vip isn't specified
vip=${vip:-127.0.0.254}
# discover commands from our path
ssh=$(type -p ssh)
ssh_options=""
arping=$(type -p arping)
ip2util=$(type -p ip)
# command for adding our vip
cmd_vip_add="sudo -n $ip2util address add ${vip} dev ${interface} label ${label}"
# command for deleting our vip
cmd_vip_del="sudo -n $ip2util address del ${vip} dev ${interface}"
# command for discovering if our vip is enabled
cmd_vip_chk="sudo -n $ip2util address show dev ${interface} to ${vip%/*}/32"
# command for sending gratuitous arp to announce ip move
cmd_arp_fix="sudo -n $arping -c 1 -U -I ${interface} ${vip%/*}"
vip_stop() {
set -x
rc=0
# ensure the vip is removed
$ssh ${ssh_options} -tt ${ssh_user:-$orig_master_ssh_user}@${orig_master_ip} \
"[ -n \"\$(${cmd_vip_chk})\" ] && ${cmd_vip_del} && sudo ${ip2util} route flush cache || [ -z \"\$(${cmd_vip_chk})\" ]"
rc=$?
$ssh ${ssh_options} ${ssh_user:-$orig_master_ssh_user}@${orig_master_ip} "mysql -ve '/* demoting master*/ SET GLOBAL read_only = 1;'"
set +x
return $rc
}
vip_start() {
set -x
rc=0
# ensure the vip is added
# this command should exit with failure if we are unable to add the vip
# if the vip already exists always exit 0 (whether or not we added it)
$ssh ${ssh_options} -tt ${ssh_user:-$new_master_ssh_user}@${new_master_ip} \
"[ -z \"\$(${cmd_vip_chk})\" ] && ${cmd_vip_add} && ${cmd_arp_fix} || [ -n \"\$(${cmd_vip_chk})\" ]"
rc=$?
$ssh ${ssh_options} ${ssh_user:-$new_master_ssh_user}@${new_master_ip} "mysql -ve '/* promoting master*/ SET GLOBAL read_only=0; START SLAVE;'"
set +x
return $rc
}
vip_status() {
# verify that the vip exists - if not things are pretty misconfigured and needs
# intervention by an administrator - just do a noop here
$ssh ${ssh_options} -tt ${ssh_user}@${orig_master_ip} "/bin/true"
}
# dispatch the requested --command option
dispatch_command() {
case $1 in
start|startssh)
vip_start
;;
stop|stopssh)
vip_stop
;;
status)
vip_status
rc=$?
echo "vip_status exited: $rc"
exit $rc
;;
*)
if [ -z "${1}" ]; then
echo "No command specified"
else
echo "Invalid command '$1'"
fi
exit 64 # EX_USAGE
;;
esac
}
usage() {
echo "Usage: $0 [options]"
return 1
}
# This effectively parses the options specified here:
# https://code.google.com/p/mysql-master-ha/wiki/Parameters#master_ip_failover_script
# https://code.google.com/p/mysql-master-ha/wiki/Parameters#master_ip_online_change_script
parse_commandline() {
local name
local value
for arg in "$@"
do
case $arg in
--command=*) command=${arg#*=} ;;
--ssh_user=*) ssh_user=${arg#*=} ;;
--ssh_options=*) ssh_options=${arg#*=} ;;
--orig_master_ssh_user=*) orig_master_ssh_user=${arg#*=} ;;
--orig_master_host=*) orig_master_host=${arg#*=} ;;
--orig_master_ip=*) orig_master_ip=${arg#*=} ;;
--orig_master_port=*) orig_master_port=${arg#*=} ;;
--orig_master_user=*) orig_master_user=${arg#*=} ;;
--orig_master_password=*) orig_master_password=${arg#*=} ;;
--orig_master_ssh_user=*) orig_master_ssh_user=${arg#*=} ;;
--new_master_ssh_user=*) new_master_ssh_user=${arg#*=} ;;
--new_master_host=*) new_master_host=${arg#*=} ;;
--new_master_ip=*) new_master_ip=${arg#*=} ;;
--new_master_port=*) new_master_port=${arg#*=} ;;
--new_master_user=*) new_master_user=${arg#*=} ;;
--new_master_password=*) new_master_password=${arg#*=} ;;
--new_master_ssh_user=*) new_master_ssh_user=${arg#*=} ;;
--new_master_ssh_user=*) new_master_ssh_user=${arg#*=} ;;
--orig_master_is_new_slave) orig_master_is_new_slave=1 ;;
*)
echo "Invalid option: ${arg}"
usage
exit $?
;;
esac
done
}
parse_commandline "$@" || exit $?
dispatch_command "${command}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment