欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

程序员文章站 2022-06-21 22:24:23
面临的问题 我们知道开启MHA Manager监控,当MHA 发生自动漂移时,会将老的主库的ip将会从配置文件中移除。那么怎么可以自动将原Master 节点自动以Slave角色添加到集群中来是运维同学面临的问题。 并且大多数情况下,MHA FailOver 后,MHA Manager 监控进程也会关 ......

面临的问题

我们知道开启mha manager监控,当mha 发生自动漂移时,会将老的主库的ip将会从配置文件中移除。那么怎么可以自动将原master 节点自动以slave角色添加到集群中来是运维同学面临的问题。

并且大多数情况下,mha failover 后,mha manager 监控进程也会关闭。所以很有必要再开启一个关于mha manager的保护进程。

 

背景知识 

 

为简化mha 配置,测试环境由一主一从一监控构成。

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

 

注意:主节点、辅助节点 之间 相互ssh 免密码登入。mha manger 到主、副节点之间 需要满足免密码登入(满足单向即可)

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

 

主节点上虚拟出了 可读/写的ip;在从节点上虚拟出只读的ip。程序访问使用虚拟ip。

工具包主要功能

工具包 功能描述
masterha_check_ssh 检查mha的ssh配置状况
masterha_check_repl 检查mysql各节点复制状态
masterha_manger 开启 mha manager
masterha_check_status 检测当前mha manager运行状态
master_ip_failover 自动切换时管理vip的脚本,主要是vip的漂移。
master_ip_online_change 手动执行mysql master switchover时执行的切换脚本,含有管理vip的脚本
masterha_master_switch 控制故障转移(可手动)

 

安装mha manager软件包后,路径/usr/local/bin上会出现以上工具包。

解决方案探究

脚本主要解决的问题

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

 实现功能的文件及描述

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

 

 主要文件mha_health_check_secondary.sh的处理逻辑

 

MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

 

实现代码 

文件mha_protect.sh的主要代码

 1 ########################################################################
 2 # file name: mha_protect.sh
 3 # excute: nohup sh mha_protect.sh &
 4 # created time: thu jul 12 est 2018            
 5 #########################################################################
 6 #!/bin/sh
 7 while true;
 8 do
 9     mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf  | grep "stopped" | wc -l`    
10     if [ "$mha_check_result" == "1" ];then
11         echo "$mha_check_result"
12         sh /etc/masterha/mha_health_check_vip.sh > /etc/masterha/mhalog/mha_check_`date "+%y%m%d%h%m%s"`.log 2>&1
13     fi
14 
15         sleep 20
16 done

 

此文件中,调用mha的配置文件的参数为 /etc/masterha/app1.conf。执行mha_health_check_secondary.sh产生的log位于路径 /etc/masterha/mhalog下面,文件以mha_check_时间命名。

 

文件mha_health_check_secondary.sh 中的主要代码

  1 #!/bin/bash
  2 
  3 server1="172.xxx.xxx.xxx" ##此处请输入server1的ip
  4 server2="172.xxx.xxx.xxx" ##此处请输入server2的ip
  5 vip="172.xxx.xxx.xxx"     ##此处请输入已配置的vip
  6 mysql_username=用户       ##此处数据用户名
  7 mysql_password=密码       ## 此处输入用户名相应的密码
  8 
  9 mha_conf=/etc/masterha/app1.conf
 10 # part:: string sql
 11 sql_change_master=""
 12 mysql_status=""
 13 slave_status=""
 14 master_status=""
 15 
 16 #if has vip , master server ip 
 17 ipaddr1=`ssh root@"$server1" ip addr | grep "inet 172" | awk -f '[/]' '{print $1}' | awk '{print $2}' | grep "$vip"`
 18 ipaddr2=`ssh root@"$server2" ip addr | grep "inet 172" | awk -f '[/]' '{print $1}' | awk '{print $2}' | grep "$vip"`
 19 
 20 ###此处应该添加一个判断当 ipaddr1 和 ipaddr2 都为 空时,说明,vip设置有问题,退出需要告知管理员,去检查
 21 
 22 if [ "$ipaddr1" = "$vip" ];then
 23     masterip=$server1
 24         echo masterip 在server1 $server1 上
 25 fi
 26 if [ "$ipaddr2" = "$vip" ];then
 27     masterip=$server2
 28         echo masterip 在server2 $server2 上
 29 fi
 30 
 31 echo "master ip: $masterip"
 32 
 33 ## start ## 查看app1.conf mha 配置文件server的信息
 34 conf_server1=`grep  "server1" $mha_conf`
 35 conf_server2=`grep  "server2" $mha_conf`
 36 
 37 
 38 echo "conf_server1: $conf_server1 conf_server2 :$conf_server2 "
 39 ## end ## 查看app1.conf mha 配置文件server的信息
 40 
 41 # 生成master mysql的[change master]sql命令
 42 sql_change_master="change master to master_host='$masterip', master_user='$mysql_username', master_password='$mysql_password',master_port=3306,master_auto_position=1;"
 43 
 44 # --------------------------
 45 # function
 46 
 47 # 对指定主机执行linux命令
 48 function do_linux_by_ssh() {
 49         # variable
 50         func_str_ip="$1"
 51         func_str_user="$2"
 52         func_str_command="$3"
 53         # action
 54         ssh $func_str_user@$func_str_ip "$func_str_command"
 55 }
 56 
 57 function do_sql() {
 58         # variable
 59         func_str_ip="$1"
 60         func_str_sql="$2"
 61         # action
 62         mysql -u $mysql_username -h $func_str_ip -p"$mysql_password" -e "$func_str_sql" -p3306
 63 }
 64 function mysql_stop_up() {
 65     # 判断mysql服务状态
 66     # variable
 67         func_str_ip="$1"
 68         mysql_status=`do_linux_by_ssh "$func_str_ip" "root" "service mysqld status" | grep -c 'not running'`
 69     if [ "$mysql_status" = 1 ] ;then
 70             do_linux_by_ssh "$func_str_ip" "root" "service mysqld start" > /dev/null
 71     fi
 72     sleep 20
 73     mysql_status=`do_linux_by_ssh "$func_str_ip" "root" "service mysqld status" | grep -c 'running'`
 74     echo ${mysql_status}
 75 }
 76 function mysql_slave_up() {
 77     # variable
 78         func_str_ip="$1"
 79         slave_status=`do_sql "$func_str_ip" "show slave status \g;" 2> /dev/null | grep "last_io_errno"  | wc -l`
 80     if [[ $slave_status == 0 ]]
 81         then
 82             do_sql "$func_str_ip" "set global read_only=1;set global relay_log_purge=0;"
 83             do_sql "$func_str_ip" "$sql_change_master"
 84             do_sql "$func_str_ip" "start slave;"
 85         fi
 86     slave_status=`do_sql "$func_str_ip" "show slave status \g;" 2> /dev/null | grep "last_io_errno: 0"  | wc -l`
 87     echo ${slave_status}
 88 }
 89 
 90 ## mha集群为2个数据节点,所以下面只循环判断server1、server2,同样如果是三个节点,则copy相关代码,修改if添加即可。
 91 
 92 #if server1 down
 93 if [ "$conf_server1" != "[server1]" ] ;then 
 94     #if myql status was dead , auto systemctl start mysqld
 95     echo "check server1 mysql status start"
 96     mysqlstatus=`mysql_stop_up "$server1"`
 97     echo "server1 mysql status : $mysqlstatus"
 98     if [ "$mysqlstatus" = 1 ] ; then 
 99         echo "server1 slave up start"
100         slave_status=`mysql_slave_up "$server1"`
101         echo "server1 slave status :$slave_status server1: $server1"
102         if [ "$slave_status" = 1 ] ; then
103             echo "write server1 app1.conf start"
104                     echo -e "\n[server1]\nhostname=$server1\nport=3306" >> /etc/masterha/app1.conf
105         fi
106         mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf  | grep "stopped" | wc -l`
107         if [ "$mha_check_result" = 1 ] ;then
108                   nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log 2>&1 & > /dev/null
109         fi
110     fi
111 fi    
112 conf_server1=`grep  "server1" /etc/masterha/app1.conf`
113 
114 #if server2 down
115 echo "$conf_server2":"$server2"
116 
117 if [ "$conf_server2" != "[server2]" ] ;then 
118     #if server2 myql status was dead , auto systemctl start mysqld
119     echo "server2 mysql stop status  start"
120     mysqlstatus=`mysql_stop_up "$server2"`
121     echo "server2 ysql_stop_up status: $mysqlstatus"
122     if [ "$mysqlstatus" = 1 ] ; then 
123         slave_satus=`mysql_slave_up "$server2"`
124         echo "server2 slave_status is : $slave_satus"
125         if [ "$slave_satus" = 1 ] ; then
126             echo "write server2 in app1.conf start"
127             echo -e "\n[server2]\nhostname=$server2\nport=3306" >> /etc/masterha/app1.conf
128         fi
129         mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf  | grep "stopped" | wc -l`
130         echo "$mha_check_result"
131         if [ "$mha_check_result" = 1 ] ;then
132             nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log 2>&1 & > /dev/null
133         fi
134     fi
135 fi    
136 conf_server2=`grep  "server2" /etc/masterha/app1.conf`
137 
138 mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf  | grep "stopped" | wc -l`
139 if [ "$conf_server1" = "[server1]" ] && [ "$conf_server2" = "[server2]" ];then
140     if [ "$mha_check_result" = "1" ];then
141         nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log 2>&1 & > /dev/null
142     fi
143 fi

 

此文件中,调用mha的配置文件的参数为 /etc/masterha/app1.conf。

masterha_manager 监控所产生的log存放在 /etc/masterha/mhalog/manager.log 中。

 

感谢:以上代码实现主要是由同事fly chen完成。