MySQL GTID 模式下同步报错 1840 通常表示尝试设置 GTID_PURGED 时 GTID_EXECUTED 不为空。最推荐的处理方向是在从库执行 RESET SLAVE ALL 清空已执行集合,再重新设定 PURGED 值。适用场景为从库需要重新指向主库 GTID 位置且允许清空本地同步历史。风险边界在于 RESET SLAVE ALL 会清除从库同步元数据,需确保主库 binlog 完整。
先说结论:报错 1840 是因为 GTID_EXECUTED 非空导致无法覆盖 PURGED 集合,必须清空执行历史。
- 先确认 SHOW SLAVE STATUS 中 GTID_EXECUTED 是否有值
- 先处理 执行 RESET SLAVE ALL 清除本地 GTID 记录
- 再验证 重新设置 GTID_PURGED 并启动同步
命令速用版
以下命令用于快速清空从库 GTID 执行历史并重置同步位置,请在从库执行。
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL GTID_PURGED = '主库 GTID 集合';
START SLAVE;为什么会这样
报错 1840 的本质是 MySQL 保护机制防止 GTID 事务丢失或重复。GTID_EXECUTED 记录实例已执行的事务,GTID_PURGED 记录已丢弃不再需要的 binlog 对应事务。当 GTID_EXECUTED 不为空时,MySQL 禁止设置 GTID_PURGED,因为这意味着你可能试图告诉从库“某些事务已丢弃”,但实际上从库记录显示“这些事务已执行”,这会导致主从 GTID 集合逻辑冲突。
分步处理
按顺序执行以下步骤,确保每一步检查点通过后再进行下一步。
步骤 1:停止同步线程
执行 STOP SLAVE; 确保 IO 和 SQL 线程停止,避免处理新事务干扰重置。
步骤 2:清空 GTID 执行历史
执行 RESET SLAVE ALL; 该命令会清除复制通道信息并清空 GTID_EXECUTED 变量。注意该操作不可逆,需确认不再需要当前从库的同步进度。
步骤 3:获取主库 GTID 集合
在主库执行 SELECT @@GLOBAL.GTID_EXECUTED; 复制结果。确保主库 binlog 未发生 Purge,否则从库无法追平。
步骤 4:设定从库 Purged 值
在从库执行 SET GLOBAL GTID_PURGED = '主库 GTID 集合'; 此时应不再报错 1840,因为 GTID_EXECUTED 已为空。
步骤 5:重启同步
执行 START SLAVE; 启动复制线程。
怎么验证是否生效
执行 SHOW SLAVE STATUS\G 检查状态。
检查点 1:Slave_IO_Running 和 Slave_SQL_Running 均为 Yes。
检查点 2:Last_Error 和 Last_SQL_Error 字段为空。
检查点 3:执行 SHOW GLOBAL VARIABLES LIKE 'gtid_executed'; 确认值随同步进度增长,不再为空。
常见坑
版本差异:RESET SLAVE ALL 清空 GTID_EXECUTED 的行为在 MySQL 5.7.8 之后才稳定支持,旧版本可能需要重启实例或修改底层文件。
数据一致性:重置 GTID 位置不校验数据内容,若从库数据与主库不一致,强制同步可能导致数据覆盖或冲突,建议先校验 checksum。
Binlog 保留:若主库 binlog 已 purge 掉从库缺失的事务,重置 GTID 后从库无法找回缺失事务,需重新全量同步。
常见问题
可以不重置直接跳过报错吗
不建议,跳过报错会导致 GTID 集合不一致,后续切换主从时可能引发事务重复或丢失。
主库需要配合操作吗
不需要,主库只需提供当前的 GTID_EXECUTED 集合值,无需重启或修改配置。
RESET SLAVE 和 RESET SLAVE ALL 有什么区别
RESET SLAVE 仅重置复制通道信息,不一定清空 GTID_EXECUTED;RESET SLAVE ALL 会清除所有复制信息并清空 GTID 执行记录。
参考来源
MySQL Official Documentation, Server Error Codes and Messages, Error 1840 ER_GTID_PURGED_WAS_NOT_EMPTY, URL: https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
MySQL Official Documentation, Replication with Global Transaction Identifiers, URL: https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html