必须先执行enforce_gtid_consistency=warn并观察日志无警告,再逐步设为on、off_permissive、on_permissive,待ongoing_anonymous_transaction_count=0且从库追平主库后,方可设gtid_mode=on,并立即配置master_auto_position=1及持久化gtid_mode=on等参数。

不能跳过 ENFORCE_GTID_CONSISTENCY = WARN 阶段直接设为 ON,否则复制会因不兼容语句中断——这是线上开启 GTID 最常踩的坑。
确认当前环境是否满足在线开启前提
MySQL 5.7 在线开启 GTID 要求严格,缺一不可:
- 所有节点(主+从)必须是
MySQL 5.7.6或更高版本,执行SELECT @@version;验证 - 所有节点
gtid_mode必须为OFF(不能是ON_PERMISSIVE等中间态) - 所有节点已启用
log_bin且binlog_format = ROW(STATEMENT模式下部分语句不兼容 GTID) - 业务侧已确认不使用 GTID 禁用语法,例如:
CREATE TABLE ... SELECT、事务内混用 InnoDB 和 MyISAM 表、事务中含CREATE TEMPORARY TABLE
必须分步执行的四次全局变量修改
gtid_mode 不支持跳跃设置,必须按顺序过渡。每一步都要在**所有节点上执行完毕**,再进入下一步:
- 先设
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;,观察错误日志至少 1–2 天高负载时段,确认无GTID consistency violated类警告 - 再设
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;(此时不兼容语句会直接报错,业务需配合改写) - 接着设
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;(主库不再生成 GTID,但从库仍能接收匿名和 GTID 事务) - 然后设
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;(主库开始生成 GTID,但从库仍兼容两种事务)
等待并验证匿名事务彻底清空
在 ON_PERMISSIVE 状态下,必须确保所有未复制的匿名事务已落地,否则 GTID_MODE = ON 会失败:
- 在每个节点执行
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';,结果必须为0 - 检查主库当前 binlog 位置:
SHOW MASTER STATUS; - 在每个从库执行
SELECT MASTER_POS_WAIT('mysql-bin.0000xx', 123456);(参数取自主库输出),返回非NULL表示已追平 - 只有全部从库都追平、且
ONGOING_ANONYMOUS_TRANSACTION_COUNT = 0后,才能执行最终一步:SET @@GLOBAL.GTID_MODE = ON;
切换从库复制模式并持久化配置
主库设为 ON 后,从库必须立刻切换到 GTID 自动定位,否则复制中断:
- 在每个从库执行:
STOP SLAVE; CHANGE MASTER TO MASTER_AUTO_POSITION = 1; START SLAVE;
- 立即更新配置文件(如
/etc/my.cnf),补全以下项(否则重启后退回到OFF):[mysqld] gtid_mode = ON enforce_gtid_consistency = ON log_slave_updates = ON
- 注意:
log_slave_updates必须开启,否则级联复制场景下中间从库无法生成 GTID
最易被忽略的是 log_slave_updates ——它不参与在线切换流程,但缺失会导致 GTID 复制在三层及以上拓扑中彻底失效,且问题往往延迟暴露。上线后务必用 SHOW SLAVE STATUS\G 检查 Retrieved_Gtid_Set 和 Executed_Gtid_Set 是否持续增长。











