[toc]
MHA基于普通主从复制高可用
1.MHA简介
MHA通常在10到30秒内以最少的停机时间执行自动的主故障转移和从升级。MHA可以防止复制一致性问题,并节省了必须购买其他服务器的费用。所有这些都具有零性能下降,无复杂性(易于安装)并且无需更改现有部署的情况。
MHA还提供了计划的在线主设备切换,可以在停机(仅阻止写入)的几秒钟(0.5-2秒)内将当前正在运行的主设备安全地更改为新的主设备。
MHA提供以下功能,在需要高可用性,数据完整性和近乎不间断的主维护的许多部署中很有用。
-
自动化的主站监视和故障转移
- MHA可以监视现有复制环境中的MySQL主服务器,并在检测到主服务器故障时执行自动主服务器故障转移。MHA通过识别来自最新从站的差分中继日志事件并将其应用于所有其他从站,包括那些尚未收到最新中继日志事件的从站,来保证所有从站的一致性。MHA通常可以在几秒钟内执行故障转移:9到12秒钟用于检测主设备故障,可选地7到10秒钟用于关闭主计算机电源,以避免脑部分裂;几秒钟的时间将差分中继日志应用于新的主设备。总停机时间通常为10-30秒。可以在配置文件中将特定从站指定为候选主站(设置优先级)。由于MHA维护从站之间的一致性,任何奴隶都可以晋升为新主人。通常不会导致突然的复制失败的一致性问题将不会发生。
-
交互式(手动启动)主故障转移
- 可以将MHA配置为手动启动(非自动),交互式故障转移,而无需监视主服务器。
-
非交互式主服务器故障转移
- 还支持不监视主服务器的非交互式自动主服务器故障转移。当已经使用MySQL主软件监视时,此功能特别有用。例如,您可以使用Pacemaker(Heartbeat)检测主服务器故障和虚拟IP地址接管,而使用MHA进行主服务器故障转移和从属升级。
-
在线将主服务器切换到其他主机
- 通常有必要将现有的主服务器迁移到另一台计算机上,例如当前主服务器存在硬件RAID控制器或RAM问题,或者要用速度更快的计算机替换它等 时,这不是主服务器崩溃,但需要定期进行主维护。计划的主机维护应尽快完成,因为这会导致部分停机(禁用主机写入)。另一方面,您应该非常仔细地阻止/杀死当前正在运行的会话,因为不同的master之间可能会发生一致性问题(即“更新master1,更新master 2,提交master1,在提交master 2时出错”会导致数据不一致)。快速主开关和平稳阻止写入都是必需的。
MHA在写入器阻塞后的0.5-2秒内提供正常的主设备切换。通常可以接受0.5-2秒的写入器停机时间,因此即使不分配计划的维护时段,您也可以切换主机。升级到更高版本,更快的计算机等操作变得更加容易。
2.MHA架构
正常工作时架构

主库down机时架构

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。
MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。
MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。
在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失(配合mysql半同步复制效果更佳),但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。
注意:目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器。
工作过程:manager节点定时检测复制集群中的每一个node,如果master宕机会选出数据与master最接近的一台slave来作为新master,去到旧master中拷贝binlog到新master中并应用binlog以保证新master与旧master数据一致,然后将剩余的slave重新changer master to,将slave的主切换为新master
3.部署过程
实验环境
| 角色 | IP | 主机名 | 系统 | 机器配置 | mysql版本 |
|---|---|---|---|---|---|
| manager | 10.0.0.130 | mha | centos7.8 | 2c4g | 5.7.28 |
| mysql-master | 10.0.0.133 | mysql01 | centos7.8 | 2c4g | 5.7.28 |
| mysql-slave1 | 10.0.0.134 | mysql02 | centos7.8 | 2c4g | 5.7.28 |
| mysql-slave2 | 10.0.0.135 | mysql03 | centos7.8 | 2c4g | 5.7.28 |
3.1 下载安装包
Manager工具包主要包括以下几个工具:
| 名称 | 含义 |
|---|---|
| masterha_check_ssh | 检查MHA的SSH配置状况 |
| masterha_check_repl | 检查MySQL复制状况 |
| masterha_manger | 启动MHA |
| masterha_check_status | 检测当前MHA运行状态 |
| masterha_master_monitor | 检测master是否宕机 |
| masterha_master_switch | 控制故障转移(自动或者手动) |
| masterha_conf_host | 添加或删除配置的server信息 |
Node工具包(这些工具通常由MHA Manager的脚本触发,无需人为操作)主要包括以下几个工具:
| 名称 | 含义 |
|---|---|
| save_binary_logs | 保存和复制master的二进制日志 |
| apply_diff_relay_logs | 识别差异的中继日志事件并将其差异的事件应用于其他的slave |
| filter_mysqlbinlog | 去除不必要的ROLLBACK事件(MHA已不再使用这个工具) |
| purge_relay_logs | 清除中继日志(不会阻塞SQL线程) |
3.2 所有机器做相互免密钥配置
⚠️复制集群中的每个节点都有可能成为master,都得开启binlog和ssh密钥认证,因为当旧master宕机后,mha要拷贝binlog到所有node节点上,而且所有节点都有可能成为master,故每个节点都要彼此密钥认证
lowB脚本运行一下
#!/bin/bash
file_path=/root
file_name=host.txt
file=$file_path/$file_name
user=root
pwd=1
ssh_file=~/.ssh/id_rsa
yum -y install expect &> /dev/null
# 生成密钥
[ -f "$ssh_file" ] || ssh-keygen -q -N "" -f ~/.ssh/id_rsa
read -p "请输入开始数值: " start_num
read -p "请输入结束数值: " end_num
read -p "请输入网段(类似格式:10.0.0.):" sub_net
seq $start_num $end_num >$file
# 在文件开头加上网段,在文件末尾加上用户名和密码
sed -i 's/^/'$sub_net'/g' $file
sed -i 's/$/ '$user' '$pwd'/g' $file
echo -e "执行成功,文件内容如下:\n`cat $file`"
while read line;do
ip=`echo $line | awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
password=`echo $line | awk '{print $3}'`
expect <<EOF
spawn ssh-copy-id -i $username@$ip
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "$password\n"}
}
expect eof
EOF
done < $file
master操作(mysql01 10.0.0.133)
3.3 mysql主从配置
这里是把10.0.0.133(mysql01)、10.0.0.134(mysql02)、10.0.0.135(mysql03)搭建为ABB,即一主两从,其中mysql01是主库,其余两个节点是从库
3.3.1 编辑/etc/my.cnf
指定
serverid,并开启binlog
# 指定serverid,越小优先级越大
server_id=1
# 开启binlog日志,位置在mysql数据目录data下
log_bin=binlog
# 开启binlog日志索引,位置在mysql数据目录data下
log_bin_index=binlog.index
# 开启半同步复制
log_slave_updates=1
重启mysql
systemctl restart mysqld
3.3.2 创建专用复制用户和设置监控用户
允许从slave上连接过来的复制用户,3台mysql服务器都要创建复制用户和监控用户!!!
⚠️复制用户名称为repl,否在在后续检测mysql集群连接情况会报错,也可以在配置文件中修改复制用户
创建专用复制 用户
mysql> grant replication slave on *.* to 'repl'@'10.0.0.%' identified by 'Bxb123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)
设置监控用户
⚠️所有节点进行授权
mysql> grant all privileges on *.* to 'mha'@'10.0.0.%' identified by 'Bxb123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql5.7会默认加载validate_password 模块,是来控制密码长度和规则的,可以在配置文件里面关闭该模块加上validate_password = off ,或者在mysql命令行执行set global validate_password_policy=0;来临时取消密码规则
禁用自动删除relay log功能
set global relay_log_purge=0;
查看master当前的binlog日志及位置信息
mysql> show master status;
slave操作(mysql02、03 10.0.0.134、135)
3.3.3 配置文件 /etc/my.cnf
指定serverid,并开启binlog日志
# 指定serverid,要比mysql-master大,slave1设置为2,slave2设置为3
server_id=2
# 开启binlog日志,位置在mysql数据目录data下
log_bin=binlog
# 开启binlog日志索引,位置在mysql数据目录data下
log_bin_index=binlog.index
# 开启半同步复制 否则自动切换主从的时候会报主键错误
log_slave_updates = 1
重启mysql
systemctl restart mysqld
3.3.4 设置slave从master拉取binlog,及拉取的位置
# 设置只读,不要在配置文件里写
mysql> set global read_only=1;
Query OK, 0 rows affected (0.00 sec)
# 禁用自动删除relay log
set global relay_log_purge=0;
# 拉取binlog
change master to master_host='10.0.0.133', \
master_port=3306, \
master_user='repl', \
master_password='Bxb123.com', \
master_log_file='binlog.000001', \
master_log_pos=155;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
启动slave并查看slave状态
# 启动slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
# 查看slave状态,SQL和IO线程都为Yes即为正确
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# 这个值是主从延迟,即slave落后master的秒数,也是一个比较重要的查看主从是否正常的标准值
Seconds_Behind_Master: 0