必须按off→off_permissive→on_permissive→on五步渐进切换,因直接set global gtid_mode = on会触发error 3098:实例中仍有未完成的匿名事务(ongoing_anonymous_transaction_count > 0),且enforce_gtid_consistency未置on、log_slave_updates未启用、binlog_format非row均会导致失败。

不能直接 SET GLOBAL gtid_mode = ON;必须按 OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON 顺序逐步切换,且每步都要在所有节点执行完再进下一步。
为什么 SET GLOBAL gtid_mode = ON 会报 ERROR 3098?
这是 MySQL 的强制保护:只要实例中还存在未清理的匿名事务(即 gtid_next = 'ANONYMOUS' 但尚未被复制或回放完成),SET GLOBAL gtid_mode = ON 就必然失败。错误信息通常是 ERROR 3098 (HY000): The value of gtid_mode cannot be changed。
根本原因不是权限或语法错,而是当前 @@global.ongoing_anonymous_transaction_count > 0 —— 表示还有正在执行、未提交、或已提交但尚未被从库拉取的匿名事务。
- 这个计数器不会自动清零,必须等所有匿名事务完成生命周期(主库提交 + 从库回放)
-
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';必须返回0才能推进到ON - 跳过检查直接设
ON,复制线程启动时会立刻中断,并报ERROR 1776或ERROR 3021
enforce_gtid_consistency = WARN 是唯一安全的探路步骤
线上业务不敢贸然设 ON,因为不兼容语句(如 CREATE TABLE ... SELECT、事务内混用 MyISAM、CREATE TEMPORARY TABLE)会直接报错中断业务。
WARN 模式是唯一能“试运行”的方式:它不阻断 SQL,只把违规行为记进错误日志,格式为 GTID consistency violated。
- 必须观察至少一个完整业务高峰周期(建议 48 小时以上),覆盖定时任务、批量导入、报表生成等场景
- 检查日志路径:
SELECT @@log_error;,然后 grep -i "consistency violated"error.log - 发现警告 ≠ 立即放弃,而是定位对应 SQL 并推动业务改写;没警告才可进入下一步
log_slave_updates = ON 是 GTID 复制的硬性前提
从库若没开 log_slave_updates,它重放的事务就不会写入自己的 binlog,导致其 gtid_executed 集合无法更新,主从 GTID 集合永远不对齐。
后果是:START SLAVE 直接失败,报 ERROR 3021 (HY000): This server is not configured to act as a replication source。
- 验证命令:
SHOW VARIABLES LIKE 'log_slave_updates';,值必须为ON - 该参数不支持动态修改,必须重启 mysqld 生效;升级 GTID 前就要配好,不能等最后一步才加
- 即使单层主从(无级联),也必须开;不是“可选”,是 GTID 协议级要求
开启后必须立刻切到 AUTO_POSITION
GTID 模式下,CHANGE REPLICATION SOURCE TO(MySQL 8.0.23+)或 CHANGE MASTER TO(5.7)不能再带 MASTER_LOG_FILE 和 MASTER_LOG_POS 参数。
否则 START SLAVE 会立即报 ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS ... cannot be set when MASTER_AUTO_POSITION is enabled。
- 正确操作是:先
STOP SLAVE;,再执行CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1; - 注意:该语句不校验当前位点是否对齐;如果主从 GTID 集合有 gap,
START SLAVE后会自动追平,但需确保网络和权限正常 - 配置文件里也要补上
gtid_mode = ON和enforce_gtid_consistency = ON,避免重启后退回到 OFF
最易被忽略的是 log_slave_updates 的重启依赖和 ONGOING_ANONYMOUS_TRANSACTION_COUNT 的真实含义——它不是“当前活跃事务数”,而是“尚未被所有从库确认回放完毕的匿名事务总数”,受网络延迟、从库负载、大事务回放时间影响极大,不能只看主库输出就认为可以推进。











