一、mysql高可用之组复制(mgr)
1.1 组复制核心特性与优势
mysql group replication(mgr)是基于分布式一致性协议(paxos)实现的高可用集群方案,核心特性包括:
- 自动故障检测与恢复:集群自动检测故障节点,并通过选举机制产生新主节点(单主模式)。
- 数据一致性保障:读写事务需经过集群多数节点(>n/2)确认后才能提交,避免数据分裂。
- 弹性扩展:支持动态添加 / 移除节点,无需中断集群服务。
- 两种运行模式:单主模式(仅 1 个可写节点)和多主模式(所有节点可写)。
1.2 组复制架构原理
组复制依赖以下核心组件:
- 组通信系统(gcs):负责节点间消息传递(如事务日志、心跳检测),基于 tcp 协议实现。
- 一致性协议层:采用 paxos 算法确保事务在集群中的顺序一致性。
- 事务验证层:检测并发事务冲突(多主模式下),避免数据不一致。
工作流程简述:
(1)主节点(单主模式)或任意节点(多主模式)接收写事务。
(2)事务执行前生成预写日志(wal),并广播至集群所有节点。
(3)所有节点验证事务合法性(如无冲突),并通过一致性协议达成提交顺序共识。
(4)多数节点确认后,事务在所有节点提交,确保全局一致。
1.3 单主模式组复制实现(实战步骤)
环境准备
| ip地址 | server-id | |
| 候选主节点 | 192.168.168.200 | 200 |
| 从节点1 | 192.168.168.129 | 129 |
| 从节点2 | 192.168.168.130 | 130 |
步骤1:所有节点基础配置(my.cnf)
[mysqld] # 基础配置 server-id=200 # 每个节点唯一(200/129/130) datadir=/data/mysql socket=/data/mysql/mysql.sock pid-file=/data/mysql/mysql.pid # 二进制日志与gtid(mgr依赖gtid) log_bin=/data/mysql/binlog binlog_format=row # 必须为row格式 log_slave_updates=on # 从库同步的事务写入自身binlog gtid_mode=on # 启用gtid enforce_gtid_consistency=on # 强制gtid一致性 # 组复制相关配置 transaction_write_set_extraction=xxhash64 # 事务写入集提取算法 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 集群uuid(自定义) loose-group_replication_start_on_boot=off # 不自动启动组复制 loose-group_replication_local_address="192.168.168.200:33061" # 本节点组通信端口(每个节点修改ip) loose-group_replication_group_seeds="192.168.168.200:33061,192.168.168.129:33061,192.168.168.130:33061" # 集群种子节点 loose-group_replication_bootstrap_group=off # 仅初始化集群时设为on loose-group_replication_single_primary_mode=on # 启用单主模式
重启所有节点使配置生效:
systemctl restart mysqld
步骤2:创建组复制专用账户(所有节点执行)
登录mysql,创建用于节点间通信的账户:
-- 创建复制用户(允许所有集群节点访问) create user 'grp_user'@'192.168.168.%' identified by 'grp@123'; -- 授予复制权限 grant replication slave on *.* to 'grp_user'@'192.168.168.%'; -- 刷新权限 flush privileges;
步骤3:配置复制通道(所有节点执行)
设置基于gtid的复制通道,用于组内事务同步:
-- 停止现有复制(若有) stop replica; -- 配置组复制通道 change replication source to source_user='grp_user', source_password='grp@123', source_auto_position=1 for channel 'group_replication_recovery';
步骤4:安装组复制插件(所有节点执行)
-- 安装组复制插件 install plugin group_replication soname 'group_replication.so'; -- 验证插件是否安装成功 show plugins like 'group_replication';
输出示例(状态为active表示成功):
+-------------------+----------+--------------------+----------------------+---------+ | name | status | type | library | license | +-------------------+----------+--------------------+----------------------+---------+ | group_replication | active | group replication | group_replication.so | gpl | +-------------------+----------+--------------------+----------------------+---------+
步骤5:初始化集群(仅在第一个节点执行)
在 192.168.168.200(候选主节点)上引导集群:
-- 启动集群初始化(仅第一次执行) set global group_replication_bootstrap_group=on; -- 启动组复制 start group_replication; -- 关闭初始化开关(避免重复初始化) set global group_replication_bootstrap_group=off;
步骤6:添加其他节点到集群(129和130节点执行)
-- 启动组复制,自动加入集群 start group_replication;
步骤7:验证集群状态
-- 启动组复制,自动加入集群 start group_replication;
select * from performance_schema.replication_group_members;
输出示例(单主模式下member_role为 primary 的是主节点):
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | channel_name | member_id | member_host | member_port | member_state | member_role | member_version | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 200e5b9a-732b-11f0-971f-000c29d6adc7 | 192.168.168.200 | 3306 | online | primary | 8.0.40 | | group_replication_applier | 129e5b9a-732b-11f0-971f-000c29d6adc7 | 192.168.168.129 | 3306 | online | secondary | 8.0.40 | | group_replication_applier | 130e5b9a-732b-11f0-971f-000c29d6adc7 | 192.168.168.130 | 3306 | online | secondary | 8.0.40 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
1.4 单主模式故障转移测试
1.模拟主节点故障:在主节点(200)执行停机命令:
systemctl stop mysqld
2.查看集群状态:在从节点(129)执行:
select * from performance_schema.replication_group_members;
输出中会显示原主节点状态为unreachable,约 30 秒后集群自动选举新主(如 129 节点变为 primary)。
3.恢复原主节点:重启 200 节点后,自动以从节点身份加入集群:
systemctl start mysqld
登录 200 节点的 mysql,启动组复制:
start group_replication;
再次查看集群状态,200 节点角色变为 secondary。
1.5 多主模式组复制配置(扩展)
多主模式允许所有节点同时处理写事务,适合高并发写入场景,配置差异如下:
1.修改所有节点的my.cnf:
loose-group_replication_single_primary_mode=off # 关闭单主模式(启用多主) loose-group_replication_enforce_update_everywhere_checks=on # 强制多主更新检查
2.重启节点并重新初始化集群(参考单主模式步骤5-6):
-- 在第一个节点执行 set global group_replication_bootstrap_group=on; start group_replication; set global group_replication_bootstrap_group=off; -- 其他节点执行 start group_replication;
3.验证多主模式:所有节点的member_role均为 primary:
select member_host, member_role from performance_schema.replication_group_members;
1.6 组复制监控与维护
1.查看集群健康状态:
-- 集群成员状态 select * from performance_schema.replication_group_members; -- 事务冲突统计(多主模式) select * from performance_schema.replication_group_member_stats;
2.动态添加节点:
-- 在新节点执行(参考步骤2-4配置后) start group_replication;
3.移除节点:
-- 在待移除节点执行 stop group_replication;
4.集群重启(全部节点故障后):
-- 在任意一个节点重新引导集群 set global group_replication_bootstrap_group=on; start group_replication; set global group_replication_bootstrap_group=off; -- 其他节点直接启动 start group_replication;
总结
mysql 组复制(mgr)通过分布式一致性协议实现了自动故障转移和数据一致性,单主模式适合读多写少场景,多主模式适合高并发写入。实际部署时需注意:
节点数至少 3 个,确保多数派机制生效;
网络延迟需控制在 100ms 以内,避免影响事务提交效率;
定期监控集群状态,及时处理故障节点。
结合业务场景选择合适的高可用架构,可有效提升 mysql 集群的稳定性和可靠性。
二、mysql高可用之mha(master high availability)
2.1 mha核心特性与优势
mha 是针对 mysql 主从复制架构的高可用解决方案,通过自动监控主库状态、实现故障检测与自动切换,核心特性包括:
- 自动故障转移:主库宕机后 10-30 秒内完成新主库选举与切换。
- 数据一致性保障:通过 binlog 补传机制减少数据丢失风险。
- 零数据丢失:配合半同步复制可实现接近零数据丢失。
- 低侵入性:无需修改 mysql 现有配置,兼容各种主从架构。
- 在线切换:支持手动触发主从切换(如主库升级维护)。
2.2 mha架构原理
mha 由两部分组成:
- mha manager:管理节点,负责监控集群状态、触发故障转移。
- mha node:部署在所有 mysql 节点,提供 binlog 复制、故障检测等功能。
故障转移流程:
1.监控阶段:manager 通过 ssh 定期(默认 3 秒)向主库发送 ping 包检测存活状态。
2.故障确认:连续 3 次 ping 失败后,manager 通过其他从库确认主库是否真的宕机。
3.选举新主:根据从库的日志同步进度(优先选择最接近主库的从库)选举新主。
4.故障转移:隔离旧主库(如关闭 vip、防火墙阻断);提升新主库(执行reset slave all);其他从库指向新主库(通过 relay log 补全差异);应用层切换至新主库(如更新 vip 指向);
2.3 mha实战部署(单主多从架构)
环境准备
| ip地址 | 主机名 | |
| mha manager | 192.168.168.201 | mha-manager |
| mysql 主库 | 192.168.168.200 | master |
| mysql 从库 1 | 192.168.168.129 | slave1 |
| mysql 从库 2 | 192.168.168.130 | slave2 |
步骤1:配置ssh免密登录(关键)
mha manager 需要免密登录所有 mysql 节点,mysql 节点间也需要免密互通:
# 在mha manager节点生成密钥
[root@mha-manager ~]# ssh-keygen -t rsa -n '' -f ~/.ssh/id_rsa
# 分发密钥到所有节点(包括自身)
[root@mha-manager ~]# for host in 192.168.168.200 192.168.168.129 192.168.168.130 192.168.168.201; do
ssh-copy-id -i ~/.ssh/id_rsa.pub root@$host
done
# 验证免密登录
[root@mha-manager ~]# ssh 192.168.168.200 date步骤2:安装mha软件
所有节点安装mha node
# 安装依赖 [root@master ~]# yum install -y perl-dbd-mysql perl-config-tiny perl-log-dispatch perl-parallel-forkmanager # 下载并安装node包 [root@master ~]# wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.noarch.rpm [root@master ~]# rpm -ivh mha4mysql-node-0.58-0.el7.noarch.rpm
mha manager节点额外安装manager包
[root@mha-manager ~]# wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.noarch.rpm [root@mha-manager ~]# rpm -ivh mha4mysql-manager-0.58-0.el7.noarch.rpm
步骤3:配置mysql权限
在主库创建 mha 专用管理用户(从库会同步该用户):
-- 创建管理用户(用于监控和故障转移) create user 'mha_admin'@'192.168.168.%' identified by 'mha@123'; grant all privileges on *.* to 'mha_admin'@'192.168.168.%' with grant option; -- 确保主从复制用户已存在(参考1.2章节的rep用户) flush privileges;
步骤4:配置mha manager
创建配置目录
[root@mha-manager ~]# mkdir -p /etc/mha/mysql_cluster [root@mha-manager ~]# mkdir -p /var/log/mha/mysql_cluster
编写集群配置文件
# /etc/mha/mysql_cluster/mha.cnf [server default] # 管理用户 user=mha_admin password=mha@123 # 复制用户(主从同步用) repl_user=rep repl_password=rep123 # 工作目录 manager_workdir=/var/log/mha/mysql_cluster # 日志文件 manager_log=/var/log/mha/mysql_cluster/manager.log # ssh连接端口 ssh_port=22 # mysql端口 mysql_port=3306 # 检测间隔(秒) ping_interval=3 # 二次检查的从库数量 secondary_check_script=masterha_secondary_check -s 192.168.168.129 -s 192.168.168.130 # 故障转移后执行的脚本(如更新vip) master_ip_failover_script=/etc/mha/mysql_cluster/master_ip_failover [server1] hostname=192.168.168.200 port=3306 # 主库故障后禁止自动启动 no_master=1 [server2] hostname=192.168.168.129 port=3306 # 候选主库权重 candidate_master=1 [server3] hostname=192.168.168.130 port=3306 candidate_master=1
步骤5:编写vip切换脚本
创建master_ip_failover脚本实现虚拟 ip(vip)自动漂移:
#!/usr/bin/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
);
# vip配置
my $vip = '192.168.168.250/24';
my $key = '0';
my $dev = 'ens33';
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,
);
exit &main();
sub main {
print "\n\nin script test====$command======\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "disabling 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 vip on 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 \"ip addr add $vip dev $dev\"`;
`ssh $ssh_user\@$new_master_host \"arping -i $dev -c 3 -s $vip 192.168.168.1 > /dev/null 2>&1\"`;
}
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \"ip addr del $vip dev $dev\"`;
}
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";
}赋予执行权限:
[root@mha-manager ~]# chmod +x /etc/mha/mysql_cluster/master_ip_failover
步骤6:验证mha环境
检查ssh连通性
[root@mha-manager ~]# masterha_check_ssh --conf=/etc/mha/mysql_cluster/mha.cnf
输出all ssh connection tests passed successfully.表示成功。
检查主从复制状态
[root@mha-manager ~]# masterha_check_repl --conf=/etc/mha/mysql_cluster/mha.cnf
输出mysql replication health is ok.表示成功。
步骤7:启动mha manager
# 后台启动 [root@mha-manager ~]# nohup masterha_manager --conf=/etc/mha/mysql_cluster/mha.cnf > /var/log/mha/mysql_cluster/manager.log 2>&1 & # 查看状态 [root@mha-manager ~]# masterha_check_status --conf=/etc/mha/mysql_cluster/mha.cnf mysql_cluster (pid: 1234) is running(0:ping_ok), master:192.168.168.200
2.4 故障转移测试
1.模拟主库故障:在主库(200)执行关机命令
[root@master ~]# systemctl stop mysqld
2.观察mha日志:
[root@mha-manager ~]# tail -f /var/log/mha/mysql_cluster/manager.log
日志会显示:检测到主库故障 → 选举新主(如 129)→ 转移 vip → 完成切换。
3.验证结果:
查看vip是否漂移到新主库:
[root@slave1 ~]# ip addr show ens33 | grep 192.168.168.250
检查从库是否指向新主:
mysql> show replica status\g
2.5 mha日常维护
1.手动切换主库(如主库升级):
[root@mha-manager ~]# masterha_master_switch --conf=/etc/mha/mysql_cluster/mha.cnf \ --master_state=alive \ --new_master_host=192.168.168.129 \ --new_master_port=3306 \ --orig_master_is_new_slave
2.重启mha manager:
[root@mha-manager ~]# masterha_stop --conf=/etc/mha/mysql_cluster/mha.cnf [root@mha-manager ~]# nohup masterha_manager --conf=/etc/mha/mysql_cluster/mha.cnf &
3.添加新从库:配置新从库与主库同步;修改 mha.cnf 添加新节点配置;重新检查并启动 mha;
总结:
mha 通过简洁的架构实现了 mysql 主从集群的高可用,适合对成本敏感且已有主从架构的场景。部署时需注意:
严格配置 ssh 免密登录(核心前提);
- 配合半同步复制减少数据丢失;
- 编写可靠的 vip 切换脚本(关键环节);
- 定期测试故障转移流程确保可用性;
根据业务规模和一致性要求,可选择 mha(低成本)、mgr(强一致)或 percona xtradb cluster(高并发)作为高可用解决方案。
到此这篇关于mysql集群高可用架构的两种使用小结的文章就介绍到这了,更多相关mysql集群高可用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论