大事务导致主从延迟是因为SQL线程必须等整个事务执行完才更新Seconds_Behind_Master;拆分INSERT INTO SELECT需按主键分段、每批5k–10k行、独立提交、目标表建索引,并避免依赖实时MAX(id)。
大事务是主从延迟最顽固的成因,必须拆分,不能只调参或升硬件。
MySQL 的 SQL 线程回放事务时,必须等整个事务执行完才更新 Seconds_Behind_Master。一个未拆分的 INSERT INTO dst SELECT * FROM src 执行 25 秒,从库在这 25 秒内:- 不会推进复制位点- 主库新产生的 binlog 全部排队等待- Seconds_Behind_Master 可能一直显示为 0 或旧值,监控完全失灵
不能用 LIMIT + OFFSET,会漏数据;也不能只加时间条件,源表可能正在写入。正确做法是:-
id)分段,例如 WHERE id BETWEEN 100000 AND 200000,确保范围不重叠、可覆盖全量INSERT 本身就会变慢,拆分反而更差SLEEP(0.1) 缓冲,降低从库瞬时压力这类操作若没走索引或没加 LIMIT,会在从库长时间持有锁,阻塞其他事务回放:-
EXPLAIN 确认 WHERE 条件是否命中索引;没命中就加索引,别硬扛LIMIT 的循环:例如 UPDATE t SET status=1 WHERE status=0 ORDER BY id LIMIT 5000,查 ROW_COUNT() 判断是否结束binlog_format = STATEMENT 下的大范围 DML,它在从库可能因函数、临时表等执行失败或更慢最容易被忽略的一点:拆分逻辑必须覆盖所有数据,且不能依赖 MAX(id) 实时值——如果源表持续写入,MAX(id) 会漂移。应先查出最大 id 快照,或用双游标方式处理活跃写入场景。