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


    MHA是一套MySQL高可用管理软件,除了检测Master宕机后,提升候选Slave为New Master之外(漂虚拟IP),还会自动让其他Slave与New Master 建立复制关系。MHA Manager可以单独部署在一台独立的机器上,并管理多个master-slave集群。当自动Failover完成后,MHA Manager服务器上的masterha_manager 进程自动退出。(Currently MHA Manager process does not run as a daemon. If failover completed successfully or the master process was killed by accident, the manager stops working. --官方文档)

    面临的问题

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

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

    背景知识 

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

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

    主节点上虚拟出了 可读/写的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上会出现以上工具包。

    解决方案探究

    脚本主要解决的问题

     实现功能的文件及描述

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

    实现代码 

    文件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 "
    [server1]
    hostname=$server1
    port=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 "
    [server2]
    hostname=$server2
    port=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完成。

    本文版权归作者所有,未经作者同意不得转载,谢谢配合!!!

  • 相关阅读:
    微信小程序开发---各代码文件简介
    LeetCode71. 简化路径
    LeetCode70. 爬楼梯
    LeetCode69. x 的平方根
    LeetCode68. 文本左右对齐
    LeetCode剑指 Offer 09. 用两个栈实现队列
    LeetCode67. 二进制求和
    LeetCode66. 加一
    LeetCode65. 有效数字
    LeetCode64. 最小路径和
  • 原文地址:https://www.cnblogs.com/xuliuzai/p/9850753.html
Copyright © 2020-2023  润新知