传统mysql主从复制需要手动切换故障节点,无法满足高可用场景下“秒级自动恢复”的需求。mysql group replication(mgr,组复制)基于paxos协议实现多节点数据同步与自动故障切换,无需依赖keepalived、mha等第三方工具,是mysql官方推荐的高可用解决方案。
一、mgr核心认知
1.1 mgr对比传统主从的优势
| 特性 | 传统主从复制 | mysql group replication |
|---|---|---|
| 故障切换 | 手动切换 | 自动选举新主节点,秒级恢复 |
| 数据一致性 | 异步/半同步,易不一致 | 强一致性(基于paxos协议) |
| 集群管理 | 依赖第三方工具 | 原生支持集群管理,无需额外组件 |
| 节点角色 | 主从固定 | 单主/多主模式,角色自动切换 |
| 脑裂风险 | 高 | 低(奇数节点仲裁) |
1.2 mgr核心原理
mgr集群由至少3个节点组成(奇数节点,保证投票仲裁),单主模式下:
- 集群选举出1个主节点(primary) 处理所有写入操作,其余为从节点(secondary) 只读;
- 主节点将事务同步到集群,所有节点通过组通信协议(xcom)达成共识后,才提交事务,保证数据一致性;
- 主节点故障时,集群自动检测并通过投票选举新主节点,从节点无缝接管写入,无需人工干预。
1.3 环境规划(单主模式)
| 节点角色 | 服务器ip | mysql版本 | 核心配置 | 端口说明 |
|---|---|---|---|---|
| mgr节点1(初始主) | 192.168.1.30 | 8.0.36 | 4核8g,500g硬盘 | 3306(mysql服务)、33061(mgr通信) |
| mgr节点2 | 192.168.1.31 | 8.0.36 | 4核8g,500g硬盘 | 3306、33061 |
| mgr节点3 | 192.168.1.32 | 8.0.36 | 4核8g,500g硬盘 | 3306、33061 |
1.4 前置准备
- 所有节点操作系统:centos 7.x(关闭selinux、防火墙开放3306/33061端口);
- 同步系统时间:
ntpdate ntp.aliyun.com; - 禁用apparmor/selinux:
setenforce 0 && sed -i 's/selinux=enforcing/selinux=disabled/' /etc/selinux/config; - 开放端口:
firewall-cmd --add-port=3306/tcp --permanent firewall-cmd --add-port=33061/tcp --permanent firewall-cmd --reload
二、第一步:所有节点安装并配置mysql 8.0
mgr对mysql版本要求严格(推荐8.0.20+),以下步骤需在所有3个节点执行。
2.1 安装mysql 8.0
# 1. 安装mysql yum源
wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
rpm -ivh mysql80-community-release-el7-7.noarch.rpm
# 2. 安装mysql服务器(忽略gpg检查,避免版本兼容问题)
yum install -y mysql-community-server --nogpgcheck
# 3. 启动mysql并设置开机自启
systemctl start mysqld
systemctl enable mysqld
# 4. 获取初始密码
initial_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $nf}')
echo "初始密码:$initial_pass"2.2 初始化mysql(修改密码、配置权限)
# 1. 登录mysql并修改root密码(需符合复杂度:大小写+数字+特殊字符) mysql -u root -p"$initial_pass" -e "alter user 'root'@'localhost' identified by 'mysql@123456'; flush privileges;" # 2. 远程访问授权(生产环境建议限制ip,此处为测试放开) mysql -u root -p"mysql@123456" -e "create user 'root'@'%' identified by 'mysql@123456'; grant all privileges on *.* to 'root'@'%' with grant option; flush privileges;"
2.3 配置mgr核心参数(修改my.cnf)
编辑/etc/my.cnf,替换原有配置为以下内容(注意替换server-id和group_replication_local_address为节点对应值):
节点1(192.168.1.30)my.cnf配置
[mysqld] # 基础配置 datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid lower_case_table_names=1 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci # mgr核心配置 server-id=30 # 每个节点唯一,建议用ip最后一段 gtid_mode=on # 开启gtid,mgr必需 enforce_gtid_consistency=on master_info_repository=table relay_log_info_repository=table binlog_checksum=none log_slave_updates=on binlog_format=row transaction_write_set_extraction=xxhash64 # mgr用于检测冲突的哈希算法 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 固定uuid,所有节点一致 loose-group_replication_start_on_boot=off # 不随mysql启动自动启动mgr loose-group_replication_local_address="192.168.1.30:33061" # 当前节点mgr通信地址 loose-group_replication_group_seeds="192.168.1.30:33061,192.168.1.31:33061,192.168.1.32:33061" # 所有节点通信地址 loose-group_replication_bootstrap_group=off # 仅初始化集群时设为on loose-group_replication_single_primary_mode=on # 单主模式(核心:自动故障切换依赖此模式) loose-group_replication_enforce_update_everywhere_checks=off # 单主模式设为off loose-group_replication_auto_increment_increment=7 # 避免主键冲突
节点2(192.168.1.31)my.cnf配置
仅修改以下2处,其余与节点1一致:
server-id=31 loose-group_replication_local_address="192.168.1.31:33061"
节点3(192.168.1.32)my.cnf配置
仅修改以下2处:
server-id=32 loose-group_replication_local_address="192.168.1.32:33061"
2.4 重启mysql并验证配置
# 重启mysql systemctl restart mysqld # 验证gtid是否开启(输出on即正常) mysql -u root -p"mysql@123456" -e "show variables like 'gtid_mode';"
三、第二步:搭建mgr集群(单主模式)
3.1 步骤1:在所有节点创建mgr专用用户
mgr需要专用用户用于节点间通信,登录每个节点执行:
mysql -u root -p"mysql@123456" << eof # 创建mgr通信用户 create user 'mgr_repl'@'%' identified by 'mgr@123456'; # 授予mgr所需权限 grant replication slave on *.* to 'mgr_repl'@'%'; grant group_replication_admin on *.* to 'mgr_repl'@'%'; flush privileges; # 配置mgr插件使用该用户 change master to master_user='mgr_repl', master_password='mgr@123456' for channel 'group_replication_recovery'; eof
3.2 步骤2:初始化mgr集群(仅节点1执行)
节点1作为初始主节点,负责引导集群创建:
mysql -u root -p"mysql@123456" << eof # 加载mgr插件(8.0+默认内置,无需手动安装) install plugin group_replication soname 'group_replication.so'; # 启动集群引导(仅第一次执行) set global group_replication_bootstrap_group=on; start group_replication; set global group_replication_bootstrap_group=off; # 验证集群状态(输出on即正常) select * from performance_schema.replication_group_members; eof
执行后查看replication_group_members,节点1状态应为online,角色为primary。
3.3 步骤3:节点2、3加入集群
节点2执行:
mysql -u root -p"mysql@123456" << eof # 加载mgr插件 install plugin group_replication soname 'group_replication.so'; # 加入集群 start group_replication; # 验证节点状态 select * from performance_schema.replication_group_members; eof
节点3执行:
与节点2命令完全一致,执行后验证节点状态。
3.4 验证集群搭建成功
在任意节点执行以下命令,查看集群成员状态:
mysql -u root -p"mysql@123456" -e "select member_host, member_role, member_state from performance_schema.replication_group_members;"
正常输出示例:
| member_host | member_role | member_state |
|---|---|---|
| 192.168.1.30 | primary | online |
| 192.168.1.31 | secondary | online |
| 192.168.1.32 | secondary | online |
3个节点均为online,且节点1为primary,说明集群搭建成功。 |
四、第三步:验证自动故障切换
4.1 前置测试:主节点写入数据
在节点1(主节点)插入测试数据,验证从节点同步:
# 节点1执行:创建测试库和表
mysql -u root -p"mysql@123456" << eof
create database if not exists mgr_test;
use mgr_test;
create table user (id int primary key auto_increment, name varchar(50));
insert into user (name) values ('mgr测试用户1'), ('mgr测试用户2');
eof
# 节点2/3执行:查询数据(应同步成功)
mysql -u root -p"mysql@123456" -e "select * from mgr_test.user;"4.2 模拟主节点故障(停止节点1的mysql)
# 节点1执行:停止mysql服务,模拟故障 systemctl stop mysqld
4.3 验证自动选举新主节点
等待5~10秒(mgr故障检测默认超时约5秒),在节点2执行以下命令:
mysql -u root -p"mysql@123456" -e "select member_host, member_role, member_state from performance_schema.replication_group_members;"
预期输出(节点2或3被选举为新主):
| member_host | member_role | member_state |
|---|---|---|
| 192.168.1.30 | unreachable | offline |
| 192.168.1.31 | primary | online |
| 192.168.1.32 | secondary | online |
4.4 验证新主节点写入功能
在新主节点(如节点2)插入数据,验证写入正常:
# 节点2执行:插入数据
mysql -u root -p"mysql@123456" << eof
use mgr_test;
insert into user (name) values ('故障切换后写入');
eof
# 节点3执行:查询数据(应同步新数据)
mysql -u root -p"mysql@123456" -e "select * from mgr_test.user;"4.5 故障节点恢复后重新加入集群
节点1修复后,重启mysql并重新加入集群:
# 节点1执行:重启mysql systemctl start mysqld # 重新加入集群 mysql -u root -p"mysql@123456" << eof start group_replication; # 验证状态(此时节点1为secondary) select member_host, member_role from performance_schema.replication_group_members; eof
五、mgr集群生产环境优化
5.1 配置自动重启mgr
编辑/etc/my.cnf,添加以下配置(所有节点),确保mysql重启后mgr自动启动:
loose-group_replication_start_on_boot=on
5.2 监控集群状态
5.2.1 核心监控sql
# 1. 集群成员状态 select member_host, member_role, member_state from performance_schema.replication_group_members; # 2. mgr运行状态 show status like 'group_replication%'; # 3. 事务冲突(生产环境需监控) select * from performance_schema.replication_group_conflicts;
5.2.2 结合prometheus+grafana监控
- 安装mysql exporter,配置监控指标;
- 导入mgr专用监控模板(grafana id:14050),重点监控:
- 节点在线状态、角色;
- 事务同步延迟;
- 集群冲突数;
- mgr通信端口连通性。
5.3 数据备份策略
mgr仅保证集群内数据一致,仍需定期备份:
- 开启binlog日志,设置过期时间:
binlog_expire_logs_seconds=604800(7天); - 每天在从节点执行全量备份:
mysqldump -u root -p"mysql@123456" --all-databases --single-transaction --master-data=2 > /backup/mysql_full_$(date +%y%m%d).sql
5.4 权限最小化(生产环境必做)
- mgr通信用户仅授予必要权限,取消远程全量授权:
revoke all privileges on *.* from 'mgr_repl'@'%'; grant replication slave, group_replication_admin on *.* to 'mgr_repl'@'192.168.1.%'; flush privileges;
- root用户限制ip访问:
create user 'root'@'192.168.1.%' identified by 'mysql@123456';。
六、常见问题与解决
6.1 节点加入集群失败(member_state=error)
- 原因:节点server-id重复、gtid不一致、防火墙未开放33061端口;
- 解决:
- 检查
server-id是否唯一; - 重置gtid:
reset master;; - 验证33061端口连通性:
telnet 192.168.1.30 33061。
- 检查
6.2 故障切换后新主节点无法写入
- 原因:单主模式未开启、
super_read_only未自动关闭; - 解决:
set global group_replication_single_primary_mode=on; set global super_read_only=off;
6.3 集群脑裂(节点状态不一致)
- 原因:网络分区、节点数量为偶数;
- 解决:
- 保证集群节点数为奇数(3/5/7);
- 配置
group_replication_member_expel_timeout=5(缩短节点驱逐超时)。
到此这篇关于mysql group replication(mgr)集群部署实现自动故障切换问题记录的文章就介绍到这了,更多相关mysql group replication自动故障切换内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论