ITPub博客

首页 > 数据库 > MySQL > MySQL5.7+Keepalived双主HA架构

MySQL5.7+Keepalived双主HA架构

原创 MySQL 作者:StevenBeijing 时间:2018-10-30 20:41:13 0 删除 编辑

数据库架构:双主复制

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 {
zdd5503@163.com
}
notification_email_from zdd5503@163.com
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 {
zdd5503@163.com
}
notification_email_from zdd5503@163.com
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"\
    zdd5503@163.com 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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-02-10

  • 博文量
    276
  • 访问量
    242001