必须先执行 RESET MASTER 清空 binlog,才能设置 gtid_purged;否则因 binlog 非空、状态不满足前提而报“Can't modify gtid_purged”错误。

旧主库重做为从库时,不跳过新主库已执行的 GTID 事务,必然导致复制中断或主键冲突——GTID 不是自动“对齐”的开关,而是必须显式清理冲突历史的标记。
为什么 SET GLOBAL gtid_purged 会报错 Can't modify gtid_purged
这个错误只在旧主库没执行 RESET MASTER 之前出现。MySQL 要求 gtid_purged 只能在 binlog 完全清空后设置,否则它认为你试图伪造 GTID 历史。不是权限问题,也不是配置遗漏,就是状态不满足前提。
- 先确认旧主库当前 binlog 状态:
SHOW BINARY LOGS;,如果列表非空,说明不能直接设gtid_purged - 执行
RESET MASTER;(注意:这会清空所有本地 binlog 文件,仅限旧主库已停写且无其他依赖时使用) - 再设
SET GLOBAL gtid_purged = 'xxx-xxx-xxx:1-12345';,值必须来自新主库切换时刻的@@global.gtid_executed快照 - 如果旧主库还残留 relay log,记得先
STOP SLAVE;再RESET SLAVE ALL;
如何精准定位“切换时刻”的 GTID 范围
不能靠运维记录猜,也不能用当前 gtid_executed 直接填——因为新主库在切换后可能又写入了新事务。你需要的是“旧主库最后一次写入”和“新主库第一次接管写入”之间的分界点。
- 查新主库当前完整 GTID 集:
SELECT @@global.gtid_executed; - 结合 binlog 解析,定位最后一条由旧主库发起的事务(比如带
server_id=101的 event):mysqlbinlog --base64-output=DECODE-ROWS -v /var/lib/mysql/binlog.000001 | grep -A 5 -B 5 'server_id=101' - 提取该事务的 GTID,例如
aaa-bbb-ccc:12340,然后取其前一个号:aaa-bbb-ccc:1-12339,作为gtid_purged的起点 - 若新主库启用了
log_slave_updates,它的gtid_executed包含了旧主库原生事务 + 自身新事务,必须人工剥离
跳过事务后仍报 Duplicate entry 怎么办
说明有事务没被 GTID 跳过机制覆盖,常见于 DDL 后的 DML 或非 GTID 模式遗留操作。GTID 只跳过事务级事件,不跳过语句级冲突。
- 检查报错时的
SHOW SLAVE STATUS\G中Exec_master_log_pos和Relay_log_file,定位具体哪条 SQL 卡住 - 用
mysqlbinlog --start-position=xxx --stop-position=yyy解析对应 binlog 片段,确认是否是 INSERT 或 REPLACE 导致主键重复 - 临时跳过单条事务:
SET GLOBAL sql_slave_skip_counter = 1;(仅限非 GTID 模式;GTID 模式下必须用gtid_executed手动注入空事务) - 更稳妥的做法:在旧主库上手动
DELETE冲突行,再START SLAVE;,避免后续同步链路持续错位
log_slave_updates 参数漏开导致反向同步失效
双主或反向同步场景下,旧主库重做为从库后,若要让它把新主库的数据再同步给其他节点(比如 A 主 ← B 主 ← B 备),log_slave_updates 是硬性要求。它默认关闭,且修改后必须重启 MySQL 才生效。
- 检查是否开启:
SELECT @@global.log_slave_updates;,返回 0 就没开 - 配置文件中加
log_slave_updates = ON,然后systemctl restart mysqld - 重启后立刻验证:
SHOW BINARY LOGS;是否有新生成的 binlog,再SHOW MASTER STATUS;看File是否在滚动 - 漏开此参数的典型现象:A 主能连上 B 主并显示
Slave_IO_Running: Yes,但 A 主自己的 binlog 空空如也,下游节点无法从 A 主拉取数据
GTID 强一致性不是开个开关就完事,它把“对齐逻辑”从位置偏移量转移到了事务标识上,但也把校准责任完全交给了人——少查一次 gtid_executed、少解析一段 binlog、少确认一个 server_id,都可能让旧主库在启动复制后几分钟内就卡死在某条 INSERT 上。


















