mysql 5.7从库因单线程回放大事务而停摆,需主键分段+三步验证拆分并满足三个并行复制条件才能真正提速。

大事务直接卡死从库SQL线程
MySQL 5.7 的从库默认仍是单线程回放 Relay Log,一个未提交的大 UPDATE 改 100 万行,主库可能几秒完成,但从库 SQL 线程必须串行执行完全部变更才能推进 Exec_Master_Log_Pos。这期间后续所有 binlog 都在 relay log 里排队,Seconds_Behind_Master 会线性上涨,不是“慢”,是“停摆”。
LIMIT + ORDER BY 拆分事务极易漏数据或重复
用 UPDATE ... WHERE status = 'pending' ORDER BY created_at LIMIT 5000 看似合理,但实际风险极高:
-
created_at若无索引,每次排序物理顺序不一致,同一批数据可能被跳过或重复处理 - 第二批执行时,第一批已更新的行仍满足
WHERE status = 'pending',导致误改 -
LIMIT不提供断点依据:无法判断是否真扫完了全表,中途失败就得重头来
安全拆分必须基于主键分段 + 三步验证
真正可用的拆分逻辑只有三步闭环:
- 先查范围:
SELECT MIN(id), MAX(id) FROM t WHERE status = 'pending' - 按主键分批:
UPDATE t SET status = 'done' WHERE id BETWEEN 100000 AND 109999 AND status = 'pending' - 每批后检查:
ROW_COUNT()返回 0 就退出,非 0 才继续下一区间
缺任何一环,都可能漏数据、重复或无限循环。
拆完还不提速?检查这三个并行复制硬性条件
即使事务拆小了,从库仍串行回放,延迟只是从“小时级”变成“分钟级”。必须同时满足:
-
slave_parallel_type = 'LOGICAL_CLOCK'(不能是DATABASE) -
binlog_row_image = 'FULL'(主库配置,否则从库无法生成逻辑时钟) -
slave_preserve_commit_order = ON(否则多 worker 可能破坏事务顺序)
少一个,slave_parallel_workers 设再高也无效。
id,网络抖动或锁等待一中断,就得全表重扫。这不是优化问题,是可靠性底线。











