不能直接 SET gtid_mode = ON,因为MySQL 5.7.6+强制要求必须按OFF_PERMISSIVE→ON_PERMISSIVE→ON三步渐进切换,跳步会触发ERROR 1788并中断复制;且每步需所有节点同步执行、确认ONGOING_ANONYMOUS_TRANSACTION_COUNT为0、并在my.cnf中持久化配置,否则重启失效或复制断裂。

不能直接 SET gtid_mode = ON,否则会触发 ERROR 1788 并中断复制。必须分阶段、逐节点、按顺序执行,漏一步或跳步都会失败。
为什么不能直接开 gtid_mode=ON
MySQL 5.7.6+ 强制要求 gtid_mode 只能按 OFF_PERMISSIVE → ON_PERMISSIVE → ON 三步走。跳步(比如从 OFF_PERMISSIVE 直接设为 ON)会立刻报错 ERROR 1788,且无法回退到中间状态。这是因为每阶段都隐含了事务兼容性检查和连接清理逻辑:
-
OFF_PERMISSIVE:新事务仍是匿名事务,但从库开始能识别并处理 GTID 事务 -
ON_PERMISSIVE:新事务开始用 GTID,从库仍兼容两种事务——但此时必须等ONGOING_ANONYMOUS_TRANSACTION_COUNT为 0,表示所有活跃连接已退出旧事务模式 -
ON:只接受 GTID 事务,传统CHANGE MASTER TO MASTER_LOG_FILE类命令立即失效
enforce_gtid_consistency 必须先 WARN 再 ON
直接 SET @@GLOBAL.enforce_gtid_consistency = ON 会让 MySQL 立即拒绝不兼容语句(如 CREATE TABLE ... SELECT、CREATE TEMPORARY TABLE),导致业务写入失败。正确做法是:
- 所有节点先执行
SET @@GLOBAL.enforce_gtid_consistency = WARN - 持续观察错误日志,搜索
Statement violates GTID consistency、ERROR 1786、ERROR 1787 - 确认无相关报错后,再统一执行
SET @@GLOBAL.enforce_gtid_consistency = ON
从库执行 CHANGE MASTER TO MASTER_AUTO_POSITION = 1 的时机很关键
这步必须在主从都完成 gtid_mode = ON 后单独执行,顺序错或漏掉会导致 IO 线程启动失败,SHOW SLAVE STATUS 中 Seconds_Behind_Master 一直为 NULL,Auto_Position 显示 0。
- 先在从库执行
STOP SLAVE - 再执行
CHANGE MASTER TO MASTER_AUTO_POSITION = 1(注意不是MASTER_AUTO_POSITION = ON) - 最后
START SLAVE,检查Retrieved_Gtid_Set和Executed_Gtid_Set是否非空且逐步收敛
配置文件不补全,重启就回退
所有 SET @@GLOBAL.xxx 命令只生效于当前会话,MySQL 重启后参数还原。若遗漏 my.cnf 配置,下次故障重启后主从直接断裂,且 SHOW SLAVE STATUS 里看不到明显异常,容易误判为网络或权限问题。
- 主从所有节点的
my.cnf都必须追加: gtid-mode = ONenforce-gtid-consistency = ON- 别忘了已有配置如
server-id、log-bin、relay-log也得保持一致
最常被忽略的是 ONGOING_ANONYMOUS_TRANSACTION_COUNT 检查和 my.cnf 补全——前者不为 0 就切 ON,后者不写死就重启失效,这两点一出错,整个切换过程就得重来。


















