MySQL不能一步设gtid_mode=ON,因会触发ERROR 1789硬性拦截;必须先设enforce_gtid_consistency=ON、log_slave_updates=ON,再经OFF_PERMISSIVE→ON_PERMISSIVE→ON三阶段切换,并校验无匿名事务后方可完成。

不能直接设 gtid_mode=ON,否则 MySQL 启动失败或主从断裂——必须分步、校验、配全参数,缺一不可。
为什么不能一步到位设 gtid_mode=ON
MySQL 会拒绝启动,报错类似 ERROR 1789 (HY000): The value of gtid_mode cannot be changed from OFF to ON without also setting enforce_gtid_consistency=ON and log_slave_updates=ON。这不是警告,是硬性拦截。根本原因是 GTID 要求事务可追溯、可重放,而匿名事务(如旧 binlog 里的语句)与 GTID 冲突,必须先“清场”再切换。
gtid_mode 必须分三阶段动态切换
所有操作需在主从节点**同时执行**,顺序不能乱:
- 先设
SET GLOBAL enforce_gtid_consistency = WARN;,观察错误日志 24 小时,确认无Statement violates GTID consistency类警告(比如CREATE TABLE ... SELECT、临时表、非事务引擎混用) - 再设
SET GLOBAL enforce_gtid_consistency = ON;(此时不兼容语句会直接报错,应用需适配) - 然后按序升级
gtid_mode:
→SET GLOBAL gtid_mode = OFF_PERMISSIVE;
→SET GLOBAL gtid_mode = ON_PERMISSIVE;
→ 最后查SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';,返回值必须为0,才能执行SET GLOBAL gtid_mode = ON;
配置文件里必须同时写对这四个参数
仅靠动态 SET 不持久,重启后失效。my.cnf 中必须包含且值严格匹配:
-
gtid_mode=ON(最终态,不是中间态) -
enforce_gtid_consistency=ON(必须在gtid_mode=ON前就存在) -
log_slave_updates=ON(主从链路中**所有节点**都要开,中间从库漏掉会导致 GTID 断链) -
binlog_format=ROW(MIXED或STATEMENT会触发ER_GTID_MODE_ON_WITH_STATEMENT_BINLOG_FORMAT错误)
顺序无关,但少任何一个都会让 MySQL 拒绝启动或复制中断。
主从初始化时千万别用 mysqldump --master-data
GTID 模式下 --master-data 记录的 file+position 完全无效,从库启动必报错:Could not execute Write_rows event on table ... impossible to write to binary log since BINLOG_FORMAT = STATEMENT。
- 正确做法:用
mysqldump --set-gtid-purged=ON(MySQL 5.6.9+),它会在 dump 开头插入SET @@GLOBAL.GTID_PURGED='...'; - 物理备份:Percona XtraBackup 必须加
--gtid参数,否则恢复后GTID_PURGED为空,从库无法 auto-position - 从库 CHANGE MASTER 语句必须带
MASTER_AUTO_POSITION=1,不能写MASTER_LOG_FILE和MASTER_LOG_POS
最容易被忽略的是中间从库的 log_slave_updates 和备份时的 --set-gtid-purged —— 这两个点出问题,整个 GTID 链就断了,而且错误现象往往延迟暴露。


















