MySQL MHA专题

2021-11-24  本文已影响0人  这货不是王马勺

部署过程

主从环境准备

首先先搭建一主两从GTID复制环境,此处不赘述

配置关键程序软链接

(所有节点均执行)

ln -s /data/mysql/bin/mysqlbinlog    /usr/bin/mysqlbinlog
ln -s /data/mysql/bin/mysql          /usr/bin/mysql

配置各节点互信

db01:
rm -rf /root/.ssh
ssh-keygen
cd /root/.ssh
mv id_rsa.pub authorized_keys
scp -r /root/.ssh 10.0.0.52:/root
scp -r /root/.ssh 10.0.0.53:/root
各节点验证
db01:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db02:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db03:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date

或:
(1)生成本机的公钥:
ssh-keygen (只需要生成一个公钥就行所以只输入一次)
#当你在生成sshkey的时候在命令行下会提示你Enter file in which to save the key,让你确认密钥文件保存的路径,
一般回车即可(一般默认会在当前用户家目录下的.ssh目录下)。
#第二个提示是 Enter passphrase (empty for no passphrase) 让你输入一个密钥的密码,
如果不输入则留空;回车生成公钥完毕 :)
此时你可以使用cat命令看下自己的公私钥。
(2)ssh-copy-id复制公钥:
ssh-copy-id x.x.x.x (需要做ssh登陆的服务器ip)
#它会将本地的所有公钥都传到服务器
(3)复制完后输入exit退出ssh登陆
(4)使用ssh登陆:
ssh x.x.x.x (需要做ssh登陆的服务器ip)

安装软件

Manager工具包主要包括以下几个工具:
masterha_manger 启动MHA
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_master_monitor 检测master是否宕机
masterha_check_status 检测当前MHA运行状态
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息

Node工具包主要包括以下几个工具:
这些工具通常由MHA Manager的脚本触发,无需人为操作
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)

mha官网:https://code.google.com/archive/p/mysql-master-ha/
github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
可能已经失效了,需要用之前的包

所有节点都安装node软件依赖包
先解压上传的压缩包
然后

yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

在db01主库中创建mha需要的用户

grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';

如果主从是好的,则在主库创建完用户,会直接同步到从库

Manager软件安装(db03)

yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

Manager配置文件准备(db03)

创建配置文件目录

 mkdir -p /etc/mha

创建日志目录

 mkdir -p /var/log/mha/app1

编辑mha配置文件

vim /etc/mha/app1.cnf

或者

cat > /etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager        
manager_workdir=/var/log/mha/app1            
master_binlog_dir=/data/binlog       
user=mha                                   
password=mha                               
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root                               
[server1]                                   
hostname=10.0.0.51
port=3306                                  
[server2]            
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
EOF

注:
其中配置文件名可以按业务来改,将manager_log、manager_workdir也一并改,我们此处就是app1
manager_log是管理端日志,也可以定制
master_binlog_dir是主库binlog位置点,这个目录一定要有权限读取到(一般建议主从目录一致)
ping_interval=2指的是每两秒监控一次
repl_user=repl是主从复制专用用户
ssh_user=root是配置互信的用户(一般是用root)

状态检查

互信检查

[root@db03 ~]# masterha_check_ssh  --conf=/etc/mha/app1.cnf

主从状态检查

[root@db03 ~]# masterha_check_repl  --conf=/etc/mha/app1.cnf

启动MHA(db03):

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

注:
masterha_manager就是启动manager程序的,配置文件指向我们之前配好的文件
执行完命令后敲几下回车

查看MHA状态

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:4719) is running(0:PING_OK), master:10.0.0.51
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.51 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 51    |
+---------------+-------+
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.52 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 52    |
+---------------+-------+
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.53 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 53    |
+---------------+-------+

配置参数(db03)

在配置文件的[server default]下面添加以下参数:

master_ip_failover_script=/usr/local/bin/master_ip_failover

注意:其中/usr/local/bin/master_ip_failover,必须事先准备好
见本文最后

vim  /usr/local/bin/master_ip_failover

改如下几行:

my $vip = '10.0.0.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

其中第一行是vip地址
第二行是如eth0:1后面的:1,就是所谓的key
第三、四行是启动和停止的命令,注意所有节点的网卡必须是同名的,如ens33、eth0等方式都行
如果是ens33的话,就要改成

my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";

第四行同理

注:
如果有中文字符要转换为英文的

yun install -y dos2unix
dos2unix /usr/local/bin/master_ip_failover

还要更改权限,添加可执行权限

chmod +x /usr/local/bin/master_ip_failover

还需手工在主库上绑定vip(首次),注意一定要和配置文件中的ethN一致,我的是ens33:1(1是key指定的值)

ifconfig ens33:1 10.0.0.55/24

之后检查
仅第一次需要手工加
然后重启MHA(db03):

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

附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.10.0.55/24';  # Virtual IP 
my $key = "1"; 
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 "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n"; 

    if ( $command eq "stop" || $command eq "stopssh" ) {

        # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
        # If you manage master ip address at global catalog database,
        # invalidate orig_master_ip here.
        my $exit_code = 1;
        eval {
            print "Disabling the VIP on old master: $orig_master_host \n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "start" ) {

        # all arguments are passed.
        # If you manage master ip address at global catalog database,
        # activate new_master_ip here.
        # You can also grant write access (create user, set read_only=0, etc) here.
        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &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 \n"; 
        `ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}

# A simple system call that enable the VIP on the new master 
sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
    `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\n";
}

MHA工作原理

MHA自动故障切换的步骤

1.Manager会每隔3秒钟探测一次MASTER主库; (Hi, 主库你还活着吗?)

2.如果Manager探测到MASTER主库故障、无法访问,Manager会执行下面操作:

3.如果所有Node节点ssh连接、msyql主库连接均连接失败,则开始故障转移,简单地说
①找到数据最新的从库(通过对比relay-log,查看show slave status即可)
②将最新的从库上的新数据同步到其他从库
③提升一个从库为主库(一般情况提升数据最新的,二般情况提升我们指定的从库为主库)
④通过原来主库的binlog补全新的主库数据
⑤其他从库以新的主库为主做主从复制

详细步骤如下:
Phase 1
Configuration Check Phase..
检查数据库版本,检查是否启用GTID检查从库是否存活 检查配置文件的candidate

Phase 2
Dead Master Shutdown Phase.
该阶段会调用master_ip_failover脚本;去关闭所有Node的IO Thread
调用shutdown_script 强制关闭MASTER实例,防止应用程序来连接;

Phase 3
Master Recovery Phase..
Phase 3.1
Getting Latest Slaves Phase.
检查所有节点,从show slave status中对比获取最新的binlog/position
Phase 3.2
Saving Dead Master's Binlog Phase..
如果老的Master可以SSH,上去获取BINLOG,从position到END位置,获取这段BINLOG(MASETER产生这段BINLOG,还未来得及发送给SLAVE)将这部分日志发送给Manager节点(manager_workdir位置);
如果故障Master无法SSH,则无法获取这段日志
Phase 3.3
Determining New Master Phase..
对比所有SLAVE,从最新SALVE中同步差异realy log给其他slave;最终确保所有SLAVE数据一致
Phase 3.3
New Master Diff Log Generation Phase..
确认新master 是否为最新slave,如果不是,则从最新slave获取差异日志;
将manager上获取的BINLOG日志发送给new master;
Phase 3.4
Master Log Apply Phase..
对比新master的Exec_Master_Log_Pos和Read_Master_Log_Pos,判断恢复的位置;
在本地回放 3.3 Phase的差异日志; 获取新master的binlog和position;

Phase 4
Slaves Recovery Phase..
Phase 4.1
Starting Parallel Slave Diff Log Generation Phase.
对每个SLAVE恢复:所有SLAVE和最新Slave做对比,如果position不一致,则生产差异日志
Phase 4.2
Starting Parallel Slave Log Apply Phase.
每个SLAVE 应用差异日志;
执行CHANGE MASTER 挂在到新Master

Phase 5
New master cleanup phase..
reset slave all;

MHA配置文件参数

        #!/usr/bin/perl`

        print "password=$ROOT_PASS\n";`

        print "repl_password=$REPL_PASS\n";`

这个参数默认为空,所以mha manager不会调用这个参数做任何事情

参考:https://zhuanlan.zhihu.com/p/396007930

上一篇 下一篇

猜你喜欢

热点阅读