MySQL MHA数据库高可用+故障切换

1. MHA概述

MHA(MasterHigh Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,是一套优秀的 MySQL 高可用环境下故障切换和主从复制的软件。在 MySQL 故障切换过程中,MHA 能做 到在 0~30 秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

1.1 MHA的组成

该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)
MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在 一台 slave 节点上。
MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测 集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。

目前 MHA 主要支持一主多从的架构,要搭建 MHA 要求一个复制集群中必须最少有三 台数据库服务器,即一台充当 master,一台充当备用 master,另外一台充当从库。因为至 少需要三台服务器

1.2 MHA的特点

自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
自动故障切换过程的本质
故障切换(本质VIP漂移)
自动(使用脚本触发自动)
使用半同步复制,可以大大降低数据丢失的风险

2.搭建MHA过程

2.1 环境

四台虚拟机:
MHA-manager 192.168.152.127
master 192.168.152.130
slave1 192.168.152.129
slave2 192.168.152.128

2.1.1 在做主从复制的基础上进行MHA的搭建,在这里要注意:

  1. 所有服务器同步阿里云时钟服务器
yum install ntp -y
yum -y install ntpdate ntp
ntpdate ntp.aliyun.com
crontab -e
crontab -l
*/30 * * * * /usr/sbin/ntpdate ntp.aliyun.com
  1. 取消my.cnf里面的注释
  2. . 所有的库配置软链接
ln -s /usr/local/mysql/bin/mysql /usr/sbin   //优化管理 mysql命令
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin   //节点恢复
  1. 所有数据库提权
三台数据库:
grant replication slave on *.* to 'myslave'@'192.168.152.%' identified by '123456'; 
grant all privileges on *.* to 'mha'@'192.168.152.%' identified by 'manager';
grant all privileges on *.* to 'mha'@'master' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave1' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave2' identified by 'manager';

两台从服务器:
set global read_only=1; #开启只读

flush privileges;

验证只读的功能:

2.1.1 先安装epel源,在所有服务器上安装MHA依赖环境

yum install epel-release --nogpgcheck -y		##安装epel源,并且不进行gph检查
yum install -y perl-DBD-MySQL \				##perl针对于mysql数据库
perl-Config-Tiny \			###从配置文件中提拿其中的值
perl-Log-Dispatch \			##log-日志
perl-Parallel-ForkManager \		##子进程的函数,多线程管理模式
perl-ExtUtils-CBuilder \			###扩展工具
perl-ExtUtils-MakeMaker \		###扩展工具
perl-CPAN		##cpan perl中的数据库

MHA 软件包对于每个操作系统版本不一样,这里Centos7.4必须选择0.57版本
在所有服务器上必须先安装node组件,最后在MHA-manager节点上安装manager组件
因为manager依赖node组件

2.1.2 服务器安装node节点

四台服务器都安装节点:
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz -C ~
cd ~
cd mha4mysql-node-0.57/
[root@master mha4mysql-node-0.57]# perl Makefile.PL 
[root@master mha4mysql-node-0.57]# make && make install

manager自己还需要安装manager软件:
tar xf mha4mysql-manager-0.57.tar.gz -C ~
cd ~ 
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install

这时候可以在文件中查看到脚本文件

[root@manager ~]# cd /usr/local/bin
[root@manager bin]# ls
apply_diff_relay_logs  masterha_conf_host        masterha_stop
filter_mysqlbinlog     masterha_manager          purge_relay_logs
masterha_check_repl    masterha_master_monitor   save_binary_logs
masterha_check_ssh     masterha_master_switch
masterha_check_status  masterha_secondary_check

主要的是:
masterha check_ ssh检查MHA的SSH配置状况
masterha check_ repl 检查MySQL复制状况
masterha_ manger启动manager的脚本
masterha check_ status检测当前MHA运行状态
masterha_ master_ monitor检测master是否宕机
masterha_ master_ switch控制故障转移(自动或者手动)
masterha_ conf_ host添加或删除配置的server信息
masterha_ stop 关闭manager


save_binary_logs #保存和复制master的二进制日志
apply_diff_relay_logs #识别差异的中继日志时间,并将其差异的事件应用于其他的slave;filter:过滤
filter_mysqlbinlog #去除不必要的ROLLBACK回滚事件(MHA 已不适用这个工具)
purge_relay_logs #清除中继日志(不会阻塞 SQL线程)

master宕机之后,slave1主备顶上,实现方式:vip虚拟ip漂移到slave1

2.2 配置无密码认证

2.2.1 在mannager上配置到所有数据库节点的无密码认证

[root@manager ~]# ssh-keygen -t rsa
#一路回车
[root@manager ~]# ssh-copy-id 192.168.152.130
[root@manager ~]# ssh-copy-id 192.168.152.129
[root@manager ~]# ssh-copy-id 192.168.152.128

2.2.2 在master上配置到从数据库节点的无密码认证

[root@master ~]# ssh-keygen -t rsa
[root@master ~]# ssh-copy-id 192.168.152.129
[root@master ~]# ssh-copy-id 192.168.152.128

2.2.3 在slave1上配置到主-从数据库节点的无密码认证

[root@slave1 ~]# ssh-keygen -t rsa
[root@slave1 ~]# ssh-copy-id 192.168.152.130
[root@slave1 ~]# ssh-copy-id 192.168.152.128

2.2.4 在slave2上配置到主-从数据库节点的无密码认证

[root@slave2 ~]# ssh-keygen -t rsa
[root@slave2 ~]# ssh-copy-id 192.168.152.130
[root@slave2 ~]# ssh-copy-id 192.168.152.129

2.3 配置MHA

配置MHA-manager服务器:
[root@manager ~]# cp -ra /root/mha4mysql-manager-0.57/samples/scripts/ /usr/local/bin
#在MHA节点上复制相关脚本到/usr/local/bin目录
[root@manager ~]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
#脚本管理 VIP,也是推荐的一种方式,生产环境不建议使用 Keepalived

[root@manager ~]# ll /usr/local/bin/scripts/
总用量 32
-rwxr-xr-x. 1 1001 1001  3648 531 2015 master_ip_failover
-rwxr-xr-x. 1 1001 1001  9870 531 2015 master_ip_online_change
-rwxr-xr-x. 1 1001 1001 11867 531 2015 power_manager
-rwxr-xr-x. 1 1001 1001  1360 531 2015 send_report
[root@manager ~]# 

脚本具体作用:
master_ip_failover:自动切换时 VIP 管理的脚本
master_ip_online_change:在线切换时 vip 的管理
power_manager:故障发生后关闭主机的脚本
send_report:因故障切换后发送报警的脚本

2.3.1 配置MHA配置文件

[root@manager ~]# vim /usr/local/bin/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,  $new_master_user,
  $new_master_password
);
my $vip = '192.168.152.152';
#这里改成你同网段的一个未使用的ip作为虚拟ip
my $brdc = '192.168.152.255';
#虚拟ip的广播地址
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $exit_code = 0;
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
##my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
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,
  'new_master_user=s'     => \$new_master_user,
  'new_master_password=s' => \$new_master_password,
);

exit &main();

sub main {

print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

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

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" ) {

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";
exit 0;
}
else {
&usage();
exit 1;
}
}
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";
 }

2.3.2 创建MHA软件目录并拷贝配置文件

[root@manager ~]# mkdir /etc/masterha
[root@manager ~]# cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
[root@manager ~]# vim /etc/masterha/app1.cnf

[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/home/mysql
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
ping_interval=1
remote_workdir=/tmp
repl_password=123456
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.152.128 -s 192.168.152.129
shutdown_script=""
ssh_user=root
user=mha

[server1]
hostname=192.168.152.130
port=3306

[server2]
candidate_master=1
hostname=192.168.152.129
check_repl_delay=0
port=3306

[server3]
hostname=192.168.152.128
port=3306

2.3.3测试ssh无密码认证

[root@manager ~]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Sun Jul 25 00:44:34 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
......省略
Sun Jul 25 00:44:47 2021 - [debug]  Connecting via SSH from root@192.168.152.128(192.168.152.128:22) to root@192.168.152.129(192.168.152.129:22)..
Sun Jul 25 00:44:58 2021 - [debug]   ok.
Sun Jul 25 00:44:59 2021 - [info] All SSH connection tests passed successfully.

2.3.4 测试 mysq 主从连接情况

最后出现 MySQL Replication Health is OK 字样说明正常

[root@manager ~]# masterha_check_repl -conf=/etc/masterha/app1.cnf
......省略
Checking the Status of the script.. OK 
Tue Jul 27 00:27:43 2021 - [info]  OK.
Tue Jul 27 00:27:43 2021 - [warning] shutdown_script is not defined.
Tue Jul 27 00:27:43 2021 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

与此同时,查看了配置文件,忘记设置虚拟地址,在主服务器上设置

[root@master ~]# ifconfig ens33:1 192.168.152.152/24

[root@master ~]# ip a
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:16:8d:76 brd ff:ff:ff:ff:ff:ff
    inet 192.168.152.130/24 brd 192.168.152.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.152.152/24 brd 192.168.152.255 scope global secondary ens33:1
       valid_lft forever preferred_lft forever
    inet6 fe80::44a6:dd8b:9907:84f2/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

再者,想想有点不放心,重新做一下主从,进行刷新,看下节点对不对
而且要注意,配置文件里面注释的符号 # 不可用 //
重新测试一下

[root@manager ~]# masterha_check_repl -conf=/etc/masterha/app1.cnf
......省略
IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.152.152===

Checking the Status of the script.. OK 
Sun Jul 25 11:39:48 2021 - [info]  OK.
Sun Jul 25 11:39:48 2021 - [warning] shutdown_script is not defined.
Sun Jul 25 11:39:48 2021 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

2.4 测试MHA

2.4.1 后台启动MHA

[root@manager ~]# 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 &
[2] 90323
[root@manager ~]# jobs
[1]-  运行中               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 &
[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 &

2.4.2 查看当前的master节点

[root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:90286) is running(0:PING_OK), master:192.168.152.130

2.4.3 模拟故障查看master变化

手动 kill 掉当前的 master

[root@master ~]# pkill -9 mysqld
[root@master ~]# systemctl status mysqld
● mysqld.service - LSB: start and stop MySQL
   Loaded: loaded (/etc/rc.d/init.d/mysqld; bad; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)
Warning: mysqld.service changed on disk. Run 'systemctl daemon-reload' to reload units.

观察 MHA 日志,如果自动切换成功,最后会输出 successfully 字样

[root@manager ~]# tail -f /var/log/masterha/app1/manager.log
Sun Jul 25 14:17:04 2021 - [info]  OK.

......省略

----- Failover Report -----

app1: MySQL Master failover 192.168.152.130(192.168.152.130:3306) to 192.168.152.129(192.168.152.129:3306) succeeded

Master 192.168.152.130(192.168.152.130:3306) is down!

Check MHA Manager logs at manager:/var/log/masterha/app1/manager.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.152.130(192.168.152.130:3306)
The latest slave 192.168.152.129(192.168.152.129:3306) has all relay logs for recovery.
Selected 192.168.152.129(192.168.152.129:3306) as a new master.
192.168.152.129(192.168.152.129:3306): OK: Applying all logs succeeded.
192.168.152.129(192.168.152.129:3306): OK: Activated master IP address.
192.168.152.128(192.168.152.128:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
192.168.152.128(192.168.152.128:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.152.129(192.168.152.129:3306)
192.168.152.129(192.168.152.129:3306): Resetting slave info succeeded.
Master failover to 192.168.152.129(192.168.152.129:3306) completed successfully.
#看到最后是切换成功的

正常自动切换一次后,MHA 进程会退出。HMA 会自动修改 app1.cnf 文件内容, 将宕机的 mysql 节点删除。查看 slave1是否接管 VIP

查看是否建立虚拟地址:
[root@slave1 ~]# ip a
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:88:c7:1a brd ff:ff:ff:ff:ff:ff
    inet 192.168.152.129/24 brd 192.168.152.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
#可以看到建立了虚拟地址192.168.152.152
    inet 192.168.152.152/24 brd 192.168.152.255 scope global secondary ens33:1
       valid_lft forever preferred_lft forever
    inet6 fe80::28f4:882:db1c:f045/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

查看当前主库(slave1)的同步点和日志:
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000002 |      154 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

当前从服务器(slave2)的状态:
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.152.129
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

2.4.4 修复原master查看变化

启动数据库:
[root@master ~]# systemctl start mysqld
Warning: mysqld.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start mysqld
[root@master ~]# mysql -u root -p
Enter password: 

mysql> 

将其改为slave,加入主从:
mysql> change master to master_host='192.168.152.129',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.152.129
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: master-relay-bin.000002
                Relay_Log_Pos: 287
        Relay_Master_Log_File: master-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            
mysql> set global read_only=1;
mysql> flush privileges;

停掉当前主库(slave1)的同步进程,不然下次作为从库同步会报错:
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> reset slave;
Query OK, 0 rows affected (0.00 sec)



修改mha主配置文件:
[root@manager ~]#  vim /etc/masterha/app1.cnf

[server1]
hostname=192.168.152.130
port=3306

[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.152.129
port=3306

[server3]
hostname=192.168.152.128
port=3306

重新测试主从复制:

这边检查了各项配置,重新做了主从关系,仍然不成功,胡七八糟的去百度了一番,各大网友基本上都是用的同一版本5.7版本或者是5.6版本,而我配置的则是 主服务器是5.6版本,从服务器是5.7版本,做到故障恢复之后,设置故障,VIP可以自己自动切换到从服务器slave1上,此时的slave1就是master,master变为slave1,但是做恢复的时候,很显然VIP 飘不过来了,这里我们要注意的是故障恢复,主要高版本兼容低版本,从可以比主高,,但是现在是master变为slave1,从服务器是5.6版本,就是从比主低,恢复起来会比较困难,5.6版本无法向上兼容。

这边在从服务器上创建了一个数据库,可以看到原主服务器跟从服务器2上可以查看到新建的数据库

mysql> create database ccc;
Query OK, 1 row affected (0.00 sec)

可以查看到效果:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| bbb                |
| ccc                |
| mysql              |
| performance_schema |
| test               |
| zwh                |
+--------------------+
8 rows in set (0.01 sec)

番外:如若使用的都是同一版本5.7版本,即可在manager服务器上输入如下命令,进行测试是否恢复成功:
这边使用5.7 按照主从复制+配置一系列的安装
做到最后一步,我们来看一下效果是否达成:
可以看到这里就是正确的,所以尽量还是需要同一版本

检查无密码认证和 MySQL 主从状态是否正常:
masterha_check_ssh -conf=/etc/masterha/app1.cnf
masterha_check_repl -conf=/etc/masterha/app1.cnf

查看当前的主服务器是否正确:
[root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:71745) is running(0:PING_OK), master:192.168.152.129

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值