必须先执行 RESET SLAVE ALL 再设 gtid_purged,否则报 ERROR 1840;因 RESET SLAVE 仅清默认通道状态,不删 slave_master_info、不清理 gtid_executed 和 relay log,而 SET GLOBAL gtid_purged 强制要求 gtid_executed 为空且需满足三重校验。

必须先执行 RESET SLAVE ALL,再设 gtid_purged,否则 SET GLOBAL gtid_purged = '...' 会直接报错 ERROR 1840。
为什么不能只用 RESET SLAVE?
MySQL 8.0 默认按通道(channel)管理复制状态。RESET SLAVE 只清空默认通道('')的 IO/SQL 线程、relay log 文件名和位点,但不删 mysql.slave_master_info 表、不清理 gtid_executed、也不移除中继日志文件。残留的 relay log 或旧 Master_Host 会导致后续 CHANGE MASTER TO 失败,或 SHOW SLAVE STATUS 显示错误配置。
常见现象包括:
-
SHOW SLAVE STATUS\G仍显示旧主库地址 - 执行
START SLAVE后Slave_SQL_Running为No,且Last_IO_Error提示 “channel is running” -
gtid_executed未清空,导致SET GLOBAL gtid_purged被拒绝
重置 GTID 执行集的正确顺序
GTID 模式下,gtid_executed 是已落地事务的集合,它必须为空才能安全写入新的 gtid_purged 基线。这个过程不是“清空所有 binlog”,而是对齐从库的 GTID 上下文。
操作链必须严格按以下顺序执行:
STOP SLAVE-
RESET SLAVE ALL(注意是ALL) - 验证
SELECT @@global.gtid_executed返回空字符串('') - 在新主库上执行
SELECT @@global.gtid_executed,拿到完整值(如'ab1b2733-2401-11e7-82fc-525400abbf4b:1-500') - 在从库执行
SET GLOBAL gtid_purged = 'ab1b2733-2401-11e7-82fc-525400abbf4b:1-500'(值必须完全一致,不能缩写、不能含多余空格)
漏掉任一环,尤其是没确认 gtid_executed 为空,就会触发校验失败。
SET GLOBAL gtid_purged 的三个硬性校验
MySQL 在执行该语句时会做三重检查,全部通过才允许写入:
-
@@global.gtid_executed必须为空字符串('')——所以RESET SLAVE ALL不可省略 - 赋的值必须是新主库当前
gtid_executed的**前缀子集**(即不能包含新主库没有的 UUID 或超出其 TID 范围) - 实例必须已启用
gtid_mode = ON且enforce_gtid_consistency = ON,否则报错ERROR 1786
常见误操作:把 Retrieved_Gtid_Set 当成 gtid_executed 来比对;或从备份恢复后没清空 gtid_executed 就直接设 gtid_purged。
重连后必须验证的两个关键字段
执行完 CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1 和 START SLAVE 后,不能只看 Seconds_Behind_Master = 0 就认为 OK。
真正要盯住的是:
-
Executed_Gtid_Set:应逐步增长,并最终与新主库的gtid_executed完全一致(可用GTID_SUBSET()双向验证) -
Retrieved_Gtid_Set:应等于或大于Executed_Gtid_Set,且不能出现不属于新主库gtid_purged范围的 UUID
如果 Retrieved_Gtid_Set 里混进了测试库或旧主库的 GTID,说明 RESET SLAVE ALL 没起效,或者从库之前执行过非同步来源的事务——这种残留必须靠彻底重建数据目录来清除。


















