迁移核心风险是gtid一致性、网络延迟容忍度、事务冲突模式变更;需全局开启gtid且无断层,实测mgr端口延迟,super_read_only须由插件自动管理,应用层须支持幂等写入与冲突回滚处理。

直接上结论:迁移不是“换配置重启”就能完事的,核心风险在 GTID 一致性、网络延迟容忍度、事务冲突模式变更这三点。没踩过坑的人容易在上线后突然发现写入卡住、主库变只读、或者某条 UPDATE 被静默拒绝。
GTID 必须全局开启且不能有 gap
MySQL 8.0 的 MGR 强制依赖 gtid_mode=ON 和 enforce_gtid_consistency=ON,但单机旧实例常存在以下隐患:
- 曾手动执行过
SET SQL_LOG_BIN=0后的 DML/DDL,导致 binlog 中缺失 GTID event,形成 GTID set 断层 - 从其他集群导入过数据(如 mysqldump --set-gtid-purged=OFF),造成本地
gtid_purged与实际 binlog 不匹配 - 启用了
reset master但未同步清理从库或应用层记录的 GTID 位点
迁移前必须验证:SELECT @@global.gtid_executed; 和 SHOW MASTER STATUS; 输出的 GTID 集合是否完全一致;若有差异,需用 SET GLOBAL gtid_purged = '...'; 手动补全,否则节点加入 MGR 时会因认证失败被拒。
网络延迟和防火墙端口要实测,不能只看 ping
MGR 的组通信(XCom)对延迟极其敏感,ping 延迟 group_replication_local_address 指定的端口(如 33061)能否稳定互通:
- 必须用
telnet 192.168.x.x 33061或nc -zv 192.168.x.x 33061测试 TCP 连通性,UDP 不行 - 禁用所有中间防火墙的连接跟踪(conntrack),否则长连接易被误杀,表现为节点反复掉线又重连
- 跨机房部署时,
group_replication_consistency若设为BEFORE级别,延迟 >20ms 就会导致写入超时
生产环境建议把 MGR 通信端口和 MySQL 实例端口分物理网卡绑定,避免业务流量挤占组播带宽。
单主模式下 super_read_only 是自动管理的,别硬编码
很多人习惯在脚本里写 SET GLOBAL super_read_only=ON; 控制从库写入,但在 MGR 单主模式中,这个变量由插件动态维护:
- 主节点故障后,新选主节点会自动清除
super_read_only,原主恢复后会自动设为ON - 若手动设为
OFF,MGR 会拒绝该节点加入组,日志报错:Group Replication: Cannot start group replication when super_read_only is OFF -
read_only可以手动设,但super_read_only必须交给插件管
检查当前状态统一用:SELECT MEMBER_ROLE, MEMBER_STATE FROM performance_schema.replication_group_members;,而不是查 super_read_only 变量值。
应用层必须处理“写入失败但事务已部分提交”的边界情况
MGR 的乐观冲突检测机制意味着:事务在本地执行成功、进入认证阶段后,仍可能因与其他节点的写集冲突而被整体回滚。此时客户端收到的错误是 ERROR 3092 (HY000): The slave is not configured or failed to initialize 或更常见的 ERROR 1236 (HY000),但应用层可能已经发出了 COMMIT。
- 不能假设 “SQL 执行成功 + COMMIT 返回 OK” 就等于数据已持久化
- 关键业务必须实现幂等写入(如带唯一业务 ID 的 INSERT ON DUPLICATE KEY UPDATE)
- 避免在事务内混合 DDL 和 DML,DDL 会阻塞整个组的认证队列,放大延迟
最易被忽略的是:MGR 的事务原子性边界在“组”而非“单节点”,这点和主从复制有本质区别。迁移后不做应用适配,大概率在高并发场景下出现数据不一致。











