前言

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,是一套优秀的作为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的搭建。

服务器环境介绍

4个节点: 其中master对外提供写服务,备选master(实际的slave,candicate master)提供读服务,slave也提供相关的读服务,一旦master宕机,将会把备选master提升为新的master,slave指向新的master

主从复制

master节点:

1
[root@localhost ~]# vim /etc/my.cnf

重启服务:

1
 systemctl restart mysqld

主库给从库授权:

1
2
3
4
5
6
7
grant replication slave on *.* to root@'%' identified by 'root';

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

flush privileges;

show master status;//查看主库master_log_file='mysqlbin.000004',master_log_pos=687

slave节点:

两台slave节点的server-id分别设置为2和3:

1
2
3
4
5
6
7
8
9
10
11
log_bin=mysql-bin
#服务器id,备选master(第一台slave)为2,第二台slave为3
server-id=2
sync-binlog=1
binlog-ignore-db=performance_schema
binlog-ignore-db=information_scheme
binlog-ignore-db=sys

relay_log=mysql-relay-bin
log_slave_updates=1
read_only=1

开启同步: 在slave节点执行如下命令:

1
2
 change master to master_host='192.168.1.123',master_port=3306,master_user='root',master_password
='root',master_log_file='mysql-bin.000004',master_log_pos=687;

会报错,我这里报错是因为我之前在这台机器上已经配置了主从同步,所以需要删除之前的配置:

1
reset slave all  //命令会删除从库的 replication 参数,之后 show slave status\G 的信息返回为空。

然后再执行同步的命令成功。

配置半同步复制:

master节点:
1
2
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.07 sec)
1
vim /etc/my.cnf
1
2
3
# 自动开启半同步复制
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=1000
1
 systemctl restart mysqld
slave节点:

两台从库都做如下配置:

1
 install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

修改配置文件:

1
2
 # 自动开启半同步复制
rpl_semi_sync_slave_enabled=ON

重启服务:

1
 systemctl restart mysqld

测试半同步状态: 可以通过mysql命令行确认:

1
 show variables like '%semi%'

在日志中进一再次确认,在master主库服务器上执行:

1
 cat /var/log/mysqld.log

可以看到在日志中开启了半同步:

MHA高可用搭建

四台机器ssh互通

在四台服务器上分别执行下面命令,生成公钥和私钥,换行回车采用默认值

1
 ssh-keygen -t rsa

在三台MySQL服务器分别执行下面命令,将公钥拷到MHA Manager服务器上

1
ssh-copy-id -i id_rsa.pub 192.168.1.128

之后可以在MHA Manager服务器上检查下,看看.ssh/authorized_keys文件是否包含3个公钥

1
 cat /root/.ssh/authorized_keys

从MHA Manager服务器执行下面命令,向其他三台MySQL服务器分发公钥信息,目的是让三台mysql服务器互通。

1
2
3
scp /root/.ssh/authorized_keys 192.168.1.123:$PWD
scp /root/.ssh/authorized_keys 192.168.1.9:$PWD
scp /root/.ssh/authorized_keys 192.168.1.125:$PWD

然后在MHA Manager服务器继续执行:

1
2
3
ssh-copy-id 192.168.1.9
ssh-copy-id 192.168.1.123
ssh-copy-id 192.168.1.125

目的是为了让mha和其他三台服务器互通。

完成后在 MHA Manager服务器用ssh命令来检测是否ssh互通:

1
2
3
ssh 192.168.1.123
ssh 192.168.1.9
ssh 192.168.1.125

注意:这里的互通指的是免密登录,输完"ssh ip"命令之后可以直接登录远程机器,而不用输入密码。

MHA下载安装

MHA下载

下载地址:

1
2
 https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58

1
https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

下载后,将Manager和Node的安装包分别上传到对应的服务器。

三台MySQL服务器需要安装node

MHA Manager服务器需要安装manager和node

MHA node安装

在所有的节点(4台服务器)安装mha node:

MHA的Node依赖于perl-DBD-MySQL,所以要先安装perl-DBD-MySQL。

1
2
3
 yum install perl-DBD-MySQL -y

rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

MHA manager安装

在MHA Manager服务器安装mha4mysql-node和mha4mysql-manager。

MHA的manager又依赖了perl-Config-Tiny、perl-Log-Dispatch、perl-Parallel-ForkManager,也分别进行安装。

1
2
3
4
5
 wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

rpm -ivh epel-release-latest-7.noarch.rpm

yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-ParallelForkManager -y

提示:由于perl-Log-Dispatch和perl-Parallel-ForkManager这两个被依赖包在yum仓库找不到,因此安装epel-release-latest-7.noarch.rpm。

继续:

1
2
3
 rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

MHA 配置文件

MHA Manager服务器需要为每个监控的 Master/Slave 集群提供一个专用的配置文件,而所有的Master/Slave 集群也可共享全局配置。 以下配置均在MHA Manager服务器上配置。 初始化配置目录 mkdir -p /var/log/mha/app1 touch /var/log/mha/app1/manager.log

配置监控全局配置文件

vim /etc/masterha_default.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[server default]
#用户名
user=root
#密码,mysql的密码
password=root
#ssh登录账号
ssh_user=root
#主从复制账号
repl_user=root
#主从复制密码,mysql的密码
repl_password=root
#ping次数
ping_interval=1
#二次检查的主机
secondary_check_script=masterha_secondary_check -s 192.168.1.125 -s
192.168.1.123 -s 192.168.1.9

配置监控实例配置文件

vim /etc/mha/app1.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[server default]
#MHA监控实例根目录
manager_workdir=/var/log/mha/app1
#MHA监控实例日志文件
manager_log=/var/log/mha/app1/manager.log
#[serverx] 服务器编号
#hostname 主机名
#candidate_master 可以做主库
#master_binlog_dir binlog日志文件目录
[server1]
hostname=192.168.1.125
candidate_master=1
master_binlog_dir="/var/lib/mysql"
#port=3306
[server2]
hostname=192.168.1.123
candidate_master=1
master_binlog_dir="/var/lib/mysql"
#port=3306
[server3]
hostname=192.168.1.9
candidate_master=1
master_binlog_dir="/var/lib/mysql"
#port=3306

MHA 配置检测

执行ssh通信检测

在MHA Manager服务器上执行:

1
 masterha_check_ssh --conf=/etc/mha/app1.cnf

检测MySQL主从复制

在MHA Manager服务器上执行:

1
 masterha_check_repl --conf=/etc/mha/app1.cnf

出现“MySQL Replication Health is OK.”证明MySQL复制集群没有问题。

遇到的问题:

解决方法: 在 /etc/mha/app1.cnf配置文件每个server中添加port端口号为3306,必须是3306,其他的报错。

MHA Manager启动

1
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 &

查看监控状态命令如下:

1
masterha_check_status --conf=/etc/mha/app1.cn

查看监控日志命令如下:

1
tail -f /var/log/mha/app1/manager.log

测试MHA故障转移

mha打开监控日志:

1
tail -f /var/log/mha/app1/manager.log

关闭Master MySQL服务器服务,模拟主节点崩溃

1
systemctl stop mysqld

日志里可以看到主节点master切换的相关字样。

将原主启动切换回主

启动主库mysql服务

1
 systemctl start mysqld

挂到新主做从库

1
2
 change master to
master_host='192.168.1.125',master_port=3306,master_user='root',master_password='root',master_log_file='mysql-bin.000008',master_log_pos=313;

master_log_file和master_log_pos参数去新主库中通过show master status\G参数查看。

1
 start slave; // 开启同步

使用MHA在线切换命令将原主切换回来

1
 masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive  --new_master_host=192.168.1.125 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000

报错: 解决方案: 设置从库为只读:

1
 set global read_only=1;

再次在线切换,还是报错,查看报错信息提示192.168.1.9这个从库有两个主库。原因是刚开始主库是192.168.1.125,故障之后主库切换成192.168.1.123了,现在如果转回原来的主库就报错。 解决方案:

1
2
change master to
master_host='192.168.1.123',master_port=3306,master_user='root',master_password='root',master_log_file='mysql-bin.000008',master_log_pos=634;