GTID复制必须开启log_slave_updates,否则主从GTID集合无法对齐;gtid_mode不能热切换,需按enforce_gtid_consistency→OFF_PERMISSIVE→ON_PERMISSIVE→ON顺序安全升级。

MySQL 5.7+ 开启 GTID 前必须关闭 log_slave_updates?
不是必须关闭,而是必须开启。GTID 复制要求从库重放的每个事务都生成自己的 GTID,并写入自己的 binlog,否则主从 GTID 集合无法对齐,START SLAVE 会直接报错:ERROR 1777 (HY000): Change replication source to executed on a server with replication filters 或更常见的 ERROR 3021 (HY000): This server is not configured to act as a replication source。
实操建议:
-
log_slave_updates = ON是 GTID 复制的硬性前提,无论是否级联复制都要开 - 若之前是传统 binlog file/pos 复制,升级 GTID 前需先重启从库启用该参数(无需重启主库)
- 检查方式:
SHOW VARIABLES LIKE 'log_slave_updates';返回ON
配置 gtid_mode=ON 时为什么总卡在 ERROR 3098 (HY000)?
这是 MySQL 的安全保护机制:GTID 模式不能热切换。当你执行 SET GLOBAL gtid_mode = ON; 时,若实例中还存在未清理的匿名事务(即 gtid_next = AUTOMATIC 但未分配 GTID 的旧事务),就会触发该错误。
正确步骤(顺序不可颠倒):
- 先执行
SET GLOBAL enforce_gtid_consistency = WARN;,观察慢查询日志或错误日志是否有不兼容语句(如CREATE TABLE ... SELECT、临时表混用、非事务引擎写入等) - 再设为
ENFORCING:SET GLOBAL enforce_gtid_consistency = ON; - 最后分三步升 GTID 级别:
SET GLOBAL gtid_mode = OFF_PERMISSIVE;→SET GLOBAL gtid_mode = ON_PERMISSIVE;→ 等待SELECT @@global.gtid_owned为空后,执行SET GLOBAL gtid_mode = ON;
如何安全地把老主从切换成 GTID 模式(不丢数据、不断服务)?
核心原则:不改主库 binlog 格式,只改从库配置 + 主从切换时用 CHANGE REPLICATION SOURCE TO ... GET_MASTER_PUBLIC_KEY=1(MySQL 8.0.4+)或手动注入 GTID set。
关键操作点:
- 从库先停复制:
STOP REPLICA;(MySQL 8.0.22+)或STOP SLAVE; - 确认从库已追平:
SHOW REPLICA STATUS\G中Retrieved_Gtid_Set == Executed_Gtid_Set - 修改从库配置文件,加入:
gtid_mode=ON、enforce_gtid_consistency=ON、log_slave_updates=ON,然后重启 - 重新拉主库:
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1;(不是MASTER_AUTO_POSITION = 1,MySQL 8.0 已弃用后者)
事务跟踪(Transaction Tracking)和 GTID 是一回事吗?
不是。GTID 是全局事务标识符,用于复制一致性;而事务跟踪(transaction_tracking)是 MySQL 8.0.27+ 引入的调试功能,通过 performance_schema.events_transactions_current 暴露事务生命周期,与复制无关。
如果你真想跟踪事务来源(比如定位某条 UPDATE 是哪个客户端发起的),需要:
- 开启
performance_schema(默认已开) - 确保
events_transactions_current消费器已启用:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_transactions_current'; - 关联
threads表查PROCESSLIST_ID,再结合应用层的 trace_id 注入(MySQL 本身不提供分布式 trace 支持)
别指望靠 GTID 反查 SQL 来源——GTID 只保证“这个事务在所有节点有唯一身份”,不记录谁发的、从哪来、带什么上下文。


















