一、关于MHA不得不了解的
使用MHA能够让我们更大程度的解放双手,用更少的指令完成更多的事,MHA主要能够做以下几件事:
-
自动的在MASTER宕机后选举新的SLAVE作为MASTER,保证服务不被中断。
-
自动的在MASTER宕机后将所有未被选举为新MASTER的SLAVE重新指向新的MASTER并启动复制。
-
自动的在MASTER宕机后向数据库管理人员发送报警邮件 自动的进行VIP漂移服务,确保服务运行不会暂停。
-
MHA搭建条件最少是1主2从,且必须是独立的服务器,不能单机多实例进行搭建。
二、架构演示
MHA实际上就是一个软件集合,它的软件分为2部分:
- Manager软件
- Node软件
Node软件必须安装在所有的MHA节点上,而Manager软件则只需安装在管理节点上。
不同的软件由不同的工具包组成,如下所示:
-- Master
masterha_manager - 用于启动MHA
masterha_check_ssh - 用于检查MHA的SSH配置情况
masterha_check_repl - 用于检查MHA的主从复制情况
masterha_master_monitor - 用于检查Master节点是否宕机
masterha_check_status - 用于检查当前MHA的运行状态
masterha_master_switch - 用于自动故障恢复
masterha_conf_host - 用于添加或者删除Manager中配置的server信息
-- Node
save_binary_logs - 保存并复制Master的binlog
apply_diff_relay_logs - 识别差异的中继日志事件并将其差异的event事件应用于其他的Slave中
purge_relay_logs - 自动清除中继日志,且不会阻塞SQL_T线程
对于MASTER、SLAVE1、SLAVE2的作用这里不再描述,主要描述一下VIP以及Manager和binlog_server的作用:
-- VIP
对外服务的虚拟IP,当Master宕机之后故障转移过程中选举了新的Master时虚拟IP也会漂移到新Master上,确保服务不会中断
-- Manager
用于管理所有的Node,它会自动的监听MySQL主从复制的状态,当主库发生宕机后会开启一系列的故障转移工作
-- binlog_server
这是一个单独存放拷贝主库binlog的服务器,不会参与任何业务处理,并且不会与主库的binlog产生任何延迟,具体思路是当主库的事务准备提交前,会将binlog记录发送给该服务器,只有当二进制日志存储服务器将该条记录成功存储后,主库上这一事务方可被提交,由此可见,这种技术是在牺牲性能的前提下保证了数据的一致性,一般来说我们都会进行开启,在主机宕机且SSH不可被链接状态下,从库的数据恢复依然可以从二进制日志存储服务器中获取数据
三、工作流程
以下是MHA的工作流程,Manager节点通过masterha_manager脚本启动MHA后会先进行检查工作:
-
Manager节点通过masterha_check_ssh脚本检查各节点的互信配置
-
Manager节点通过masterha_check_repl脚本检查主从之间的复制情况
检查工作均完成且确认无误后,Manager节点会进行监控工作:
- Manager节点通过masterha_master_monitor对主库不断的进行心跳检测,主库3次无响应后会认为其以宕机
当主库宕机后,会开始故障转移工作,首先会对SLAVE进行选主,有以下3种算法:
- 读取Manager配置文件,判断是否有强制选主的Slave
- 自动判断目前已有从库的日志量,将最接近主库日志量的从库选为新的主库
- 根据配置文件中先后顺序进行选主
当选主完成后,Manager节点会再次通过SSH链接已宕机主库,有以下2种情况发生:
- 已宕机主库的SSH能够链接,表明MySQL服务是由逻辑因素所导致的宕机,此时Manager会通过save_binary_logs脚本,计算各个从库(包括新主库)与已宕机主库之间binlog差异,将已宕机主库的binlog位置找出来并进行截取、分发到各个从库上进行数据对齐,确保数据一致性
- 已宕机主库的SSH不能链接,表明MySQL服务是由物理因素所导致的宕机,此时Manager会通过apply_diff_relay_logs脚本,计算各个从库relay-log的差异,将差异较大的从库与新主库进行relay-log对齐,确保数据一致性
当所有库的数据一致性被确保之后,所有从库都将会与新主库建立主从关系,同时旧的已宕机主库信息将会从Manager项目配置文件中移除,至此整个MHA软件服务结束,Manager不会再对Node进行管理,接下来需要管理员手动对已宕机主库进行排查恢复,并且手动搭建旧主库与新主库之间的主从关系然后重新启动整个MHA服务
三、部署架构
node | IP | 安装组件 |
---|---|---|
mha01 | 192.168.47.101 | MySQL-Master |
mha02 | 192.168.47.102 | MySQL-Slave01 |
mha03 | 192.168.47.103 | MySQL-Slave02 |
mha04 | 192.168.47.104 | MHA Manager |
mha05 | 192.168.47.105 | binlog-server |
1、安装MySQL
MySQL的搭建过程这里就不说了,可以看这里Centos 安装MySQL 5.7.38
请注意节点上service-id 不能一样;此处MySQL的配置文件my.cnf中需要添加如下参数
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
2、配置主从MySQL
1、在MASTER上执行以下操作,创建复制用户:
[root@admin03 5.7.38_mysql_rpm]# mysql -uroot -pipaas@XX20200718173737 -e "set global validate_password_policy = 0;"
[root@admin03 5.7.38_mysql_rpm]# mysql -uroot -pipaas@XX20200718173737 -e "grant replication slave on *.* to repl@'%' identified by 'repl@123'";
-- 注意,如果是线上环境,请设置repl用户的允许登录地址
-- repl用户的权限是仅用于复制操作
2、在SLAVE1和SLAVE2上执行以下操作,这里我们不构建延时从库
- slave01节点
[root@admin03 ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.38-log MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.47.103',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='repl@123',
-> MASTER_PORT=3306,
-> MASTER_CONNECT_RETRY=10,
-> MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
- slave02节点
[root@admin03 ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.38-log MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.47.103',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='repl@123',
-> MASTER_PORT=3306,
-> MASTER_CONNECT_RETRY=10,
-> MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
- 查看主从复制状态
在SLAVE1和SLAVE2上执行以下操作,检查复制状态,确保IO_T和SQL_T都是Yes:
slave01
slave02
4、主从验证
这里我们对主从进行一次验证,为了后续的VIP功能测试,所以在主库创建一个数据库,看从库是否正常同步。
在master节点执行
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)
可以发现从库已经将主库创建的数据库test同步过来。