主主同步中断后应先确认server_id,再比对双方MASTER STATUS与SLAVE STATUS的File/Position及Exec_Master_Log_Pos,结合Relay_Log_Space增长、pt-heartbeat延迟和GTID位点综合判断数据丢失方。
MySQL 主主同步断开后怎么快速判断哪边丢了数据
主主同步(m-m)一旦中断,不能默认两边数据一致。最直接的办法是比对 show master status 和 show slave status 里的位点,但要注意:这些值只反映复制线程的「当前位置」,不等于「实际已执行的数据变更」。
- 先在两台服务器上分别执行
SELECT @@server_id,确认身份,避免看反 - 在 A 机上查
SHOW MASTER STATUS得到File和Position;再查SHOW SLAVE STATUS\G,重点看Master_Host是否指向 B,以及Read_Master_Log_Pos和Exec_Master_Log_Pos是否停滞 - 在 B 机上做同样操作,但方向反过来。如果 A 的
Exec_Master_Log_Pos停在某个位置,而 B 的Master_Position已经更靠后,说明 A 落后了 - 别信
Seconds_Behind_Master:它在 IO 线程卡住或 relay log 损坏时会显示NULL或 0,完全不可靠
INSERT 冲突导致同步中断,错误日志里看到 “Duplicate entry” 怎么修
这是 M-M 最典型的死锁场景:两边同时插入相同主键,其中一个被拒绝,SQL 线程报错停摆。关键不是“怎么跳过”,而是“为什么能插出重复”。
- 检查是否用了自增主键:
auto_increment_increment和auto_increment_offset必须配对设置,比如 A 设为increment=2, offset=1,B 就得是increment=2, offset=2,否则必然撞 - 不要手动改
auto_increment值,尤其不要用ALTER TABLE ... AUTO_INCREMENT=xxx,它不跨实例同步,下次插入就可能重复 - 修复时别用
SET GLOBAL sql_slave_skip_counter=1—— 它跳的是 event,不是语句,容易跳过不该跳的更新。优先用STOP SLAVE; SET GTID_NEXT='...'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE;(如果是 GTID 模式) - 如果非 GTID,且冲突简单,可用
INSERT ... ON DUPLICATE KEY UPDATE改写业务逻辑,把“必须插入”变成“有则更新”,从源头避开
连接反复断开,Lost connection to MySQL server during query 是网络问题还是配置问题
这个错误看着像网络抖动,但在 M-M 架构里,大概率是 max_allowed_packet 或 wait_timeout 不一致导致的假性断连。
- 两台服务器的
max_allowed_packet必须完全相等,否则大事务在 A 上能提交,在 B 上解析失败,IO 线程直接断开,日志里只写 “error reading packet” -
wait_timeout和interactive_timeout不影响复制本身,但会影响监控脚本、备份工具等间接连接。如果它们连着主库查状态,超时后重连可能触发复制线程误判 - 检查
slave_net_timeout:默认 3600 秒太长,建议调成 60。它控制的是 SQL 线程多久没收到新 event 就主动断开重连,设太大会掩盖真实延迟 - 抓包看 TCP 层:如果
tcpdump显示 FIN 包来自 MySQL 进程(不是中间设备),基本可锁定是服务端主动断开,不是网络问题
如何验证当前同步是否真正在跑,而不是“看起来在跑”
很多运维看到 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 就以为没问题,其实这两项只代表线程活着,不代表数据在流动。
- 对比
Relay_Log_Space:持续增长说明 IO 线程在收日志;长时间不变,说明上游没新日志,或者网络/权限阻塞了拉取 - 看
Seconds_Behind_Master的变化趋势,不是单次值。如果它缓慢爬升又突然归零,可能是 SQL 线程在重放一个大事务,期间不更新该字段 - 用
pt-heartbeat工具打时间戳表,比原生指标靠谱得多。它每秒写一条带当前时间的记录,从从库读出来算差值,结果是真实延迟 - 注意 binlog 格式:如果用了
MIXED或STATEMENT,某些函数(如NOW()、UUID())在从库执行结果不同,表面同步成功,实际数据已偏移
双向同步的脆弱性不在配置多难,而在所有环节都要求“两边绝对对称”。少改一个参数、漏查一次位点、忽略一行日志里的 warning,都可能让问题拖到故障爆发才暴露。

















