不能直接改;必须先STOP SLAVE,比对Relay_Master_Log_File与主库SHOW MASTER LOGS结果,若已被purge则用SHOW MASTER STATUS最新File和Position执行CHANGE MASTER TO,禁用MASTER_AUTO_POSITION=1以防GTID断层,并校验Seconds_Behind_Master、测试写入及binlog实际写入状态。

Master_Log_File 和 Exec_Master_Log_Pos 对不上,直接改就行?
不能直接改。MySQL 从库的 Master_Log_File 和 Exec_Master_Log_Pos 是 SHOW SLAVE STATUS\G 里两个关键字段,分别表示「从库当前连接的主库 binlog 文件名」和「该文件中已执行到的位置」。它们不匹配主库真实状态时,START SLAVE 会卡住、报错或跳过事务——尤其是当 Master_Log_File 指向一个已被主库 purge 掉的旧 binlog(比如 mysql-bin.000012),而主库当前是 mysql-bin.000045,这时从库根本读不到日志。
真正要校对的是 Relay_Master_Log_File 和 Exec_Master_Log_Pos 这一对,它反映的是「从库 SQL 线程实际执行完的那条语句,在主库 binlog 中的位置」。这个位置必须能被主库当前的 binlog 文件覆盖,否则同步失败。
- 先在从库执行
STOP SLAVE; - 再查
SHOW SLAVE STATUS\G,重点关注Relay_Master_Log_File和Exec_Master_Log_Pos - 去主库执行
SHOW MASTER LOGS;,确认Relay_Master_Log_File是否还在列表里;如果不在,说明已被清理,必须重设位点 - 若已清理,主库上执行
SHOW MASTER STATUS;,拿到最新的File和Position
CHANGE MASTER TO 时该用哪个文件名和位置?
用 Relay_Master_Log_File 和 Exec_Master_Log_Pos 做起点,不是 Master_Log_File 和 Read_Master_Log_Pos。后者只是 IO 线程拉取进度,可能滞后、甚至出错;前者才是 SQL 线程真正“消化完”的位置,是数据一致性的锚点。
但注意:这个位置必须存在于主库当前 binlog 中。如果主库已滚动并 purge,你就得退回到一个安全的、双方都还保留的 binlog 位置——通常选 SHOW MASTER STATUS; 返回的最新 File + Position,前提是主库没开启 GTID 或你已确认 GTID 集合兼容。
- 主库执行
SHOW MASTER STATUS;,记下File(如mysql-bin.000045)和Position(如1987) - 从库执行:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000045', MASTER_LOG_POS=1987; - 不要加
MASTER_AUTO_POSITION=1,除非你确认主从 GTID 集合完全对齐(SELECT @@global.gtid_executed;对比) - 执行后立刻
START SLAVE;,再看Seconds_Behind_Master是否开始下降
为什么 RESET SLAVE ALL 后反而同步不了?
因为 RESET SLAVE ALL 会清空 gtid_purged,但主库的 gtid_executed 可能包含大量已 purge binlog 对应的 GTID。从库重启后尝试自动定位,发现主库缺了那些 GTID 对应的日志,就直接拒绝连接,报错:The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.
这不是配置问题,是数据断层。此时不能硬启,必须人工干预:
- 从库执行
SELECT @@global.gtid_executed;,主库也执行同一句,对比差异 - 若从库 GTID 集合超前(比如多了
aaa-fff:1-100,但主库gtid_purged已含aaa-fff:1-80),说明从库有未同步的事务残留,需用SET GLOBAL gtid_purged = '...';手动补全(仅限空从库或已确认无写入) - 更稳妥的做法是放弃 GTID 自动模式,切回基于文件+位置的手动模式:
CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE='...', MASTER_LOG_POS=...;
校对位点后还要验证什么?
位点对上只是第一步,不代表数据真一致。常见漏掉的验证点:
-
Seconds_Behind_Master归零后,等 1–2 分钟再查一次,确认不反弹(防短暂延迟假象) - 在主库写一条带唯一标识的测试记录(如
INSERT INTO test_sync (ts) VALUES (NOW());),立刻查从库是否出现 - 检查
Slave_SQL_Running_State是否为Slave has read all relay log; waiting for more updates,而不是卡在某条语句 - 如果业务允许,用
pt-table-checksum对比主从表级数据一致性(注意避开高峰期)
最容易被忽略的是:校对位点后没确认主库 binlog 是否真的在写入——比如主库误关了 log_bin,或者 binlog_do_db 配置过滤掉了目标库。位点再准,日志不产生,从库永远追不上。


















