使用MHA实现MySQL主从复制高可用

使用MHA实现MySQL主从复制高可用

2018年07月31日 16:37:10 wzy0623 阅读数 4910更多
所属专栏: MySQL高可用方案
 
版权声明:本文为博主原创文章,未经博主容许不得转载。 https://blog.csdn.net/wzy0623/article/details/81304654

目录html

1、MHA简介node

2、实验架构设计mysql

1. 基本环境linux

2. 架构设计git

3、MHA安装配置github

1. 配置主从复制redis

2. 安装Perl等依赖模块sql

3. 配置SSH登陆无密码验证数据库

4. 安装MHA Nodebash

5. 安装MHA Manager

6. 配置MHA

7. 建立相关脚本

4、检查MHA配置

1. 检查SSH配置

2. 检查整个复制环境情况

3. 检查MHA Manager的状态

4. 查看启动日志

5、功能测试

1. 初始绑定VIP

2. 测试自动切换

3. 测试手工切换

4. 测试在线切换

5. 修复宕机的Master 

参考:


1、MHA简介

        MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司的youshimaton(现就任于Facebook公司)开发,是一套优秀的做为MySQL高可用性环境下故障切换和主从提高的高可用软件。在MySQL故障切换过程当中,MHA能作到在0~30秒以内自动完成数据库的故障切换操做,而且在进行故障切换的过程当中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

        该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager能够单独部署在一台独立的机器上管理多个master-slave集群,也能够部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它能够自动将最新数据的slave提高为新的master,而后将全部其余的slave从新指向新的master。整个故障转移过程对应用程序彻底透明。

        在MHA自动故障切换过程当中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不老是可行的。例如,若是主服务器硬件故障或没法经过ssh访问,MHA无法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,能够大大下降数据丢失的风险。MHA能够与半同步复制结合起来。若是只有一个slave已经收到了最新的二进制日志,MHA能够将最新的二进制日志应用于其余全部的slave服务器上,所以能够保证全部节点的数据一致性。

        目前MHA主要支持一主多从的架构。要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另一台充当从库。由于至少须要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。(出自:《深刻浅出MySQL(第二版)》)从代码层面看,MHA就是一套Perl脚本,那么相信以阿里系的技术实力,将MHA改为支持一主一从也并不是难事。

图1所示为MHA架构:

图1

        MHA工做原理总结为如下几条:

  1. 从宕机崩溃的master保存二进制日志事件(binlog events);
  2. 识别含有最新更新的slave;
  3. 应用差别的中继日志(relay log)到其余slave;
  4. 应用从master保存的二进制日志事件(binlog events);
  5. 提高一个slave为新master;
  6. 使用其余的slave链接新的master进行复制。

        官方介绍:https://code.google.com/archive/p/mysql-master-ha/
 

2、实验架构设计

1. 基本环境

  • 操做系统版本:CentOS Linux release 7.2.1511 (Core)
  • MySQL版本:5.6.14
  • VIP(虚IP):172.16.1.100
  • 主机信息:见表1

角色

IP

主机名

网卡

server_id

 功能

Monitor Host

172.16.1.124

hdp1

-

-

监控复制组

Master

172.16.1.127

hdp4

ens160

127

响应写请求

Candidate Master

172.16.1.126

hdp3

ens32

126

响应读请求

Slave

172.16.1.125

hdp2

ens32

125

响应读请求

表1

2. 架构设计

        实验架构如图2所示。

图2

        hdp1做为MHA Manager,其它三台主机构成MySQL一主二从复制集群,做为MHA Node。

3、MHA安装配置

1. 配置主从复制

        MySQL主从复制的配置较为简单,具体过程可参考MySQL官方文档,这里从略。若是是全新搭建的复制,只要打开Master的binlog,而后将Slave change master到指定的file和pos,再start slave便可。若是是为已经存在且正在使用的数据库搭建从库,有两种方式,一是用mysqldump master-data参数记录master的file和pos,但可能卡库;比较好的方法是用innobackupex联机搭建从库,过程以下:
(1)前置条件

  • 主从都安装好依赖包:
yum install perl perl-DBI perl-DBD-MySQL perl-IO-Socket-SSL perl-Time-HiRes
  • ​​​主从都安装percona-xtrabackup
  • 设置PATH环境变量,如:
.:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/home/mysql/mysql-5.6.14/bin:/home/mysql/percona-xtrabackup-2.2.4-Linux-x86_64/bin:/home/mysql/bin

(2)配置主到从的SSH免密码链接
        在主上用mysql用户执行:

 
  1.  
    ssh-keygen    
  2.  
    ... 一路回车 ...    
  3.  
    ssh-copy-id slave的IP或主机名

(3)备份并传输
        例如,在主上用mysql用户执行:

innobackupex --user root --password 123456 --defaults-file=/home/mysql/mysql-5.6.14/my.cnf --no-lock --socket=/home/mysql/mysql-5.6.14/mysql.sock --port 3306 --stream=tar ./ | ssh mysql@172.16.1.126 \ "cat - > /home/mysql/backup.tar"  

(4)恢复备份
        在从上用mysql用户执行:

 
  1.  
    # 解压缩
  2.  
    tar -ixvf backup.tar -C /home/mysql/mysql-5.6.14/data
  3.  
    # 应用日志
  4.  
    innobackupex --apply-log /home/mysql/mysql-5.6.14/data/   
  5.  
     
  6.  
    # 查看binlog日志文件的位置值
  7.  
    cat /home/mysql/mysql-5.6.14/data/xtrabackup_binlog_info
  8.  
     
  9.  
    # 编辑my.cnf
  10.  
    vi /etc/my.cnf
  11.  
     
  12.  
    # 启动MySQL,目录要和主保持一致
  13.  
    service mysql start
  14.  
     
  15.  
    mysql -uroot -p123456 -P3306 -h127.0.0.1
  16.  
     
  17.  
    # 配置复制
  18.  
    reset master;
  19.  
    reset slave all;
  20.  
     
  21.  
    change master to
  22.  
    master_host='172.16.1.127',
  23.  
    master_port=3306,
  24.  
    master_user='repl',
  25.  
    master_password='123456',
  26.  
    master_log_file='mysql-bin.000001',
  27.  
    master_log_pos=120;
  28.  
     
  29.  
    # 其中master_log_file和master_log_pos赋予/home/mysql/mysql5.6.14/data/xtrabackup_binlog_info中的值。
  30.  
     
  31.  
    # 启动slave
  32.  
    start slave;
  33.  
     
  34.  
    # 查看slave状态
  35.  
    show slave status\G

(5)后续工做
        备份my.cnf、bat文件和crontab等。

2. 安装Perl等依赖模块

        用root用户在全部四个节点执行下面的操做。

 
  1.  
    # 安装一个epel源
  2.  
    wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
  3.  
     
  4.  
    # 用yum安装依赖包
  5.  
    yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes -y


3. 配置SSH登陆无密码验证

        在hdp1 172.16.1.124(Monitor)上用root用户执行:

 
  1.  
    ssh-keygen -t rsa
  2.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.125
  3.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.126
  4.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.127

        在hdp4 172.16.1.127(Master)上用root用户执行:

 
  1.  
    ssh-keygen -t rsa
  2.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.125
  3.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.126

        在hdp3 172.16.1.126(slave1)上用root用户执行:

 
  1.  
    ssh-keygen -t rsa
  2.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.125
  3.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.127

        在hdp2 172.16.1.125(slave2)上用root用户执行:

 
  1.  
    ssh-keygen -t rsa
  2.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.126
  3.  
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.127


4. 安装MHA Node

        下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
        在hdp二、hdp三、hdp4上用root用户执行下面的操做。

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

        安装完成后,在/usr/bin/目录下有以下MHA相关文件:

 
  1.  
    apply_diff_relay_logs
  2.  
    filter_mysqlbinlog
  3.  
    purge_relay_logs
  4.  
    save_binary_logs

        这些脚本工具一般由MHA Manager的脚本触发,无需人为操做。脚本说明:

  • apply_diff_relay_logs:识别差别的中继日志事件并将其差别的事件应用于其它slave。
  • filter_mysqlbinlog:去除没必要要的ROLLBACK事件(MHA已再也不使用这个工具)。
  • purge_relay_logs:清除中继日志(不会阻塞SQL线程)。
  • save_binary_logs:保存和复制master的二进制日志。

5. 安装MHA Manager

        下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
        在hdp1上用root用户执行下面的操做。

rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

        安装完成后,在/usr/bin/目录下有以下MHA相关文件:

 
  1.  
    masterha_check_repl
  2.  
    masterha_check_ssh
  3.  
    masterha_check_status
  4.  
    masterha_conf_host
  5.  
    masterha_manager
  6.  
    masterha_master_monitor
  7.  
    masterha_master_switch
  8.  
    masterha_secondary_check
  9.  
    masterha_stop
  10.  
    apply_diff_relay_logs
  11.  
    filter_mysqlbinlog
  12.  
    purge_relay_logs
  13.  
    save_binary_logs

6. 配置MHA

        在hdp1上用root用户执行下面(1)、(2)、(3)的操做。

(1)创建配置文件目录

mkdir -p /etc/masterha

(2)建立配置文件/etc/masterha/app1.cnf,内容以下:

 
  1.  
    [server default]
  2.  
    manager_log=/var/log/masterha/app1/manager.log
  3.  
    manager_workdir=/var/log/masterha/app1.log
  4.  
    master_binlog_dir=/data
  5.  
    master_ip_failover_script=/usr/bin/master_ip_failover
  6.  
    master_ip_online_change_script=/usr/bin/master_ip_online_change
  7.  
    password=123456
  8.  
    ping_interval=1
  9.  
    remote_workdir=/tmp
  10.  
    repl_password=123456
  11.  
    repl_user=repl
  12.  
    secondary_check_script=/usr/bin/masterha_secondary_check -s hdp4 -s hdp3 --user=root --master_host=hdp4 --master_ip=172.16.1.127 --master_port=3306
  13.  
    shutdown_script=""
  14.  
    ssh_user=root
  15.  
    user=root
  16.  
     
  17.  
    [server1]
  18.  
    hostname=172.16.1.127
  19.  
    port=3306
  20.  
     
  21.  
    [server2]
  22.  
    candidate_master=1
  23.  
    check_repl_delay=0
  24.  
    hostname=172.16.1.126
  25.  
    port=3306
  26.  
     
  27.  
    [server3]
  28.  
    hostname=172.16.1.125
  29.  
    port=3306

        server default段是manager的一些基本配置参数,server一、server二、server3分别对应复制中的master、第一个slave、第二个slave。该文件的语法要求严格,变量值后不要有多余的空格。主要配置项说明以下。

  • manager_log:设置manager的日志文件。
  • manager_workdir:设置manager的工做目录。
  • master_binlog_dir:设置master保存binlog的位置,以便MHA能够找到master的日志,这里的也就是mysql的数据目录。
  • master_ip_failover_script:设置自动failover时候的切换脚本。
  • master_ip_online_change_script:设置手动切换时候的切换脚本。
  • password:设置mysql中root用户的密码。
  • ping_interval:设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover。
  • remote_workdir:设置远端mysql在发生切换时binlog的保存位置。
  • repl_password:设置复制用户的密码。
  • repl_user:设置复制环境中的复制用户名
  • secondary_check_script:一旦MHA到hdp4的监控之间出现问题,MHA Manager将会尝试从hdp3登陆到hdp4。
  • shutdown_script:设置故障发生后关闭故障主机脚本。该脚本的主要做用是关闭主机放在发生脑裂,这里没有使用。
  • ssh_user:设置ssh的登陆用户名。
  • user:设置监控用户为root。
  • candidate_master:设置为候选master。设置该参数之后,发生主从切换之后将会将此从库提高为主库,即便这个主库不是集群中事件最新的slave。
  • check_repl_delay:默认状况下若是一个slave落后master 100M的relay logs的话,MHA将不会选择该slave做为一个新的master,由于对于这个slave的恢复须要花费很长时间,经过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机很是有用,由于这个候选主在切换的过程当中必定是新的master。

(3)创建软链接

 
  1.  
    ln -s /home/mysql/mysql-5.6.14/bin/mysqlbinlog /usr/bin/mysqlbinlog
  2.  
    ln -s /home/mysql/mysql-5.6.14/bin/mysql /usr/bin/mysql

(4)设置复制中Slave的relay_log_purge参数
        在hdp3和hdp2上用mysql用户执行:

mysql -uroot -p123456 -e "set global relay_log_purge=0"

        注意,MHA在发生切换的过程当中,从库的恢复过程当中依赖于relay log的相关信息,因此这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。默认状况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。可是在MHA环境中,这些中继日志在恢复其余从服务器时可能会被用到,所以须要禁用中继日志的自动删除功能。按期清除中继日志须要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件须要必定的时间,会致使严重的复制延时。为了不复制延时,须要暂时为中继日志建立硬连接,由于在linux系统中经过硬连接删除大文件速度会很快。(在mysql数据库中,删除大表时,一般也采用创建硬连接的方式)

7. 建立相关脚本

(1)建立按期清理relay脚本
        在hdp三、hdp2两台slave上创建/root/purge_relay_log.sh文件,内容以下:

 
  1.  
    #!/bin/bash
  2.  
     
  3.  
    . /home/mysql/.bashrc
  4.  
     
  5.  
    user=root
  6.  
    passwd=123456
  7.  
    port=3306
  8.  
    log_dir='/data'
  9.  
    work_dir='/data'
  10.  
    purge='/usr/bin/purge_relay_logs'
  11.  
     
  12.  
    if [ ! -d $log_dir ]
  13.  
    then
  14.  
       mkdir $log_dir -p
  15.  
    fi
  16.  
     
  17.  
    $purge --user=$user --password=$passwd --disable_relay_log_purge --port=$port --workdir=$work_dir >> $log_dir/purge_relay_logs.log 2>&1

        purge_relay_logs的参数说明:

  • user mysql:MySQL用户名。
  • password mysql:MySQL用户密码。
  • port:MySQL端口号。
  • workdir:指定建立relay log的硬连接的位置,默认是/var/tmp。因为系统不一样分区建立硬连接文件会失败,故须要执行硬连接具体位置,成功执行脚本后,硬连接的中继日志文件被删除。
  • disable_relay_log_purge:默认状况下,若是relay_log_purge=1,脚本会什么都不清理,自动退出。经过设定这个参数,当relay_log_purge=1的状况下会将relay_log_purge设置为0。清理relay log以后,最后将参数设置为OFF。

        改模式为可执行:

chmod 755 purge_relay_log.sh

        手工执行/root/purge_relay_log.sh,在控制台输出:

 
  1.  
    2018-07-31 12:45:20: purge_relay_logs script started.
  2.  
     Found relay_log.info: /data/relay-log.info
  3.  
     Opening /data/hdp2-relay-bin.000001 ..
  4.  
     Opening /data/hdp2-relay-bin.000002 ..
  5.  
     Executing SET GLOBAL relay_log_purge=1; FLUSH LOGS; sleeping a few seconds so that SQL thread can delete older relay log
  6.  
     files (if it keeps up); SET GLOBAL relay_log_purge=0; .. ok.
  7.  
    2018-07-31 12:45:23: All relay log purging operations succeeded.

        添加到crontab中:

0 4 * * * /bin/bash /root/purge_relay_log.sh

(2)建立自动failover脚本
        在hdp1上建立/usr/bin/master_ip_failover文件,内容以下:

 
  1.  
    #!/usr/bin/env perl
  2.  
    use strict;
  3.  
    use warnings FATAL => 'all';
  4.  
     
  5.  
    use Getopt::Long;
  6.  
     
  7.  
    my (
  8.  
        $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
  9.  
        $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
  10.  
    );
  11.  
     
  12.  
    my $vip = '172.16.1.100';  # Virtual IP 
  13.  
    my $key = "1"; 
  14.  
    my $ssh_start_vip = "/sbin/ifconfig ens32:$key $vip";
  15.  
    my $ssh_stop_vip = "/sbin/ifconfig ens160:$key down";
  16.  
     
  17.  
    GetOptions(
  18.  
        'command=s'          => \$command,
  19.  
        'ssh_user=s'         => \$ssh_user,
  20.  
        'orig_master_host=s' => \$orig_master_host,
  21.  
        'orig_master_ip=s'   => \$orig_master_ip,
  22.  
        'orig_master_port=i' => \$orig_master_port,
  23.  
        'new_master_host=s'  => \$new_master_host,
  24.  
        'new_master_ip=s'    => \$new_master_ip,
  25.  
        'new_master_port=i'  => \$new_master_port,
  26.  
    );
  27.  
     
  28.  
    exit &main();
  29.  
     
  30.  
    sub main {
  31.  
     
  32.  
        print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n"; 
  33.  
     
  34.  
        if ( $command eq "stop" || $command eq "stopssh" ) {
  35.  
     
  36.  
            # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
  37.  
            # If you manage master ip address at global catalog database,
  38.  
            # invalidate orig_master_ip here.
  39.  
            my $exit_code = 1;
  40.  
            eval {
  41.  
                print "Disabling the VIP on old master: $orig_master_host \n";
  42.  
                &stop_vip();
  43.  
                $exit_code = 0;
  44.  
            };
  45.  
            if ($@) {
  46.  
                warn "Got Error: $@\n";
  47.  
                exit $exit_code;
  48.  
            }
  49.  
            exit $exit_code;
  50.  
        }
  51.  
        elsif ( $command eq "start" ) {
  52.  
     
  53.  
            # all arguments are passed.
  54.  
            # If you manage master ip address at global catalog database,
  55.  
            # activate new_master_ip here.
  56.  
            # You can also grant write access (create user, set read_only=0, etc) here.
  57.  
            my $exit_code = 10;
  58.  
            eval {
  59.  
                print "Enabling the VIP - $vip on the new master - $new_master_host \n";
  60.  
                &start_vip();
  61.  
                $exit_code = 0;
  62.  
            };
  63.  
            if ($@) {
  64.  
                warn $@;
  65.  
                exit $exit_code;
  66.  
            }
  67.  
            exit $exit_code;
  68.  
        }
  69.  
        elsif ( $command eq "status" ) {
  70.  
            print "Checking the Status of the script.. OK \n"; 
  71.  
            `ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
  72.  
            exit 0;
  73.  
        }
  74.  
        else {
  75.  
            &usage();
  76.  
            exit 1;
  77.  
        }
  78.  
    }
  79.  
     
  80.  
    # A simple system call that enable the VIP on the new master 
  81.  
    sub start_vip() {
  82.  
        `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
  83.  
    }
  84.  
    # A simple system call that disable the VIP on the old_master
  85.  
    sub stop_vip() {
  86.  
        `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
  87.  
    }
  88.  
     
  89.  
    sub usage {
  90.  
        print
  91.  
        "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\n";
  92.  
    }

        注意脚本中VIP漂移的部分。

(3)建立手动failover脚本
        在hdp1上建立/usr/bin/master_ip_online_change文件,内容以下:

 
  1.  
    #!/usr/bin/env perl
  2.  
      
  3.  
    ## Note: This is a sample script and is notcomplete. Modify the script based on your environment.
  4.  
      
  5.  
    use strict;
  6.  
    use warnings FATAL => 'all';
  7.  
      
  8.  
    use Getopt::Long;
  9.  
    use MHA::DBHelper;
  10.  
    use MHA::NodeUtil;
  11.  
    # use Time::HiRes qw( sleep gettimeofdaytv_interval );
  12.  
    use Time::HiRes qw(sleep gettimeofday tv_interval);
  13.  
    use Data::Dumper;
  14.  
      
  15.  
    my $_tstart;
  16.  
    my $_running_interval = 0.1;
  17.  
    my (
  18.  
     $command,         $orig_master_host, $orig_master_ip,
  19.  
     $orig_master_port, $orig_master_user,
  20.  
     $new_master_host, $new_master_ip,   $new_master_port,
  21.  
     $new_master_user, 
  22.  
    );
  23.  
      
  24.  
    my $vip = '172.16.1.100';  # Virtual IP 
  25.  
    my $key = "1"; 
  26.  
    my $ssh_start_vip = "/sbin/ifconfig ens32:$key $vip";
  27.  
    my $ssh_stop_vip = "/sbin/ifconfig ens160:$key down";
  28.  
    my $ssh_user = "root";
  29.  
    my $new_master_password = "123456";
  30.  
    my $orig_master_password = "123456";
  31.  
      
  32.  
    GetOptions(
  33.  
     'command=s'              =>\$command,
  34.  
     #'ssh_user=s'             => \$ssh_user, 
  35.  
     'orig_master_host=s'     =>\$orig_master_host,
  36.  
     'orig_master_ip=s'       =>\$orig_master_ip,
  37.  
     'orig_master_port=i'     =>\$orig_master_port,
  38.  
     'orig_master_user=s'     =>\$orig_master_user,
  39.  
     #'orig_master_password=s' => \$orig_master_password,
  40.  
     'new_master_host=s'      =>\$new_master_host,
  41.  
     'new_master_ip=s'        =>\$new_master_ip,
  42.  
     'new_master_port=i'      =>\$new_master_port,
  43.  
     'new_master_user=s'      =>\$new_master_user,
  44.  
     #'new_master_password=s'  =>\$new_master_password,
  45.  
    );
  46.  
      
  47.  
    exit &main();
  48.  
      
  49.  
    sub current_time_us {
  50.  
      my ($sec, $microsec ) = gettimeofday();
  51.  
      my$curdate = localtime($sec);
  52.  
     return $curdate . " " . sprintf( "%06d", $microsec);
  53.  
    }
  54.  
      
  55.  
    sub sleep_until {
  56.  
      my$elapsed = tv_interval($_tstart);
  57.  
      if ($_running_interval > $elapsed ) {
  58.  
       sleep( $_running_interval - $elapsed );
  59.  
      }
  60.  
    }
  61.  
      
  62.  
    sub get_threads_util {
  63.  
      my$dbh                    = shift;
  64.  
      my$my_connection_id       = shift;
  65.  
      my$running_time_threshold = shift;
  66.  
      my$type                   = shift;
  67.  
     $running_time_threshold = 0 unless ($running_time_threshold);
  68.  
     $type                   = 0 unless($type);
  69.  
      my@threads;
  70.  
      
  71.  
      my$sth = $dbh->prepare("SHOW PROCESSLIST");
  72.  
     $sth->execute();
  73.  
      
  74.  
     while ( my $ref = $sth->fetchrow_hashref() ) {
  75.  
        my$id         = $ref->{Id};
  76.  
        my$user       = $ref->{User};
  77.  
        my$host       = $ref->{Host};
  78.  
        my$command    = $ref->{Command};
  79.  
        my$state      = $ref->{State};
  80.  
        my$query_time = $ref->{Time};
  81.  
        my$info       = $ref->{Info};
  82.  
       $info =~ s/^\s*(.*?)\s*$/$1/ if defined($info);
  83.  
       next if ( $my_connection_id == $id );
  84.  
       next if ( defined($query_time) && $query_time <$running_time_threshold );
  85.  
       next if ( defined($command)   && $command eq "Binlog Dump" );
  86.  
       next if ( defined($user)      && $user eq "system user" );
  87.  
       next
  88.  
         if ( defined($command)
  89.  
         && $command eq "Sleep"
  90.  
         && defined($query_time)
  91.  
         && $query_time >= 1 );
  92.  
      
  93.  
        if( $type >= 1 ) {
  94.  
         next if ( defined($command) && $command eq "Sleep" );
  95.  
          nextif ( defined($command) && $command eq "Connect" );
  96.  
        }
  97.  
      
  98.  
        if( $type >= 2 ) {
  99.  
         next if ( defined($info) && $info =~ m/^select/i );
  100.  
         next if ( defined($info) && $info =~ m/^show/i );
  101.  
        }
  102.  
      
  103.  
       push @threads, $ref;
  104.  
      }
  105.  
     return @threads;
  106.  
    }
  107.  
      
  108.  
    sub main {
  109.  
      if ($command eq "stop" ) {
  110.  
        ##Gracefully killing connections on the current master
  111.  
        #1. Set read_only= 1 on the new master
  112.  
        #2. DROP USER so that no app user can establish new connections
  113.  
        #3. Set read_only= 1 on the current master
  114.  
        #4. Kill current queries
  115.  
        #* Any database access failure will result in script die.
  116.  
        my$exit_code = 1;
  117.  
       eval {
  118.  
         ## Setting read_only=1 on the new master (to avoid accident)
  119.  
         my $new_master_handler = new MHA::DBHelper();
  120.  
      
  121.  
         # args: hostname, port, user, password, raise_error(die_on_error)_or_not
  122.  
         $new_master_handler->connect( $new_master_ip, $new_master_port,
  123.  
           $new_master_user, $new_master_password, 1 );
  124.  
         print current_time_us() . " Set read_only on the new master..";
  125.  
         $new_master_handler->enable_read_only();
  126.  
         if ( $new_master_handler->is_read_only() ) {
  127.  
           print "ok.\n";
  128.  
         }
  129.  
         else {
  130.  
           die "Failed!\n";
  131.  
         }
  132.  
         $new_master_handler->disconnect();
  133.  
      
  134.  
         # Connecting to the orig master, die if any database error happens
  135.  
         my $orig_master_handler = new MHA::DBHelper();
  136.  
         $orig_master_handler->connect( $orig_master_ip, $orig_master_port,
  137.  
           $orig_master_user, $orig_master_password, 1 );
  138.  
      
  139.  
          ## Drop application user so that nobodycan connect. Disabling per-session binlog beforehand
  140.  
         #$orig_master_handler->disable_log_bin_local();
  141.  
         #print current_time_us() . " Drpping app user on the origmaster..\n";
  142.  
         #FIXME_xxx_drop_app_user($orig_master_handler);
  143.  
      
  144.  
         ## Waiting for N * 100 milliseconds so that current connections can exit
  145.  
         my $time_until_read_only = 15;
  146.  
         $_tstart = [gettimeofday];
  147.  
         my @threads = get_threads_util( $orig_master_handler->{dbh},
  148.  
           $orig_master_handler->{connection_id} );
  149.  
         while ( $time_until_read_only > 0 && $#threads >= 0 ) {
  150.  
           if ( $time_until_read_only % 5 == 0 ) {
  151.  
             printf "%s Waiting all running %d threads aredisconnected.. (max %d milliseconds)\n",
  152.  
               current_time_us(), $#threads + 1, $time_until_read_only * 100;
  153.  
             if ( $#threads < 5 ) {
  154.  
               print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump ."\n"
  155.  
                 foreach (@threads);
  156.  
             }
  157.  
           }
  158.  
           sleep_until();
  159.  
           $_tstart = [gettimeofday];
  160.  
           $time_until_read_only--;
  161.  
           @threads = get_threads_util( $orig_master_handler->{dbh},
  162.  
             $orig_master_handler->{connection_id} );
  163.  
         }
  164.  
      
  165.  
         ## Setting read_only=1 on the current master so that nobody(exceptSUPER) can write
  166.  
         print current_time_us() . " Set read_only=1 on the orig master..";
  167.  
         $orig_master_handler->enable_read_only();
  168.  
         if ( $orig_master_handler->is_read_only() ) {
  169.  
           print "ok.\n";
  170.  
         }
  171.  
         else {
  172.  
           die "Failed!\n";
  173.  
         }
  174.  
      
  175.  
         ## Waiting for M * 100 milliseconds so that current update queries cancomplete
  176.  
         my $time_until_kill_threads = 5;
  177.  
         @threads = get_threads_util( $orig_master_handler->{dbh},
  178.  
           $orig_master_handler->{connection_id} );
  179.  
         while ( $time_until_kill_threads > 0 && $#threads >= 0 ) {
  180.  
           if ( $time_until_kill_threads % 5 == 0 ) {
  181.  
             printf "%s Waiting all running %d queries aredisconnected.. (max %d milliseconds)\n",
  182.  
               current_time_us(), $#threads + 1, $time_until_kill_threads * 100;
  183.  
             if ( $#threads < 5 ) {
  184.  
               print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump ."\n"
  185.  
                 foreach (@threads);
  186.  
             }
  187.  
           }
  188.  
           sleep_until();
  189.  
           $_tstart = [gettimeofday];
  190.  
           $time_until_kill_threads--;
  191.  
           @threads = get_threads_util( $orig_master_handler->{dbh},
  192.  
             $orig_master_handler->{connection_id} );
  193.  
         }
  194.  
      
  195.  
                    print "Disabling the VIPon old master: $orig_master_host \n";
  196.  
                    &stop_vip();    
  197.  
      
  198.  
         ## Terminating all threads
  199.  
         print current_time_us() . " Killing all applicationthreads..\n";
  200.  
         $orig_master_handler->kill_threads(@threads) if ( $#threads >= 0);
  201.  
         print current_time_us() . " done.\n";
  202.  
         #$orig_master_handler->enable_log_bin_local();
  203.  
         $orig_master_handler->disconnect();
  204.  
      
  205.  
         ## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK
  206.  
         $exit_code = 0;
  207.  
        };
  208.  
        if($@) {
  209.  
         warn "Got Error: $@\n";
  210.  
         exit $exit_code;
  211.  
        }
  212.  
       exit $exit_code;
  213.  
      }
  214.  
     elsif ( $command eq "start" ) {
  215.  
        ##Activating master ip on the new master
  216.  
        #1. Create app user with write privileges
  217.  
        #2. Moving backup script if needed
  218.  
        #3. Register new master's ip to the catalog database
  219.  
      
  220.  
    # We don't return error even thoughactivating updatable accounts/ip failed so that we don't interrupt slaves'recovery.
  221.  
    # If exit code is 0 or 10, MHA does notabort
  222.  
        my$exit_code = 10;
  223.  
        eval{
  224.  
         my $new_master_handler = new MHA::DBHelper();
  225.  
      
  226.  
         # args: hostname, port, user, password, raise_error_or_not
  227.  
         $new_master_handler->connect( $new_master_ip, $new_master_port,
  228.  
           $new_master_user, $new_master_password, 1 );
  229.  
      
  230.  
         ## Set read_only=0 on the new master
  231.  
         #$new_master_handler->disable_log_bin_local();
  232.  
         print current_time_us() . " Set read_only=0 on the newmaster.\n";
  233.  
         $new_master_handler->disable_read_only();
  234.  
      
  235.  
         ## Creating an app user on the new master
  236.  
         #print current_time_us() . " Creating app user on the newmaster..\n";
  237.  
         #FIXME_xxx_create_app_user($new_master_handler);
  238.  
         #$new_master_handler->enable_log_bin_local();
  239.  
         $new_master_handler->disconnect();
  240.  
      
  241.  
         ## Update master ip on the catalog database, etc
  242.  
                    print "Enabling the VIP -$vip on the new master - $new_master_host \n";
  243.  
                    &start_vip();
  244.  
                    $exit_code = 0;
  245.  
        };
  246.  
        if($@) {
  247.  
         warn "Got Error: $@\n";
  248.  
         exit $exit_code;
  249.  
        }
  250.  
       exit $exit_code;
  251.  
      }
  252.  
     elsif ( $command eq "status" ) {
  253.  
      
  254.  
        #do nothing
  255.  
       exit 0;
  256.  
      }
  257.  
      else{
  258.  
       &usage();
  259.  
       exit 1;
  260.  
      }
  261.  
    }
  262.  
      
  263.  
    # A simple system call that enable the VIPon the new master
  264.  
    sub start_vip() {
  265.  
       `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
  266.  
    }
  267.  
    # A simple system call that disable the VIPon the old_master
  268.  
    sub stop_vip() {
  269.  
       `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
  270.  
    }
  271.  
      
  272.  
    sub usage {
  273.  
     print
  274.  
    "Usage: master_ip_online_change --command=start|stop|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\n";
  275.  
      die;
  276.  
    }

        注意脚本中VIP漂移的部分。

4、检查MHA配置

1. 检查SSH配置

        在hdp1上用root用户操做。

 
  1.  
    [root@hdp1~]#masterha_check_ssh --conf=/etc/masterha/app1.cnf
  2.  
    Tue Jul 31 12:50:22 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
  3.  
    Tue Jul 31 12:50:22 2018 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
  4.  
    Tue Jul 31 12:50:22 2018 - [info] Reading server configuration from /etc/masterha/app1.cnf..
  5.  
    Tue Jul 31 12:50:22 2018 - [info] Starting SSH connection tests..
  6.  
    Tue Jul 31 12:50:23 2018 - [debug] 
  7.  
    Tue Jul 31 12:50:22 2018 - [debug]  Connecting via SSH from root@172.16.1.127(172.16.1.127:22) to root@172.16.1.126(172.16.1.126:22)..
  8.  
    Tue Jul 31 12:50:22 2018 - [debug]   ok.
  9.  
    Tue Jul 31 12:50:22 2018 - [debug]  Connecting via SSH from root@172.16.1.127(172.16.1.127:22) to root@172.16.1.125(172.16.1.125:22)..
  10.  
    Tue Jul 31 12:50:23 2018 - [debug]   ok.
  11.  
    Tue Jul 31 12:50:24 2018 - [debug] 
  12.  
    Tue Jul 31 12:50:23 2018 - [debug]  Connecting via SSH from root@172.16.1.126(172.16.1.126:22) to root@172.16.1.127(172.16.1.127:22)..
  13.  
    Tue Jul 31 12:50:23 2018 - [debug]   ok.
  14.  
    Tue Jul 31 12:50:23 2018 - [debug]  Connecting via SSH from root@172.16.1.126(172.16.1.126:22) to root@172.16.1.125(172.16.1.125:22)..
  15.  
    Tue Jul 31 12:50:23 2018 - [debug]   ok.
  16.  
    Tue Jul 31 12:50:25 2018 - [debug] 
  17.  
    Tue Jul 31 12:50:23 2018 - [debug]  Connecting via SSH from root@172.16.1.125(172.16.1.125:22) to root@172.16.1.127(172.16.1.127:22)..
  18.  
    Tue Jul 31 12:50:23 2018 - [debug]   ok.
  19.  
    Tue Jul 31 12:50:23 2018 - [debug]  Connecting via SSH from root@172.16.1.125(172.16.1.125:22) to root@172.16.1.126(172.16.1.126:22)..
  20.  
    Tue Jul 31 12:50:24 2018 - [debug]   ok.
  21.  
    Tue Jul 31 12:50:25 2018 - [info] All SSH connection tests passed successfully.
  22.  
    [root@hdp1~]#

        能够看到各个节点ssh验证都是ok的。

2. 检查整个复制环境情况

        在hdp1上用root用户操做。

 
  1.  
    [root@hdp1~]#masterha_check_repl --conf=/etc/masterha/app1.cnf
  2.  
    Tue Jul 31 12:52:19 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
  3.  
    Tue Jul 31 12:52:19 2018 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
  4.  
    Tue Jul 31 12:52:19 2018 - [info] Reading server configuration from /etc/masterha/app1.cnf..
  5.  
    Tue Jul 31 12:52:19 2018 - [info] MHA::MasterMonitor version 0.56.
  6.  
    Tue Jul 31 12:52:21 2018 - [info] GTID failover mode = 0
  7.  
    Tue Jul 31 12:52:21 2018 - [info] Dead Servers:
  8.  
    Tue Jul 31 12:52:21 2018 - [info] Alive Servers:
  9.  
    Tue Jul 31 12:52:21 2018 - [info]   172.16.1.127(172.16.1.127:3306)
  10.  
    Tue Jul 31 12:52:21 2018 - [info]   172.16.1.126(172.16.1.126:3306)
  11.  
    Tue Jul 31 12:52:21 2018 - [info]   172.16.1.125(172.16.1.125:3306)
  12.  
    Tue Jul 31 12:52:21 2018 - [info] Alive Slaves:
  13.  
    Tue Jul 31 12:52:21 2018 - [info]   172.16.1.126(172.16.1.126:3306)  Version=5.6.14-log (oldest major version between slaves) log-bin:enabled
  14.  
    Tue Jul 31 12:52:21 2018 - [info]     Replicating from 172.16.1.127(172.16.1.127:3306)
  15.  
    Tue Jul 31 12:52:21 2018 - [info]     Primary candidate for the new Master (candidate_master is set)
  16.  
    Tue Jul 31 12:52:21 2018 - [info]   172.16.1.125(172.16.1.125:3306)  Version=5.6.14-log (oldest major version between slaves) log-bin:enabled
  17.  
    Tue Jul 31 12:52:21 2018 - [info]     Replicating from 172.16.1.127(172.16.1.127:3306)
  18.  
    Tue Jul 31 12:52:21 2018 - [info] Current Alive Master: 172.16.1.127(172.16.1.127:3306)
  19.  
    Tue Jul 31 12:52:21 2018 - [info] Checking slave configurations..
  20.  
    Tue Jul 31 12:52:21 2018 - [info]  read_only=1 is not set on slave 172.16.1.126(172.16.1.126:3306).
  21.  
    Tue Jul 31 12:52:21 2018 - [info] Checking replication filtering settings..
  22.  
    Tue Jul 31 12:52:21 2018 - [info]  binlog_do_db= , binlog_ignore_db= 
  23.  
    Tue Jul 31 12:52:21 2018 - [info]  Replication filtering check ok.
  24.  
    Tue Jul 31 12:52:21 2018 - [info] GTID (with auto-pos) is not supported
  25.  
    Tue Jul 31 12:52:21 2018 - [info] Starting SSH connection tests..
  26.  
    Tue Jul 31 12:52:23 2018 - [info] All SSH connection tests passed successfully.
  27.  
    Tue Jul 31 12:52:23 2018 - [info] Checking MHA Node version..
  28.  
    Tue Jul 31 12:52:24 2018 - [info]  Version check ok.
  29.  
    Tue Jul 31 12:52:24 2018 - [info] Checking SSH publickey authentication settings on the current master..
  30.  
    Tue Jul 31 12:52:24 2018 - [info] HealthCheck: SSH to 172.16.1.127 is reachable.
  31.  
    Tue Jul 31 12:52:24 2018 - [info] Master MHA Node version is 0.56.
  32.  
    Tue Jul 31 12:52:24 2018 - [info] Checking recovery script configurations on 172.16.1.127(172.16.1.127:3306)..
  33.  
    Tue Jul 31 12:52:24 2018 - [info]   Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/data --output_file=/tmp/save_binary_logs_test --manager_version=0.56 --start_file=mysql-bin.000001 
  34.  
    Tue Jul 31 12:52:24 2018 - [info]   Connecting to root@172.16.1.127(172.16.1.127:22).. 
  35.  
      Creating /tmp if not exists..    ok.
  36.  
      Checking output directory is accessible or not..
  37.  
       ok.
  38.  
      Binlog found at /data, up to mysql-bin.000001
  39.  
    Tue Jul 31 12:52:25 2018 - [info] Binlog setting check done.
  40.  
    Tue Jul 31 12:52:25 2018 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
  41.  
    Tue Jul 31 12:52:25 2018 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=172.16.1.126 --slave_ip=172.16.1.126 --slave_port=3306 --workdir=/tmp --target_version=5.6.14-log --manager_version=0.56 --relay_log_info=/data/relay-log.info  --relay_dir=/data/  --slave_pass=xxx
  42.  
    Tue Jul 31 12:52:25 2018 - [info]   Connecting to root@172.16.1.126(172.16.1.126:22).. 
  43.  
      Checking slave recovery environment settings..
  44.  
        Opening /data/relay-log.info ... ok.
  45.  
        Relay log found at /data, up to hdp3-relay-bin.000003
  46.  
        Temporary relay log file is /data/hdp3-relay-bin.000003
  47.  
        Testing mysql connection and privileges..Warning: Using a password on the command line interface can be insecure.
  48.  
     done.
  49.  
        Testing mysqlbinlog output.. done.
  50.  
        Cleaning up test file(s).. done.
  51.  
    Tue Jul 31 12:52:25 2018 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=172.16.1.125 --slave_ip=172.16.1.125 --slave_port=3306 --workdir=/tmp --target_version=5.6.14-log --manager_version=0.56 --relay_log_info=/data/relay-log.info  --relay_dir=/data/  --slave_pass=xxx
  52.  
    Tue Jul 31 12:52:25 2018 - [info]   Connecting to root@172.16.1.125(172.16.1.125:22).. 
  53.  
      Checking slave recovery environment settings..
  54.  
        Opening /data/relay-log.info ... ok.
  55.  
        Relay log found at /data, up to hdp2-relay-bin.000003
  56.  
        Temporary relay log file is /data/hdp2-relay-bin.000003
  57.  
        Testing mysql connection and privileges..Warning: Using a password on the command line interface can be insecure.
  58.  
     done.
  59.  
        Testing mysqlbinlog output.. done.
  60.  
        Cleaning up test file(s).. done.
  61.  
    Tue Jul 31 12:52:25 2018 - [info] Slaves settings check done.
  62.  
    Tue Jul 31 12:52:25 2018 - [info] 
  63.  
    172.16.1.127(172.16.1.127:3306) (current master)
  64.  
     +--172.16.1.126(172.16.1.126:3306)
  65.  
     +--172.16.1.125(172.16.1.125:3306)
  66.  
     
  67.  
    Tue Jul 31 12:52:25 2018 - [info] Checking replication health on 172.16.1.126..
  68.  
    Tue Jul 31 12:52:25 2018 - [info]  ok.
  69.  
    Tue Jul 31 12:52:25 2018 - [info] Checking replication health on 172.16.1.125..
  70.  
    Tue Jul 31 12:52:25 2018 - [info]  ok.
  71.  
    Tue Jul 31 12:52:25 2018 - [info] Checking master_ip_failover_script status:
  72.  
    Tue Jul 31 12:52:25 2018 - [info]   /usr/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=172.16.1.127 --orig_master_ip=172.16.1.127 --orig_master_port=3306 
  73.  
     
  74.  
     
  75.  
    IN SCRIPT TEST====/sbin/ifconfig ens160:1 down==/sbin/ifconfig ens32:1 172.16.1.100===
  76.  
     
  77.  
    Checking the Status of the script.. OK 
  78.  
    SIOCSIFADDR: No such device
  79.  
    ens32:1: ERROR while getting interface flags: No such device
  80.  
    Tue Jul 31 12:52:25 2018 - [info]  OK.
  81.  
    Tue Jul 31 12:52:25 2018 - [warning] shutdown_script is not defined.
  82.  
    Tue Jul 31 12:52:25 2018 - [info] Got exit code 0 (Not master dead).
  83.  
     
  84.  
    MySQL Replication Health is OK.

        没有明显报错,只有几个警告而已,复制显示正常。

3. 检查MHA Manager的状态

        在hdp1上用root用户操做。

 
  1.  
    [root@hdp1~]#masterha_check_status --conf=/etc/masterha/app1.cnf
  2.  
    app1 is stopped(2:NOT_RUNNING).
  3.  
    [root@hdp1~]#

        显示"NOT_RUNNING",这表明MHA监控没有开启。执行下面的命令后台启动MHA。

 
  1.  
    mkdir -p  /var/log/masterha/app1/
  2.  
    nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

        启动参数说明:

  • remove_dead_master_conf:该参数表明当发生主从切换后,老的主库的ip将会从配置文件中移除。
  • manger_log:日志存放位置。
  • ignore_last_failover:在缺省状况下,若是MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之因此这样限制是为了不ping-pong效应。该参数表明忽略上次MHA触发切换产生的文件,默认状况下,MHA发生切换后会在日志目录,也就是上面设置的/data产生app1.failover.complete文件,下次再次切换的时候若是发现该目录下存在该文件将不容许触发切换,除非在第一次切换后收到删除该文件。为了方便,这里设置为--ignore_last_failover。

        再次检查MHA Manager的状态:

 
  1.  
    [root@hdp1~]#masterha_check_status --conf=/etc/masterha/app1.cnf
  2.  
    app1 (pid:298237) is running(0:PING_OK), master:172.16.1.127
  3.  
    [root@hdp1~]#

        能够看见已经在监控了,并且master的主机为172.16.1.127。

4. 查看启动日志

        在hdp1上用root用户操做。

 
  1.  
    [root@hdp1~]#tail -n20 /var/log/masterha/app1/manager.log
  2.  
    Tue Jul 31 12:57:06 2018 - [info] 
  3.  
    172.16.1.127(172.16.1.127:3306) (current master)
  4.  
     +--172.16.1.126(172.16.1.126:3306)
  5.  
     +--172.16.1.125(172.16.1.125:3306)
  6.  
     
  7.  
    Tue Jul 31 12:57:06 2018 - [info] Checking master_ip_failover_script status:
  8.  
    Tue Jul 31 12:57:06 2018 - [info]   /usr/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=172.16.1.127 --orig_master_ip=172.16.1.127 --orig_master_port=3306 
  9.  
     
  10.  
     
  11.  
    IN SCRIPT TEST====/sbin/ifconfig ens160:1 down==/sbin/ifconfig ens32:1 172.16.1.100===
  12.  
     
  13.  
    Checking the Status of the script.. OK 
  14.  
    SIOCSIFADDR: No such device
  15.  
    ens32:1: ERROR while getting interface flags: No such device
  16.  
    Tue Jul 31 12:57:06 2018 - [info]  OK.
  17.  
    Tue Jul 31 12:57:06 2018 - [warning] shutdown_script is not defined.
  18.  
    Tue Jul 31 12:57:06 2018 - [info] Set master ping interval 1 seconds.
  19.  
    Tue Jul 31 12:57:06 2018 - [info] Set secondary check script: /usr/bin/masterha_secondary_check -s hdp4 -s hdp3 --user=root --master_host=hdp4 --master_ip=172.16.1.127 --master_port=3306
  20.  
    Tue Jul 31 12:57:06 2018 - [info] Starting ping health check on 172.16.1.127(172.16.1.127:3306)..
  21.  
    Tue Jul 31 12:57:06 2018 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
  22.  
    [root@hdp1~]#

5、功能测试

1. 初始绑定VIP

        在hdp4 172.16.1.127(master)上用root用户执行:

/sbin/ifconfig ens160:1 172.16.1.100/24

        查看VIP:

 
  1.  
    [root@hdp4~]#ip a
  2.  
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
  3.  
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4.  
        inet 127.0.0.1/8 scope host lo
  5.  
           valid_lft forever preferred_lft forever
  6.  
        inet6 ::1/128 scope host 
  7.  
           valid_lft forever preferred_lft forever
  8.  
    2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
  9.  
        link/ether 00:50:56:a5:49:7f brd ff:ff:ff:ff:ff:ff
  10.  
        inet 172.16.1.127/24 brd 172.16.1.255 scope global ens160
  11.  
           valid_lft forever preferred_lft forever
  12.  
        inet 172.16.1.100/16 brd 172.16.255.255 scope global ens160:1
  13.  
           valid_lft forever preferred_lft forever
  14.  
        inet6 fe80::250:56ff:fea5:497f/64 scope link 
  15.  
           valid_lft forever preferred_lft forever
  16.  
    [root@hdp4~]#

2. 测试自动切换

(1)在slave1库(172.16.1.126)上停掉slave IO线程,模拟主从延时:

mysql -uroot -p123456 -e "stop slave io_thread;"

(2)在master库(172.16.1.127)安装sysbench,进行sysbench数据生成,在sbtest库下生成sbtest表,共10W记录。

 
  1.  
    # 用root用户安装sysbench
  2.  
    yum install sysbench -y
  3.  
     
  4.  
    # 用mysql用户创建sbtest 数据库
  5.  
    mysql -uroot -p123456 -e "create database sbtest;"
  6.  
     
  7.  
    # 用mysql用户执行sysbench生成数据
  8.  
    sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=complex --oltp-tables-count=10 --oltp-table-size=10000 --threads=10 --time=120 --report-interval=10 --db-driver=mysql prepare

(3)用root用户中止master的mysql服务。

service mysql stop

(4)验证VIP漂移。
        在hdp3上用root用户操做。

 
  1.  
    [root@hdp3~]#ip a
  2.  
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
  3.  
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4.  
        inet 127.0.0.1/8 scope host lo
  5.  
           valid_lft forever preferred_lft forever
  6.  
        inet6 ::1/128 scope host 
  7.  
           valid_lft forever preferred_lft forever
  8.  
    2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  9.  
        link/ether 00:50:56:a5:0f:77 brd ff:ff:ff:ff:ff:ff
  10.  
        inet 172.16.1.126/24 brd 172.16.1.255 scope global ens32
  11.  
           valid_lft forever preferred_lft forever
  12.  
        inet 172.16.1.100/16 brd 172.16.255.255 scope global ens32:1
  13.  
           valid_lft forever preferred_lft forever
  14.  
        inet6 fe80::250:56ff:fea5:f77/64 scope link 
  15.  
           valid_lft forever preferred_lft forever
  16.  
    [root@hdp3~]#

        在hdp4上用root用户操做。

 
  1.  
    [root@hdp4~]#ip a
  2.  
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
  3.  
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4.  
        inet 127.0.0.1/8 scope host lo
  5.  
           valid_lft forever preferred_lft forever
  6.  
        inet6 ::1/128 scope host 
  7.  
           valid_lft forever preferred_lft forever
  8.  
    2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
  9.  
        link/ether 00:50:56:a5:49:7f brd ff:ff:ff:ff:ff:ff
  10.  
        inet 172.16.1.127/24 brd 172.16.1.255 scope global ens160
  11.  
           valid_lft forever preferred_lft forever
  12.  
        inet6 fe80::250:56ff:fea5:497f/64 scope link 
  13.  
           valid_lft forever preferred_lft forever
  14.  
    [root@hdp4~]#

        能够看到VIP已经从hdp4 172.16.1.127(master)漂移到了hdp3 172.16.1.126(slave1)。

(5)客户端用VIP访问数据库

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.100 -e "show databases; use sbtest; show tables; select count(*) from sbtest1; select count(*) from sbtest10;"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    +--------------------+
  4.  
    | Database           |
  5.  
    +--------------------+
  6.  
    | information_schema |
  7.  
    | mysql              |
  8.  
    | performance_schema |
  9.  
    | sbtest             |
  10.  
    | source             |
  11.  
    | test               |
  12.  
    +--------------------+
  13.  
    +------------------+
  14.  
    | Tables_in_sbtest |
  15.  
    +------------------+
  16.  
    | sbtest1          |
  17.  
    | sbtest10         |
  18.  
    | sbtest2          |
  19.  
    | sbtest3          |
  20.  
    | sbtest4          |
  21.  
    | sbtest5          |
  22.  
    | sbtest6          |
  23.  
    | sbtest7          |
  24.  
    | sbtest8          |
  25.  
    | sbtest9          |
  26.  
    +------------------+
  27.  
    +----------+
  28.  
    | count(*) |
  29.  
    +----------+
  30.  
    |    10000 |
  31.  
    +----------+
  32.  
    +----------+
  33.  
    | count(*) |
  34.  
    +----------+
  35.  
    |    10000 |
  36.  
    +----------+
  37.  
     
  38.  
    C:\WINDOWS\system32>

        在还没建立sbtest库的时候,172.16.1.126就停了slave sql线程。在新的Master 172.16.1.126上查看数据,能够看到落后的数据也同步过来了,数据没有丢失。

(6)查看复制的主从切换

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.125 -e "show slave status\G"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    *************************** 1. row ***************************
  4.  
                   Slave_IO_State: Waiting for master to send event
  5.  
                      Master_Host: 172.16.1.126
  6.  
                      Master_User: repl
  7.  
                      Master_Port: 3306
  8.  
                    Connect_Retry: 60
  9.  
                  Master_Log_File: mysql-bin.000001
  10.  
              Read_Master_Log_Pos: 19093607
  11.  
                   Relay_Log_File: hdp2-relay-bin.000002
  12.  
                    Relay_Log_Pos: 283
  13.  
            Relay_Master_Log_File: mysql-bin.000001
  14.  
                 Slave_IO_Running: Yes
  15.  
                Slave_SQL_Running: Yes
  16.  
                  Replicate_Do_DB:
  17.  
              Replicate_Ignore_DB:
  18.  
               Replicate_Do_Table:
  19.  
           Replicate_Ignore_Table:
  20.  
          Replicate_Wild_Do_Table:
  21.  
      Replicate_Wild_Ignore_Table:
  22.  
                       Last_Errno: 0
  23.  
                       Last_Error:
  24.  
                     Skip_Counter: 0
  25.  
              Exec_Master_Log_Pos: 19093607
  26.  
                  Relay_Log_Space: 455
  27.  
                  Until_Condition: None
  28.  
                   Until_Log_File:
  29.  
                    Until_Log_Pos: 0
  30.  
               Master_SSL_Allowed: No
  31.  
               Master_SSL_CA_File:
  32.  
               Master_SSL_CA_Path:
  33.  
                  Master_SSL_Cert:
  34.  
                Master_SSL_Cipher:
  35.  
                   Master_SSL_Key:
  36.  
            Seconds_Behind_Master: 0
  37.  
    Master_SSL_Verify_Server_Cert: No
  38.  
                    Last_IO_Errno: 0
  39.  
                    Last_IO_Error:
  40.  
                   Last_SQL_Errno: 0
  41.  
                   Last_SQL_Error:
  42.  
      Replicate_Ignore_Server_Ids:
  43.  
                 Master_Server_Id: 126
  44.  
                      Master_UUID: fadd5b7d-7d9f-11e8-90b4-13ccc7802b56
  45.  
                 Master_Info_File: /data/master.info
  46.  
                        SQL_Delay: 0
  47.  
              SQL_Remaining_Delay: NULL
  48.  
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
  49.  
               Master_Retry_Count: 86400
  50.  
                      Master_Bind:
  51.  
          Last_IO_Error_Timestamp:
  52.  
         Last_SQL_Error_Timestamp:
  53.  
                   Master_SSL_Crl:
  54.  
               Master_SSL_Crlpath:
  55.  
               Retrieved_Gtid_Set:
  56.  
                Executed_Gtid_Set:
  57.  
                    Auto_Position: 0
  58.  
     
  59.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.126 -e "show slave status\G"
  60.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  61.  
     
  62.  
    C:\WINDOWS\system32>

        能够看到,172.16.1.126称为新的master,而172.16.1.125也指向了这个新的master。

(7)检查MHA Manager的状态
        在hdp1上用root用户执行下面的操做。

 
  1.  
    [root@hdp1~]#masterha_check_status --conf=/etc/masterha/app1.cnf
  2.  
    app1 is stopped(2:NOT_RUNNING).
  3.  
    [1]+  Done                    nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1
  4.  
    [root@hdp1~]#

        发如今执行了一次自动failover后,MHA Manager进程中止了。官网上对这种状况的解释以下:

        意思是安装一个进程工具,经过该工具结合脚原本管理进程。

3. 测试手工切换

        首先要还原环境。

        还原数据库复制:

 
  1.  
    -- 在hdp四、hdp三、hdp2上重置master、slave
  2.  
    stop slave;
  3.  
    drop database sbtest;
  4.  
    reset master;
  5.  
    reset slave all;
  6.  
     
  7.  
    -- 在hdp三、hdp2上从新指向hdp4为master
  8.  
    change master to
  9.  
    master_host='172.16.1.127',
  10.  
    master_port=3306,
  11.  
    master_user='repl',
  12.  
    master_password='123456',
  13.  
    master_log_file='mysql-bin.000001',
  14.  
    master_log_pos=120;
  15.  
     
  16.  
    start slave;
  17.  
    show slave status\G

        还原VIP绑定:

 
  1.  
    # 在hdp3上用root用户执行
  2.  
    /sbin/ifconfig ens32:1 down
  3.  
     
  4.  
    # 在hdp4上用root用户执行
  5.  
    /sbin/ifconfig ens160:1 172.16.1.100

        还原配置文件:
        编辑在hdp1上/etc/masterha/app1.cnf,将[server1]段添加回去。

        启动MHA Manage:

 
  1.  
    # 在hdp1上用root用户执行
  2.  
    nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

        至此环境还原完毕,能够开始测试手工切换。当主服务器故障时,人工手动调用MHA来进行故障切换操做,步骤以下。
(1)中止MHA Manage
        在hdp1上用root用户操做。

masterha_stop --conf=/etc/masterha/app1.cnf

(2)关闭master
        在hdp4上用root用户操做。

service mysql stop

(3)执行手工切换
        在hdp1上用root用户操做。

masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=172.16.1.127 --dead_master_port=3306 --new_master_host=172.16.1.126 --new_master_port=3306 --ignore_last_failover

(4)验证VIP漂移到172.16.1.126

 
  1.  
    [root@hdp3~]#ip a
  2.  
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
  3.  
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4.  
        inet 127.0.0.1/8 scope host lo
  5.  
           valid_lft forever preferred_lft forever
  6.  
        inet6 ::1/128 scope host 
  7.  
           valid_lft forever preferred_lft forever
  8.  
    2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  9.  
        link/ether 00:50:56:a5:0f:77 brd ff:ff:ff:ff:ff:ff
  10.  
        inet 172.16.1.126/24 brd 172.16.1.255 scope global ens32
  11.  
           valid_lft forever preferred_lft forever
  12.  
        inet 172.16.1.100/16 brd 172.16.255.255 scope global ens32:1
  13.  
           valid_lft forever preferred_lft forever
  14.  
        inet6 fe80::250:56ff:fea5:f77/64 scope link 
  15.  
           valid_lft forever preferred_lft forever
  16.  
    [root@hdp3~]#

(5)验证复制关系

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.125 -e "show slave status\G"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    *************************** 1. row ***************************
  4.  
                   Slave_IO_State: Waiting for master to send event
  5.  
                      Master_Host: 172.16.1.126
  6.  
                      Master_User: repl
  7.  
                      Master_Port: 3306
  8.  
                    Connect_Retry: 60
  9.  
                  Master_Log_File: mysql-bin.000001
  10.  
              Read_Master_Log_Pos: 120
  11.  
                   Relay_Log_File: hdp2-relay-bin.000002
  12.  
                    Relay_Log_Pos: 283
  13.  
            Relay_Master_Log_File: mysql-bin.000001
  14.  
                 Slave_IO_Running: Yes
  15.  
                Slave_SQL_Running: Yes
  16.  
                  Replicate_Do_DB:
  17.  
              Replicate_Ignore_DB:
  18.  
               Replicate_Do_Table:
  19.  
           Replicate_Ignore_Table:
  20.  
          Replicate_Wild_Do_Table:
  21.  
      Replicate_Wild_Ignore_Table:
  22.  
                       Last_Errno: 0
  23.  
                       Last_Error:
  24.  
                     Skip_Counter: 0
  25.  
              Exec_Master_Log_Pos: 120
  26.  
                  Relay_Log_Space: 455
  27.  
                  Until_Condition: None
  28.  
                   Until_Log_File:
  29.  
                    Until_Log_Pos: 0
  30.  
               Master_SSL_Allowed: No
  31.  
               Master_SSL_CA_File:
  32.  
               Master_SSL_CA_Path:
  33.  
                  Master_SSL_Cert:
  34.  
                Master_SSL_Cipher:
  35.  
                   Master_SSL_Key:
  36.  
            Seconds_Behind_Master: 0
  37.  
    Master_SSL_Verify_Server_Cert: No
  38.  
                    Last_IO_Errno: 0
  39.  
                    Last_IO_Error:
  40.  
                   Last_SQL_Errno: 0
  41.  
                   Last_SQL_Error:
  42.  
      Replicate_Ignore_Server_Ids:
  43.  
                 Master_Server_Id: 126
  44.  
                      Master_UUID: fadd5b7d-7d9f-11e8-90b4-13ccc7802b56
  45.  
                 Master_Info_File: /data/master.info
  46.  
                        SQL_Delay: 0
  47.  
              SQL_Remaining_Delay: NULL
  48.  
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
  49.  
               Master_Retry_Count: 86400
  50.  
                      Master_Bind:
  51.  
          Last_IO_Error_Timestamp:
  52.  
         Last_SQL_Error_Timestamp:
  53.  
                   Master_SSL_Crl:
  54.  
               Master_SSL_Crlpath:
  55.  
               Retrieved_Gtid_Set:
  56.  
                Executed_Gtid_Set:
  57.  
                    Auto_Position: 0
  58.  
     
  59.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.126 -e "show slave status\G"
  60.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  61.  
     
  62.  
    C:\WINDOWS\system32>

(6)验证客户端VIP访问

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.100 -e "show variables like 'server_id'; show databases;"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    +---------------+-------+
  4.  
    | Variable_name | Value |
  5.  
    +---------------+-------+
  6.  
    | server_id     | 126   |
  7.  
    +---------------+-------+
  8.  
    +--------------------+
  9.  
    | Database           |
  10.  
    +--------------------+
  11.  
    | information_schema |
  12.  
    | mysql              |
  13.  
    | performance_schema |
  14.  
    | source             |
  15.  
    | test               |
  16.  
    +--------------------+
  17.  
     
  18.  
    C:\WINDOWS\system32>

4. 测试在线切换

        在许多状况下,须要将现有的主服务器迁移到另一台服务器上。好比主服务器硬件故障,RAID控制卡须要重建,将主服务器移到性能更好的服务器上等等。维护主服务器引发性能降低,致使停机时间至少没法写入数据。另外,阻塞或杀掉当前运行的会话会致使主主之间数据不一致的问题发生。MHA 提供快速切换和优雅的阻塞写入,这个切换过程只须要 0.5-2s 的时间,这段时间内数据是没法写入的。在不少状况下,0.5-2s 的阻塞写入是能够接受的。所以切换主服务器不须要计划分配维护时间窗口。

        MHA在线切换的大概过程:

  1. 检测复制设置和肯定当前主服务器
  2. 肯定新的主服务器
  3. 阻塞写入到当前主服务器
  4. 等待全部从服务器遇上复制
  5. 授予写入到新的主服务器
  6. 从新设置从服务器 

        注意,在线切换的时候应用架构须要考虑如下两个问题:

  1. 自动识别master和slave的问题(master的机器可能会切换),若是采用了vip的方式,基本能够解决这个问题。
  2. 负载均衡的问题(能够定义大概的读写比例,每台机器可承担的负载比例,当有机器离开集群时,须要考虑这个问题)

        为了保证数据彻底一致性,在最快的时间内完成切换,MHA的在线切换必须知足如下条件才会切换成功,不然会切换失败。

  • 全部slave的IO线程都在运行
  • 全部slave的SQL线程都在运行
  • 全部的show slave status的输出中Seconds_Behind_Master参数小于或者等于running_updates_limit秒。若是在切换过程当中不指定running_updates_limit,那么默认状况下running_updates_limit为1秒。
  • 在master端,经过show processlist输出,没有一个更新花费的时间大于running_updates_limit秒。

        在测试前,先按照上面“测试手工切换”测试前的步骤执行还原环境(手工切换不用修改/etc/masterha/app1.cnf配置文件),而后按如下步骤测试线切换:

(1)中止MHA Manage
        在hdp1上用root用户操做。

masterha_stop --conf=/etc/masterha/app1.cnf

(2)执行在线切换命令
        在hdp1上用root用户操做。

masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=172.16.1.126 --new_master_port=3306  --orig_master_is_new_slave --running_updates_limit=10000

(3)验证复制关系
        在hdp二、hdp三、hdp4查看slave status:

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.125 -e "show slave status\G"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    *************************** 1. row ***************************
  4.  
                   Slave_IO_State: Waiting for master to send event
  5.  
                      Master_Host: 172.16.1.126
  6.  
                      Master_User: repl
  7.  
                      Master_Port: 3306
  8.  
                    Connect_Retry: 60
  9.  
                  Master_Log_File: mysql-bin.000001
  10.  
              Read_Master_Log_Pos: 120
  11.  
                   Relay_Log_File: hdp2-relay-bin.000002
  12.  
                    Relay_Log_Pos: 283
  13.  
            Relay_Master_Log_File: mysql-bin.000001
  14.  
                 Slave_IO_Running: Yes
  15.  
                Slave_SQL_Running: Yes
  16.  
                  Replicate_Do_DB:
  17.  
              Replicate_Ignore_DB:
  18.  
               Replicate_Do_Table:
  19.  
           Replicate_Ignore_Table:
  20.  
          Replicate_Wild_Do_Table:
  21.  
      Replicate_Wild_Ignore_Table:
  22.  
                       Last_Errno: 0
  23.  
                       Last_Error:
  24.  
                     Skip_Counter: 0
  25.  
              Exec_Master_Log_Pos: 120
  26.  
                  Relay_Log_Space: 455
  27.  
                  Until_Condition: None
  28.  
                   Until_Log_File:
  29.  
                    Until_Log_Pos: 0
  30.  
               Master_SSL_Allowed: No
  31.  
               Master_SSL_CA_File:
  32.  
               Master_SSL_CA_Path:
  33.  
                  Master_SSL_Cert:
  34.  
                Master_SSL_Cipher:
  35.  
                   Master_SSL_Key:
  36.  
            Seconds_Behind_Master: 0
  37.  
    Master_SSL_Verify_Server_Cert: No
  38.  
                    Last_IO_Errno: 0
  39.  
                    Last_IO_Error:
  40.  
                   Last_SQL_Errno: 0
  41.  
                   Last_SQL_Error:
  42.  
      Replicate_Ignore_Server_Ids:
  43.  
                 Master_Server_Id: 126
  44.  
                      Master_UUID: fadd5b7d-7d9f-11e8-90b4-13ccc7802b56
  45.  
                 Master_Info_File: /data/master.info
  46.  
                        SQL_Delay: 0
  47.  
              SQL_Remaining_Delay: NULL
  48.  
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
  49.  
               Master_Retry_Count: 86400
  50.  
                      Master_Bind:
  51.  
          Last_IO_Error_Timestamp:
  52.  
         Last_SQL_Error_Timestamp:
  53.  
                   Master_SSL_Crl:
  54.  
               Master_SSL_Crlpath:
  55.  
               Retrieved_Gtid_Set:
  56.  
                Executed_Gtid_Set:
  57.  
                    Auto_Position: 0
  58.  
     
  59.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.126 -e "show slave status\G"
  60.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  61.  
     
  62.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.127 -e "show slave status\G"
  63.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  64.  
    *************************** 1. row ***************************
  65.  
                   Slave_IO_State: Waiting for master to send event
  66.  
                      Master_Host: 172.16.1.126
  67.  
                      Master_User: repl
  68.  
                      Master_Port: 3306
  69.  
                    Connect_Retry: 60
  70.  
                  Master_Log_File: mysql-bin.000001
  71.  
              Read_Master_Log_Pos: 120
  72.  
                   Relay_Log_File: hdp4-relay-bin.000002
  73.  
                    Relay_Log_Pos: 283
  74.  
            Relay_Master_Log_File: mysql-bin.000001
  75.  
                 Slave_IO_Running: Yes
  76.  
                Slave_SQL_Running: Yes
  77.  
                  Replicate_Do_DB:
  78.  
              Replicate_Ignore_DB:
  79.  
               Replicate_Do_Table:
  80.  
           Replicate_Ignore_Table:
  81.  
          Replicate_Wild_Do_Table:
  82.  
      Replicate_Wild_Ignore_Table:
  83.  
                       Last_Errno: 0
  84.  
                       Last_Error:
  85.  
                     Skip_Counter: 0
  86.  
              Exec_Master_Log_Pos: 120
  87.  
                  Relay_Log_Space: 455
  88.  
                  Until_Condition: None
  89.  
                   Until_Log_File:
  90.  
                    Until_Log_Pos: 0
  91.  
               Master_SSL_Allowed: No
  92.  
               Master_SSL_CA_File:
  93.  
               Master_SSL_CA_Path:
  94.  
                  Master_SSL_Cert:
  95.  
                Master_SSL_Cipher:
  96.  
                   Master_SSL_Key:
  97.  
            Seconds_Behind_Master: 0
  98.  
    Master_SSL_Verify_Server_Cert: No
  99.  
                    Last_IO_Errno: 0
  100.  
                    Last_IO_Error:
  101.  
                   Last_SQL_Errno: 0
  102.  
                   Last_SQL_Error:
  103.  
      Replicate_Ignore_Server_Ids:
  104.  
                 Master_Server_Id: 126
  105.  
                      Master_UUID: fadd5b7d-7d9f-11e8-90b4-13ccc7802b56
  106.  
                 Master_Info_File: /data/master.info
  107.  
                        SQL_Delay: 0
  108.  
              SQL_Remaining_Delay: NULL
  109.  
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
  110.  
               Master_Retry_Count: 86400
  111.  
                      Master_Bind:
  112.  
          Last_IO_Error_Timestamp:
  113.  
         Last_SQL_Error_Timestamp:
  114.  
                   Master_SSL_Crl:
  115.  
               Master_SSL_Crlpath:
  116.  
               Retrieved_Gtid_Set:
  117.  
                Executed_Gtid_Set:
  118.  
                    Auto_Position: 0
  119.  
     
  120.  
    C:\WINDOWS\system32>

        能够看到hdp3 172.16.1.126成为新的master,而hdp2 172.16.1.125和hdp4 172.16.1.127 成为指向新master的slave。

(4)验证VIP自动漂移

 
  1.  
    [root@hdp3~]#ip a
  2.  
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
  3.  
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4.  
        inet 127.0.0.1/8 scope host lo
  5.  
           valid_lft forever preferred_lft forever
  6.  
        inet6 ::1/128 scope host 
  7.  
           valid_lft forever preferred_lft forever
  8.  
    2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  9.  
        link/ether 00:50:56:a5:0f:77 brd ff:ff:ff:ff:ff:ff
  10.  
        inet 172.16.1.126/24 brd 172.16.1.255 scope global ens32
  11.  
           valid_lft forever preferred_lft forever
  12.  
        inet 172.16.1.100/16 brd 172.16.255.255 scope global ens32:1
  13.  
           valid_lft forever preferred_lft forever
  14.  
        inet6 fe80::250:56ff:fea5:f77/64 scope link 
  15.  
           valid_lft forever preferred_lft forever
  16.  
    [root@hdp3~]#

(5)验证客户端经过VIP访问数据库

 
  1.  
    C:\WINDOWS\system32>mysql -uroot -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
  2.  
    mysql: [Warning] Using a password on the command line interface can be insecure.
  3.  
    +---------------+-------+
  4.  
    | Variable_name | Value |
  5.  
    +---------------+-------+
  6.  
    | server_id     | 126   |
  7.  
    +---------------+-------+
  8.  
     
  9.  
    C:\WINDOWS\system32>

5. 修复宕机的Master 

        一般状况下自动切换之后,原master可能已经废弃掉,待原master主机修复后,若是数据完整的状况下,可能想把原来master从新做为新主库的slave。这时咱们能够借助当时自动切换时刻的MHA日志来完成对原master的修复。下面是提取相关日志的命令:

grep -i "All other slaves should start" /var/log/masterha/app1/manager.log

        能够看到相似下面的信息:

All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.16.1.126', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=120, MASTER_USER='repl', MASTER_PASSWORD='123456';

        意思是说,若是Master主机修复好了,能够在修复好后的Master执行CHANGE MASTER操做,做为新的slave库。

参考:

相关文章
相关标签/搜索