数据库架构:双主复制
master:192.168.8.57
slave1:192.168.8.58
keepalived工具包
keepalived-1.4.5.tar.gz
一、添加非本机IP绑定支持
echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf sysctl -p
二、下载并安装 keepalived
tar
zxvf keepalived-1.4.5.
tar
.gz
cd
keepalived-1.4.5
.
/configure
--prefix=
/usr/local/keepalived/
make
&&
make
install
keepalived 开机自动启动
systemctl enable keepalived
三、配置keepalived
192.168.8.57
# vi /etc/keepalived/keepalived.conf ! Configuration file for keepalived global_defs { router_id 8.57 notification_email { [email protected] } notification_email_from [email protected] smtp_server stmp.163.com smtp_connect_timeout 30 } vrrp_script chk_mysql { script "/etc/keepalived/check_mysql.sh" interval 3 } vrrp_instance V_mysql_1 { state BACKUP interface enp0s3 virtual_router_id 200 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass steven } track_script { chk_mysql } virtual_ipaddress { 192.168.8.88/24 } }
192.168.8.58
! Configuration file for keepalived global_defs { router_id 8.58 notification_email { [email protected] } notification_email_from [email protected] smtp_server stmp.163.com smtp_connect_timeout 30 } vrrp_instance V_mysql_1 { state BACKUP interface enp0s3 virtual_router_id 200 priority 90 advert_int 1 authentication { auth_type PASS auth_pass steven } notify_master /etc/keepalived/notify_master_mysql.sh virtual_ipaddress { 192.168.8.88/24 } }
check_mysql.sh
#!/bin/bash #/etc/keepalived/check_mysql.sh #chmod u+x /etc/keepalived/check_mysql.sh if [ `ps -ef|grep -w "$0"|grep "/bin/sh*"|grep "?"|grep "?"|grep -v "grep"|wc -l` -gt 2 ];then # exit 0 fi mysql_con='/usr/local/mysql/bin/mysql -uroot -pmysql' function excute_query { $mysql_con -e "select 1 from dual;" 2>>/mysql/log/check_mysql.err } function service_error { echo -e "`date "+%F %H:%M:%S"` -----mysql service error,now stop keepalived-----" >> /mysql/log/check_mysql.err /sbin/service keepalived stop &>> /mysql/log/check_mysql.err echo -e "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" >> /mysql/log/check_mysql.err } function query_error { echo -e "`date "+%F %H:%M:%S"` -----query error, but mysql service ok, retry after 30s-----" >> /mysql/log/check_mysql.err sleep 30 excute_query if [ $? -ne 0 ];then echo -e "`date "+%F %H:%M:%S"` -----still can't execute query-----" >> /mysql/log/check_mysql.err echo -e "`date "+%F %H:%M:%S"` -----set read_only = 1 on DB1-----" >> /mysql/log/check_mysql.err $mysql_con -e "set global read_only = 1;" 2>> /mysql/log/check_mysql.err echo -e "`date "+%F %H:%M:%S"` -----kill current client thread-----" >> /mysql/log/check_mysql.err rm -f /mysql/log/kill.sql &>/dev/null $mysql_con -NB -e 'select concat("kill ",id,";") from information_schema.PROCESSLIST where command="Query" or command="Execute"' > /mysql/log/kill.sql $mysql_con -e "source /mysql/log/kill.sql" sleep 2 echo -e "`date "+%F %H:%M:%S"` -----stop keepalived-----" >> /mysql/log/check_mysql.err systemctl stop keepalived &>> /mysql/log/check_mysql.err echo -e "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" >> /mysql/log/check_mysql.err else echo -e "`date "+%F %H:%M:%S"` -----query ok after 30s-----" >> /mysql/log/check_mysql.err echo -e "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" >> /mysql/log/check_mysql.err fi } excute_query if [ $? -ne 0 ];then service mysql status &>/dev/null if [ $? -ne 0 ];then service_error else query_error fi fi
notify_master_mysql.sh
#!/bin/bash #/etc/keepalived/notify_master_mysql.sh #chmod u+x /etc/keepalived/notify_master_mysql.sh change_log=/mysql/log/state_change.log slave_status_log=/mysql/log/slave_status_log.log mysql_conn='/usr/local/mysql/bin/mysql -uroot -pmysql' echo -e "`date "+%F %H:%M:%S"` -----keepalived change to MASTER-----" >> $change_log echo -e "`date "+%F %H:%M:%S"` ----------" >> $slave_status_log $mysql_conn -e "show slave status\G;" >> $slave_status_log Slave_IO_Running=`$mysql_conn -e "show slave status\G;"|egrep -w "Slave_IO_Running|Slave_SQL_Running"|awk 'NR==1{print}' | awk '{print $2}'` Slave_SQL_Running=`$mysql_conn -e "show slave status\G;"|egrep -w "Slave_IO_Running|Slave_SQL_Running"|awk 'NR==2{print}' | awk '{print $2}'` Master_Log_File=`$mysql_conn -e "show slave status\G;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==1{print}' | awk '{print $2}'` Read_Master_Log_Pos=`$mysql_conn -e "show slave status\G;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==2{print}' | awk '{print $2}'` Exec_Master_Log_Pos=`$mysql_conn -e "show slave status\G;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==3{print}' | awk '{print $2}'` action() { echo -e "`date "+%F %H:%M:%S"` -----set read_only = 0 on itpuxdb2-slave-----" >> $change_log $mysql_conn -e "set global read_only = 0;" 2>> $change_log $mysql_conn -e "stop slave;" 2>> $change_log echo "slave1 keepalived转为MASTER状态,线上数据库切换至slave1"|/bin/mailx -s "slave1 keepalived change to MASTER"\ [email protected] 2>> $change_log echo -e "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" >> $change_log } if [ "$Slave_IO_Running" = "Yes" -a "$Slave_SQL_Running" = "Yes" ];then if [ $Read_Master_Log_Pos = $Exec_Master_Log_Pos ];then echo -e "`date "+%F %H:%M:%S"` -----Master_Log_File=$Master_Log_File . Exec_Master_Log_Pos($Exec_Master_Log_Pos) is equal Read_Master_Log_Pos($Read_Master_Log_Pos)" >> $change_log action $mysql_conn -e "reset slave all;" 2>> $change_log else echo -e "`date "+%F %H:%M:%S"` -----Master_Log_File=$Master_Log_File . Exec_Master_Log_Pos($Exec_Master_Log_Pos) is behind Read_Master_Log_Pos($Read_Master_Log_Pos), The waits time is more than 10s,now force change." >> $change_log sleep 10 action $mysql_conn -e "reset slave all;" 2>> $change_log exit 0 fi action else echo -e "itpuxdb2-slave's slave status is wrong,now force change. Master_Log_File=$Master_Log_File Read_Master_Log_Pos=$Read_Master_Log_Pos Exec_Master_Log_Pos=$Exec_Master_Log_Pos" >> $change_log action fi
四、启动 keepalived
systemctl daemon-reload systemctl enable keepalived systemctl stop keepalived systemctl start keepalived
查看keepalived进程
ps -ef|grep keepalived root 7406 1 0 20:25 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D -d -S 0 root 7407 7406 0 20:25 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D -d -S 0 root 7408 7406 0 20:25 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D -d -S 0 root 7412 3067 0 20:25 pts/2 00:00:00 grep --color=auto keepalived
看到这样的说明启动成功,否则启动失败
五、查看VIP状态
192.168.8.57
ip a |grep 88 inet 192.168.8.88/24 scope global secondary enp0s3
192.168.8.58则查询不到
六、通过VIP连接MySQL
mysql -uroot -pmysql -h192.168.8.88 -e "select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | master | +------------+
七、模拟宕机
关闭192.168.8.57服务器
mysql -uroot -pmysql -h192.168.8.88 -e "select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | slave1 | +------------+
MySQL连接切换成功,业务可正常切换至备机
八、故障恢复
192.168.8.57恢复之后,重新将该节点数据库加入至双主复制
reset slave;
change master to
master_host='192.168.8.58',
master_port=3306,
master_user='repl',
master_password='mysql',
master_auto_position=1;
start slave;
等数据追平之后,可以将vip切换至192.168.8.57
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30135314/viewspace-2218136/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30135314/viewspace-2218136/