MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL主从复制架构提供 了 automating master failover 功能。MHA 在监控到master 节点故障时,会提升其中拥有最新数据的 slave 节点成为新的master 节点,在此期间,MHA 会通过于其它从节点获取额外信息来避免一致性方面的问题。MHA 还提供了 master 节点的在线切换功能,即按需切换 master/slave 节点。

MHA是由日本人yoshinorim(原就职于DeNA现就职于FaceBook)开发的比较成熟的MySQL高可用方案。MHA能够在30秒内实现故障切换,并能在故障切换中,最大可能的保证数据一致性。目前淘宝也正在开发相似产品TMHA,目前已支持一主一从。
MySQL高可用架构之MHA_第1张图片

MHA 服务有两种角色,MHA Manager(管理节点)和 MHA Node(数据节点):

MHA Manager:

通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个master/slave 集群称作一个 application,用来管理统筹整个集群。

MHA node:

运行在每台 MySQL 服务器上(master/slave/manager),它通过监控具备解析和清理 logs 功能的脚本来加快故障转移。主要是接收管理节点所发出指令的代理,代理需要运行在每一个mysql节点上。

简单讲node就是用来收集从节点服务器上所生成的bin-log。对比打算提升为新的主节点之上的从节点的是否拥有并完成操作,如果没有发给新主节点在本地应用后提升为主节点。

MHA会提供诸多工具程序,其常见的如下所示

Manager节点:

masterha_check_ssh :MHA依赖的ssh环境监测工具

masterha_check_repl: MYSQL复制环境检测工具;

masterga_manager: MHA 服务主程序

masterha_check_status: MHA 运行状态探测工具;

masterha_master_monitor:MYSQL master节点可用性监测工具;

masterha_master_swith:master节点切换工具;

masterha_conf_host:添加或删除配置的节点;

masterha_stop:关闭MHA服务的工具。

Node节点:

save_binary_logs:保存和复制master的二进制日志;

apply_diff_relay_logs:识别差异的中继日志事件并应用于其他slave;

purge_relay_logs:清除中继日志(不会阻塞SQL线程);自定义扩展

secondary_check_script:通过多条网络路由检测master的可用性;

master_ip_failover_script:更新application使用的masterip;

report_script:发送报告

init_conf_load_script:加载初始配置参数;

master_ip_online_change_script:更新master节点ip地址;
MySQL高可用架构之MHA_第2张图片

MHA工作原理总结为以下几条:

(1)从宕机崩溃的master保存二进制日志事件(binlog events);

(2)识别含有最新更新的slave;

(3)应用差异的中继日志(relay log) 到其他slave;

(4)应用从master保存的二进制日志事件(binlog events);

(5)提升一个slave为新master;

(6)使用其他的slave连接新的master进行复制。

具体实战

一、准备实验MYSQL Replication环境:

MHA对MYSQL复制环境有特殊要求,例如各节点都要开启二进制日志及中继日志,各从节点必须显示启用其read-only属性,并关闭relay_log_purge功能等,这里对配置做事先说明。

本实验环境共有四个节点,其角色分配如下:

node1:MariaDB master
node2: MariaDB slave
node3: MariaDB slave
node4: MHA Manager

各节点的/etc/hosts文件配置内容中添加(每个节点都需要添加,以实现后期四个节点之间的ssh无密登录):

172.17.253.208 node1.magedu.com node1
172.17.254.204 node2.magedu.com node2
172.17.254.205 node3.magedu.com node3
172.17.254.188 node4.magedu.com node4

1、初始主节点master配置:

[mysqld]
server-id = 1
log-bin = master-log
relay-log = relay-log
skip_name_resolve = ON

2、所有slave节点依赖的配置(所有slave除了ID不同,其他配置都相同):

依赖的配置:
[mysqld]
server-id = 2 #复制集群中的各节点的id均必须唯一;
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0 #是否自动清空不再需要中继日志
skip_name_resolve = ON

3、按上述要求分别配置好主从节点之后,按MYSQL复制配置架构的配置方式将其配置完成并启动master节点和各slave节点,以及为各slave节点启动其IO和SQL线程,确保主从复制运行无误。操作如下:

master节点上:

MariaDB [(none)]>GRANT REPLICATION SLAVE,REPLICATION CLIENT ON*.* TO slave@'172.17.%.%' IDENTIFIED BY '55555';
MariaDB [(none)]> FLUSH PRIVILEGES;#刷新MySQL的系统权限相关表
MariaDB [(none)]> SHOW MASTER STATUS;

各slave节点上:

[root@node3 ~]# mysql
MariaDB [(none)]> CHANGE MASTER TO
MASTER_HOST='172.17.253.208′,MASTER_USER='slave',MASTER_PASSWORD='55555',MASTER_LOG_FILE='masterlog.000003′,MASTER_LOG_POS=498;
MariaDB [(none)]> START SLAVE;
MariaDB [(none)]> SHOW SLAVE STATUS\G

二、安装配置MHA

1、在所有MYSQL节点授权拥有管理权限的用户可在本地网络中有其他节点上远程访问。当然,此时仅需要且只能在master节点运行类似如下SQL语句即可。

mysql> GRANT ALL ON *.* TO 'mhaadmin'@'172.17.%.%' IDENTIFIED BY'mhapass';(授权MHA管理节点权限)

2、准备基于SSH互信通信环境:

MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。简单起见,可在Manager节点生成密钥对儿,并设置其可远程连接本地主机后,将私钥文件及authorized_keys文件复制给余下的所有节点即可。

下面操作在node4:Manager 节点上操作,每个节点上都需要同样的操作:

[root@node4 ~]# ssh-keygen -t rsa
[root@node4 ~]#ssh-copy-id -i .ssh/id_rsa.pub root@node4
[root@node4 ~]#ssh-copy-id -i .ssh/id_rsa.pub root@node3
[root@node4 ~]#ssh-copy-id -i .ssh/id_rsa.pub root@node2
[root@node4 ~]#ssh-copy-id -i .ssh/id_rsa.pub root@node1

3、 进行MHA安装包安装

Manager 节点: #yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
所有节点,包括Manager: #yum install mha4mysql-node-0.56-0.el6.norch.rpm

4、初始化MHA,进行配置

Manager 节点需要为每个监控的master/slave集群提供一个专用的配置文件,而所有的master/slave集群也可共享全局配置。全局配置文件默认为/etc/masterha_default.cnf,其为可选配置。如果仅监控一组master/slave集群,也可直接通过application的配置来提供各服务器的默认配置信息。而每个application的配置文件路径为自定义。

5、 定义MHA管理配置文件

在manager上为MHA专门创建一个管理用户,方便以后使用,在mysql的主节点上,三个节点自动同步

mkdir /etc/mha_master
vim /etc/mha_master/app1.cnf

配置文件内容如下;

[server default] //适用于server1,2,3个server的配置
user=mhaadmin //mha管理用户
password=mhapass //mha管理密码
manager_workdir=/etc/mha_master/app1 //mha_master自己的工作路径
manager_log=/etc/mha_master/manager.log // mha_master自己的日志文件
remote_workdir=/mydata/mha_master/app1 //每个远程主机的工作目录在何处,如果不存在该目录则需手动创建目录
ssh_user=root // 基于ssh的密钥认证
repl_user=slave//数据库用户名
repl_password=55555 //数据库密码
ping_interval=1 // ping间隔时长
[server1] //节点1(主节点),节点是按照节点数字从小到大读的
hostname=172.17.253.208 //节点1主机地址
ssh_port=22 //节点1的ssh端口
candidate_master=1 // 将来可不可以成为master候选节点/主节点

[server2]
hostname=172.17.254.204
ssh_port=22
candidate_master=1

[server3]
hostname=172.17.254.205
ssh_port=22
candidate_master=1

6、 检测各节点间ssh互信通信配置是否Ok:

[root@node4 ~]# masterha_check_ssh -conf=/etc/mha_master/app1.cnf
输出信息最后一行类似如下信息,表示其通过检测。
[info]All SSH connection tests passed successfully.

检查管理的MySQL复制集群的连接配置参数是否OK:

[root@node4 ~]#masterha_check_repl -conf=/etc/mha_master/app1.cnf
如果测试时会报错,可能是从节点上没有账号,因为这个架构,任何一个从节点,将有可能成为主节点,所以也需要创建账号。
因此,这里只要在mater节点上再次执行以下操作即可:
MariaDB [(none)]>GRANT REPLICATION SLAVE,REPLICATION CLIENT ON
*.* TO slave@'172.17.%.%' IDENTIFIED BY '55555';
MariaDB [(none)]> FLUSH PRIVILEGES;
Manager节点上再次运行,就显示Ok了。
有时也会出现如下的报错信息
Fri Nov 24 17:30:21 2017 - [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln393] 172.17.253.208(172.17.253.208:3306): User slave does not exist or does not have REPLICATION SLAVE privilege! Other slaves can not start replication from this host.
Fri Nov 24 17:30:21 2017 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln424] Error happened on checking configurations.  at /usr/share/perl5/vendor_perl/MHA/ServerManager.pm line 1403.
Fri Nov 24 17:30:21 2017 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln523] Error happened on monitoring servers.
Fri Nov 24 17:30:21 2017 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!
信息中会给出具体出错的节点IP,此时在该节点上运行如上操作也可以解决问题。

三、启动MHA

[root@node4 ~]#nohup masterha_manager -conf=/etc/mha_master/app1.cnf
&> /etc/mha_master/manager.log &(最后一个&符号表示在后台运行)

启动成功后,可用过如下命令来查看master节点的状态:

[root@node4 ~]#masterha_check_status -conf=/etc/mha_master/app1.cnf
app1 (pid:4978)is running(0:PING_OK),master:172.16.252.18
上面的信息中“app1 (pid:4978)is running(0:PING_OK)”表示MHA服务运行OK,否则,则会显示为类似“app1 is stopped(1:NOT_RUNNINg).”
如果要停止MHA,需要使用masterha_stop命令。
[root@node4 ~]#masterha_stop -conf=/etc/mha_master/app1.cnf

四、测试MHA测试故障转移

(1)在master节点关闭mariadb服务,模拟主节点数据崩溃

#killall -9 mysqld mysqld_safe
#rm -rf /var/lib/mysql/*

(2)在manager节点查看日志:

/etc/masterha/app1/manager.log 日志文件中出现如下信息(日志文件的位置是在之前的application的配置中配置的路径),表示manager检测到172.17.253.208节点故障,而后自动执行故障转移,将172.17.254.204提升为主节点。注意,故障转移完成后,manager将会自动停止,具体日志内容如下:

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

app1: MySQL Master failover 172.17.253.208(172.17.253.208:3306) to 172.17.254.204(172.17.254.204:3306) succeeded

Master 172.17.253.208(172.17.253.208:3306) is down!

Check MHA Manager logs at localhost.localdomain:/etc/mha_master/manager.log for details.

Started automated(non-interactive) failover.
The latest slave 172.17.254.204(172.17.254.204:3306) has all relay logs for recovery.
Selected 172.17.254.204(172.17.254.204:3306) as a new master.
172.17.254.204(172.17.254.204:3306): OK: Applying all logs succeeded.
172.17.254.205(172.17.254.205:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
172.17.254.205(172.17.254.205:3306): OK: Applying all logs succeeded. Slave started, replicating from 172.17.254.204(172.17.254.204:3306)
172.17.254.204(172.17.254.204:3306): Resetting slave info succeeded.
Master failover to 172.17.254.204(172.17.254.204:3306) completed successfully.

此时使用masterha_check_status命令检测将会遇到错误提示,如下所示:

#masterha_check_status –conf=/etc/masterha/app1.cnf 
app1 is stopped(2:NOT_RINNING).

(3) 提供新的从节点以修复复制集群

原有 master 节点故障后,需要重新准备好一个新的 MySQL 节点。基于来自于master 节点的备份恢复数据后,将其配置为新的 master 的从节点即可(对新的master做主从备份即可)。注意,新加入的节点如果为新 增节点,其 IP 地址要配置为原来 master 节点的 IP,否则,还需要修改 app1.cnf 中相应的 ip 地址。随后再次启动 manager,并再次检测其状态。

(4)新节点提供后再次执行检查操作

masterha_check_status -conf=/etc/mha_master/app1.cnf

masterha_check_repl -conf=/etc/mha_master/app1.cnf

检查无误,再次运行,这次要记录日志

masterha_manager -conf=/etc/mha_master/app1.cnf
&>/etc/mha_master/manager.log &

MySQL高可用架构之MHA_第3张图片
五、新节点上线,故障转换恢复注意事项

(1)、在生产环境中,当你的主节点挂了后,一定要在从节点上做一个备份,拿着备份文件把主节点手动提升为从节点,并指明从哪一个日志文件的位置开始复制

(2)、每一次自动完成转换后,每一次的(replication health )检测不ok始终都是启动不了必须手动修复主节点,除非你改配置文件

(3)、手动修复主节点提升为从节点后,再次运行检测命令

-[root@node5 ~]# masterha_check_repl --conf=/etc/mha_master/app1.cnf
app1 (pid:3211) is running(0:PING_OK), master:172.16.5.103

(4)、再次运行起来就恢复成功了

masterha_manager --conf=/etc/mha_master/app1.cnf