• MySQL--16 MHA修复


    一、恢复MHA

    #1.修复旧主库 
    [root@db01 ~]# /etc/init.d/mysqld start 
    #2.在mha日志中找到change master语句 
    #GTID模式下:
    [root@db04 ~]# grep -i 'change master to' /etc/mha/manager.log
    Tue Nov 19 20:49:31 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='slave', MASTER_PASSWORD='123'; 
    
    #普通模式下:
    [root@db03 ~]# grep -i 'change master to' /etc/mha/manager.log 
    Tue Nov 19 19:22:22 2019 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=120, MASTER_USER='slave', MASTER_PASSWORD='xxx';
    
    #3.在旧主库中执行change master语句 
    CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='slave', MASTER_PASSWORD='123'; 
    
    #4.将mha配置文件修复 
    [server1]
    hostname=10.0.0.51 
    port=3306 
    
    #5.启动mha 
    [root@db04 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf -- ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &
    ##### MHA启动命令 详解
    nohup masterha_manager --conf=/etc/mha/app1.cnf 
    #从配置文件中移除旧主库 
    --remove_dead_master_conf 
    #忽略上一次切换 
    --ignore_last_failover 
    ## mha工作机制:在mha一次切换后,会在mha的工作目录下生成一个lock,锁文件
    

    执行脚本恢复

    [root@db01 ~]# cat mysql_vip.sh 
    #!/bin/bash
    /etc/init.d/mysqld start
    mha=10.0.0.53
    change=`ssh $mha "grep -i 'change master to' /etc/mha/manager.log"|awk -F : '{print $4}'|sed 's#xxx#123#g'`
    mysql -e "$change;start slave;"
    ssh $mha cp /etc/mha/app1.cnf.ori /etc/mha/app1.cnf
    

    二、MHA切换

    如果在数据量相同的情况下,根据配置文件中的server标签,越小优先级越高。

    [server4]
    hostname=10.0.0.53
    port=3306
    
    [server2]
    hostname=10.0.0.53
    port=3306
    
    [server1]
    hostname=10.0.0.54
    port=3306
    
    [server3]
    hostname=10.0.0.53
    port=3306
    
    

    注意:如果10.0.0.53宕机,会自动切换到10.0.0.54当主库

    三、配置VIP漂移

    VIP漂移的两种方式
    1)通过keepalived的方式,管理虚拟IP的漂移
    2)通过MHA自带脚本方式,管理虚拟IP的漂移

    修改配置文件

    #编辑配置文件
    [root@mysql-db03 ~]# vim /etc/mha/app1.cnf
    #在[server default]标签下添加
    [server default]
    #使用MHA自带脚本
    master_ip_failover_script=/usr/local/bin/master_ip_failover
    

    编辑脚本

    [root@db03 ~]# cat /etc/mha/master_ip_failover 
    #!/usr/bin/env perl
    
    use strict;
    use warnings FATAL => 'all';
    
    use Getopt::Long;
    
    my (
        $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
        $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
    );
    
    my $vip = '10.0.0.55/24';
    my $key = '0';
    my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
    my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
    
    GetOptions(
        'command=s'          => $command,
        'ssh_user=s'         => $ssh_user,
        'orig_master_host=s' => $orig_master_host,
        'orig_master_ip=s'   => $orig_master_ip,
        'orig_master_port=i' => $orig_master_port,
        'new_master_host=s'  => $new_master_host,
        'new_master_ip=s'    => $new_master_ip,
        'new_master_port=i'  => $new_master_port,
    );
    
    exit &main();
    
    sub main {
    
        print "
    
    IN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===
    
    ";
    
        if ( $command eq "stop" || $command eq "stopssh" ) {
    
            my $exit_code = 1;
            eval {
                print "Disabling the VIP on old master: $orig_master_host 
    ";
                &stop_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn "Got Error: $@
    ";
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "start" ) {
    
            my $exit_code = 10;
            eval {
                print "Enabling the VIP - $vip on the new master - $new_master_host 
    ";
                &start_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn $@;
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "status" ) {
            print "Checking the Status of the script.. OK 
    ";
            exit 0;
        }
        else {
            &usage();
            exit 1;
        }
    }
    
    sub start_vip() {
        `ssh $ssh_user@$new_master_host " $ssh_start_vip "`;
    }
    sub stop_vip() {
         return 0  unless  ($ssh_user);
        `ssh $ssh_user@$orig_master_host " $ssh_stop_vip "`;
    }
    
    sub usage {
        print
        "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port
    ";
    }
    
    
    #根据配置文件中脚本路径编辑
    [root@mysql-db03 ~]# vim /etc/mha/master_ip_failover
    #修改以下几行内容
    my $vip = '10.0.0.55/24';
    my $key = '0';
    my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
    my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; 
    

    注意:

    1.脚本权限问题

    2.语法问题

    3.格式问题

    [root@db04 mha]# chmod +x master_ip_failover 
    [root@db04 mha]# dos2unix master_ip_failover 
    dos2unix: converting file master_ip_failover to Unix format ... 
    

    手动绑定VIP

    #绑定vip
    [root@mysql-db01 ~]# ifconfig eth0:0 10.0.0.55/24
    #查看vip
    [root@mysql-db01 ~]# ip a |grep eth0
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
       inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
       inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    

    测试ip漂移

    #登录db02
    [root@mysql-db02 ~]# mysql -uroot -p123
    #查看slave信息
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 10.0.0.51
                      Master_User: rep
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000007
              Read_Master_Log_Pos: 191
                   Relay_Log_File: mysql-db02-relay-bin.000002
                    Relay_Log_Pos: 361
            Relay_Master_Log_File: mysql-bin.000007
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
    #停掉主库
    [root@mysql-db01 ~]# /etc/init.d/mysqld stop
    Shutting down MySQL..... SUCCESS!
    #在db01上查看vip信息
    [root@mysql-db01 ~]# ip a |grep eth0
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    
    [root@db01 ~]# mysql
    mysql> show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000005 |      120 |              |                  | 6e607afa-0a67-11ea-ac08-000c29f3321a:1-2 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    1 row in set (0.00 sec)
    
    
    #在db02上查看vip信息
    [root@mysql-db02 ~]# ip a |grep eth0
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0
        inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
        
    #在db03上查看从库slave信息
    
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 10.0.0.52
                      Master_User: rep
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000006
              Read_Master_Log_Pos: 191
                   Relay_Log_File: mysql-db03-relay-bin.000002
                    Relay_Log_Pos: 361
            Relay_Master_Log_File: mysql-bin.000006
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
    

    写脚本启动mha,检测主库,并绑定主库虚拟vip

    [root@db03 ~]# vim mha_check.sh
    #1.在manager节点上检查MHA复制状态
    mha=10.0.0.53
    # 启动mha
    cp /etc/mha/app1.cnf.ori /etc/mha/app1.cnf
    ssh $mha 'nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_cnf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &'
    echo "mha 正在启动,请稍后..."
    sleep 20
    #定义主库
    master_ip=`ssh $mha "masterha_check_status --conf=/etc/mha/app1.cnf"|awk -F : '{print $4}'`
    
    if [[ $? = 0 ]];then
       echo "mha 启动成功,master_ip: $master_ip "
    else
            echo "$(date +%F-%T) MHA没有启动" > /etc/mha/app1.log
    fi
    
    #2.主库先绑定虚拟vip
    ssh $master_ip 'ifconfig eth0:0 10.0.0.55/24'
    #宕掉主库会自己恢复
    #ssh $master  '/etc/init.d/mysqld stop'
    

    配置文件

    [root@db03 ~]# vim /etc/mha/app1.cnf.ori 
    [server default]
    manager_log=/etc/mha/manager.log
    manager_workdir=/etc/mha/app1
    master_binlog_dir=/application/mysql/data
    master_ip_failover_script=/etc/mha/master_ip_failover
    password=123
    ping_interval=2
    repl_password=123
    repl_user=db
    ssh_user=root
    user=mha
    [server1]
    hostname=10.0.0.51
    port=3306
    
    [server3]
    hostname=10.0.0.53
    port=3306
    
    [server4]
    hostname=10.0.0.54
    port=3306
    
    [server2]
    hostname=10.0.0.52
    port=3306
    
    [binlog1]
    no_master=1
    hostname=10.0.0.53
    master_binlog_dir=/data/mysql/binlog/
    
    

    执行结果

    [root@db03 ~]# sh mha_check.sh 
    mha 正在启动,请稍后...
    mha 启动成功,master_ip: 10.0.0.54 
    

    把自动恢复宕机主库的脚本写进perl里,宕机自动恢复变成从库

    [root@db03 ~]# cat mysql_vip.sh 
    #!/bin/bash
    /etc/init.d/mysqld start
    mha=10.0.0.53
    change=`ssh $mha "grep -i 'change master to' /etc/mha/manager.log"|awk -F : '{print $4}'|sed 's#xxx#123#g'`
    mysql -e "$change;start slave;"
    
    [root@db03 mha]# cat master_ip_failover
    #!/usr/bin/env perl
    ...
    sub start_vip() {
        `ssh $ssh_user@$new_master_host " $ssh_start_vip "`;
    	`ssh $ssh_user@$orig_master_host " sh /root/mysql_vip.sh "`;
    ...
    
    

    perl脚本参考

    [root@db03 mha]# pwd
    /etc/mha
    [root@db03 mha]# cat master_ip_failover 
    #!/usr/bin/env perl
    
    use strict;
    use warnings FATAL => 'all';
    
    use Getopt::Long;
    
    my (
        $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
        $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
    );
    
    my $vip = '10.0.0.55/24';
    my $key = '0';
    my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
    my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
    
    GetOptions(
        'command=s'          => $command,
        'ssh_user=s'         => $ssh_user,
        'orig_master_host=s' => $orig_master_host,
        'orig_master_ip=s'   => $orig_master_ip,
        'orig_master_port=i' => $orig_master_port,
        'new_master_host=s'  => $new_master_host,
        'new_master_ip=s'    => $new_master_ip,
        'new_master_port=i'  => $new_master_port,
    );
    
    exit &main();
    
    sub main {
    
        print "
    
    IN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===
    
    ";
    
        if ( $command eq "stop" || $command eq "stopssh" ) {
    
            my $exit_code = 1;
            eval {
                print "Disabling the VIP on old master: $orig_master_host 
    ";
                &stop_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn "Got Error: $@
    ";
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "start" ) {
    
            my $exit_code = 10;
            eval {
                print "Enabling the VIP - $vip on the new master - $new_master_host 
    ";
                &start_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn $@;
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "status" ) {
            print "Checking the Status of the script.. OK 
    ";
            exit 0;
        }
        else {
            &usage();
            exit 1;
        }
    }
    
    sub start_vip() {
        `ssh $ssh_user@$new_master_host " $ssh_start_vip "`;
    	`ssh $ssh_user@$orig_master_host " sh /root/mysql_vip.sh "`;
    
    }
    sub stop_vip() {
         return 0  unless  ($ssh_user);
        `ssh $ssh_user@$orig_master_host " $ssh_stop_vip "`;
    }
    
    sub usage {
        print
        "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port
    ";
    }
    
    
  • 相关阅读:
    第六章:单元测试框架unittest
    Jenkins 使用 war包安装时,如果出现报离线错误解决方法
    Appium自动化封装教案
    yaml文件读取(5.1之前与5.1之后对比)
    appium-desktop配置运用方法
    postwoman 配置
    jwt解析
    pytest
    centos安装python3.8
    linux 查找命令
  • 原文地址:https://www.cnblogs.com/gongjingyun123--/p/11909589.html
Copyright © 2020-2023  润新知