主从切换导致gtid不连续需重置gtid上下文:先stop slave、reset slave all清空状态,确认gtid_executed为空后,用新主库的gtid_executed值set global gtid_purged,再change master to master_auto_position=1并start slave。

主从切换后 GTID 不连续,不是“断了”,而是从库的 gtid_executed 里混入了旧主库或其它源的 GTID,而新主库的 gtid_purged 已经清掉那段历史——此时 START SLAVE 必然报错 ERROR 1236,跳过单个事务没用,必须重对齐 GTID 上下文。
为什么主从切换会导致 GTID 不连续
GTID 复制依赖两个关键集合严格匹配:Retrieved_Gtid_Set(已拉取但未执行)和 Executed_Gtid_Set(已执行),而主从切换时常见三类破坏点:
- 旧主库被降级为从库后,
gtid_executed仍保留全部历史,但新主库的gtid_purged可能已清除早期 binlog(比如执行过PURGE BINARY LOGS) - 从库曾连接过测试主库、临时备份源,执行过不相关的事务,这些 GTID 被记入
gtid_executed,但新主库根本没有对应 binlog - 备份恢复时用了
--set-gtid-purged=ON,但恢复目标是已有数据的实例,导致gtid_purged被硬塞进一个不兼容的值
结果就是:从库说“我要执行 uuid:1-100”,新主库查了下 gtid_purged,发现“uuid:1-50 已删”,直接拒绝同步。
如何安全重置从库 GTID 状态并重连
不能只 RESET MASTER 或只改 gtid_purged——前者清空所有 binlog,后者填错会启动失败。正确顺序是“清执行历史 → 设 purge 基线 → 重绑主库”:
- 在从库执行:
STOP SLAVE; RESET SLAVE ALL;(注意是ALL,否则 relay log 和复制元数据残留) - 确认
gtid_executed已为空:SELECT @@global.gtid_executed;应返回空字符串 - 在新主库上查当前完整 GTID 集:
SELECT @@global.gtid_executed;,例如得到ab1b2733-2401-11e7-82fc-525400abbf4b:1-500 - 在从库执行:
SET GLOBAL gtid_purged = 'ab1b2733-2401-11e7-82fc-525400abbf4b:1-500';(值必须完全一致,不能多空格、不能缩写) - 再执行:
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_AUTO_POSITION = 1; -
START SLAVE;后检查SHOW SLAVE STATUS\G中Seconds_Behind_Master是否下降、Slave_SQL_Running是否为Yes
执行 SET GLOBAL gtid_purged 的硬性前提
这个赋值操作看似简单,但 MySQL 会做三道校验,任一失败就报 ERROR 1840:
-
@@global.gtid_executed必须为空——所以必须先RESET SLAVE ALL,不能只STOP SLAVE - 赋的值必须是新主库
gtid_executed的**前缀子集**,比如主库是uuid:1-100,你只能设uuid:1-50,不能设uuid:1-100,abc:1(引入新 uuid) - 不能包含任何从库本地执行过的 GTID(比如之前手动注入的空事务),否则后续
START SLAVE会立刻卡住
最易忽略的一点:如果从库启用了 log_slave_updates,它自己的 binlog 里可能已记录过旧 GTID,这时 RESET SLAVE ALL 不会清 binlog,得额外 PURGE BINARY LOGS BEFORE '2026-06-01 00:00:00'; 再设 gtid_purged。
跳过空洞 vs 重置 GTID:什么情况该选哪个
空洞(比如 uuid:1,3,4 缺 2)是正常现象,不影响复制;不连续(比如从库有 uuid:1-100,新主库 gtid_purged 是 uuid:1-50)才是真问题。前者用单个 SET GTID_NEXT + BEGIN; COMMIT; 就能跳,后者必须重置整个 GTID 上下文——因为 gtid_purged 是主库告诉从库“我能提供的最早起点”,它错了,整个同步链就断了。











