整个脚本的逻辑是让从的Exec_Master_Log_Pos尽可能的追上Read_Master_Log_Pos,它给了10s的限制,如果还是没有追上,则直接将master2设置为主(通过解除read_only属性),其实这里面还是有待商榷的,譬如10s的限制是否合理,还是一定需要Exec_Master_Log_Pos=Read_Master_Log_Pos才切换。
当原主恢复正常后,如何将VIP从master2切回到master1中呢?
#!/bin/bash ###手动执行将主库切换回DB1的操作 mysql_con='mysql -uroot -p123456' echo -e "`date "+%F %H:%M:%S"` -----change to BACKUP manually-----" >> /etc/keepalived/logs/state_change.log echo -e "`date "+%F %H:%M:%S"` -----set read_only = 1 on DB2-----" >> /etc/keepalived/logs/state_change.log $mysql_con -e "set global read_only = 1;" 2>> /etc/keepalived/logs/state_change.log ###kill掉当前客户端连接 echo -e "`date "+%F %H:%M:%S"` -----kill current client thread-----" >> /etc/keepalived/logs/state_change.log rm -f /tmp/kill.sql &>/dev/null ###这里其实是一个批量kill线程的小技巧 $mysql_con -e 'select concat("kill ",id,";") from information_schema.PROCESSLIST where command="Query" or command="Execute" into outfile "/tmp/kill.sql";' $mysql_con -e "source /tmp/kill.sql" 2>> /etc/keepalived/logs/state_change.log sleep 2 ###给kill一个执行和缓冲时间 ###确保DB1已经追上了,下面的repl为复制所用的账户,-h后跟DB1的内网IP log_file_pos=`mysql -urepl -pmysql -h192.168.244.145 -e "show slave status\G;"|egrep -w "Master_Log_File|Read_Master_Log_Pos|Relay_Master_Log_File|Exec_Master_Log_Pos"` Master_Log_File=`echo $log_file_pos|awk '{print $2}'` Read_Master_Log_Pos=`echo $log_file_pos|awk '{print $4}'` Relay_Master_Log_File=`echo $log_file_pos|awk '{print $6}'` Exec_Master_Log_Pos=`echo $log_file_pos|awk '{print $8}'` until [ $Read_Master_Log_Pos = $Exec_Master_Log_Pos -a $Master_Log_File = $Relay_Master_Log_File ] do echo -e "`date "+%F %H:%M:%S"` -----DB1 Exec_Master_Log_Pos($exec_pos) is behind Read_Master_Log_Pos($read_pos), wait......" >> /etc/keepalived/logs/state_change.log sleep 1 done ###然后解除DB1的read_only属性 echo -e "`date "+%F %H:%M:%S"` -----set read_only = 0 on DB1-----" >> /etc/keepalived/logs/state_change.log ssh 192.168.244.145 'mysql -uroot -p123456 -e "set global read_only = 0;" && /etc/init.d/keepalived start' 2>> /etc/keepalived/logs/state_change.log ###重启DB2的keepalived使VIP漂移到DB1 echo -e "`date "+%F %H:%M:%S"` -----make VIP move to DB1-----" >> /etc/keepalived/logs/state_change.log /sbin/service keepalived restart &>> /etc/keepalived/logs/state_change.log echo "DB2 keepalived转为BACKUP状态,线上数据库切换至DB1"|mail -s "DB2 keepalived change to BACKUP" slowtech@126.com 2>> /etc/keepalived/logs/state_change.log echo -e "--------------------------------------------------\n" >> /etc/keepalived/logs/state_change.log
总结:
1. /etc/keepalived/check_mysql.sh和/etc/keepalived/notify_master_mysql.sh必须加可执行权限。
如果前者没有加可执行权限,则master1上将不会绑定VIP,日志直接提示如下信息: