mysql 5.7+不能直接set global gtid_mode = on,因强制要求分三步渐进切换:off_permissive→on_permissive→on;跳步会触发error 1788,且需确保enforce_gtid_consistency=on、无匿名事务残留、binlog_format=row等前提。

不能直接改,必须按三阶段渐进切换,跳步或漏步骤会触发 ERROR 1788 并中断复制。
为什么不能 SET GLOBAL gtid_mode = ON 一步到位
MySQL 5.7.6+ 强制要求 gtid_mode 必须按 OFF_PERMISSIVE → ON_PERMISSIVE → ON 顺序切换。跳过中间状态(比如从 OFF_PERMISSIVE 直接设为 ON)会立刻报错:ERROR 1788: The value of @@GLOBAL.GTID_MODE cannot be changed,且 IO 线程无法启动。
根本原因是:GTID 模式要求所有事务都带唯一标识,而旧连接可能还在执行匿名事务(anonymous transaction),强行切 ON 会让从库拒绝接收这些事务。
-
OFF_PERMISSIVE:新事务仍为匿名,但从库可同时处理匿名和 GTID 事务 -
ON_PERMISSIVE:新事务开始用 GTID,从库仍兼容两种事务 —— 此时必须等ONGOING_ANONYMOUS_TRANSACTION_COUNT为 0 -
ON:只允许 GTID 事务,从库也只认 GTID 事务,传统MASTER_LOG_FILE/MASTER_LOG_POS命令失效
enforce_gtid_consistency 必须先 WARN 再 ON
直接 SET @@GLOBAL.enforce_gtid_consistency = ON 会导致业务写入失败,因为会立刻拒绝不兼容语句(如 CREATE TABLE ... SELECT、事务内 CREATE TEMPORARY TABLE),报错 ERROR 1786 或 ERROR 1787。
正确做法是分两轮观察:
- 所有节点先执行
SET @@GLOBAL.enforce_gtid_consistency = WARN - 持续检查错误日志,搜索
Statement violates GTID consistency,确认无相关警告至少 24 小时(生产环境建议 3–7 天) - 全部节点统一执行
SET @@GLOBAL.enforce_gtid_consistency = ON
这步漏掉或跳过,后续切换到 ON_PERMISSIVE 阶段时,ONGOING_ANONYMOUS_TRANSACTION_COUNT 可能永远不归零 —— 因为有活跃连接在跑违规语句。
从库执行 CHANGE MASTER TO 的时机和写法
主从都完成 gtid_mode = ON 后,才轮到从库操作。顺序错、命令错、漏 STOP SLAVE,都会导致 IO 线程卡在 Connecting 或报 ERROR 3021。
- 必须先
STOP SLAVE - 必须用
CHANGE MASTER TO MASTER_AUTO_POSITION = 1(不是MASTER_LOG_FILE + MASTER_LOG_POS) - 必须确保
MASTER_USER和MASTER_PASSWORD正确,且主库用户有REPLICATION SLAVE权限 - 执行后
START SLAVE,再查SHOW SLAVE STATUS\G
验证关键字段:Auto_Position: 1、Retrieved_Gtid_Set 和 Executed_Gtid_Set 非空且逐步增长;Slave_IO_Running 和 Slave_SQL_Running 均为 Yes。
配置文件不补全,重启就断裂
所有 SET @@GLOBAL.xxx 命令只生效于当前会话。MySQL 重启后参数还原,从库会退回到传统复制模式,但 SHOW SLAVE STATUS 里 Auto_Position 仍显示 1,Retrieved_Gtid_Set 清空,Executed_Gtid_Set 停滞 —— 表象像网络问题,实则是配置丢失。
务必在每台节点的 my.cnf 中追加:
[mysqld] gtid_mode = ON enforce_gtid_consistency = ON log_slave_updates = ON binlog_format = ROW
注意:server_id 必须全局唯一;log_bin 主库必须开,从库建议也开(级联复制必需);log_slave_updates 在从库上开启才能参与多层复制。
最容易被忽略的是:切换完成后,应用端不能再执行任何不支持 GTID 的语句(比如跨引擎混合事务、非事务表 DML),否则整个复制链路会中断且难以定位。











