mysql单线程sql回放无法切分大事务,其在binlog中为完整事件单元,从库必须原子执行全部变更;并行复制(mts)对大事务完全无效,因logical_clock和writeset均只在事务间并行,不拆分单事务内部;大事务导致静默延迟,seconds_behind_master执行中冻结不更新,掩盖真实积压。

MySQL单线程SQL回放无法切分大事务
大事务在binlog中是一个完整事件单元,从库SQL线程必须原子性地执行完全部变更才能推进到下一个事务。哪怕主库只用8秒提交一个DELETE FROM orders WHERE id > 1000000(删500万行),从库也得花几十秒甚至几分钟重放这500万行的row event——期间Seconds_Behind_Master不更新,但后续所有事务全被堵死。
并行复制(MTS)对大事务完全无效
MySQL的slave_parallel_type = LOGICAL_CLOCK只判断“不同事务之间”能否并行,不是把一个事务内部拆开跑。一个大事务的所有event共享同一last_committed值,会被强制分配给同一个worker线程,结果还是单线程串行处理。
- 即使你设了
slave_parallel_workers = 16,它也只加速“多个小事务并发回放”,对单个大事务毫无帮助 -
WRITESET模式同样失效:事务内所有行变更都落在同一张表、同一索引下,冲突检测认为必须串行 - 主库
binlog_group_commit_sync_delay再小,也无法缩短从库单事务回放时间
大事务会引发连锁资源争抢
从库执行大事务时,不只是SQL线程卡住,还会连带拖垮整个实例:
- 持有
metadata lock时间过长,阻塞其他DDL或DML语句 - 大量写入buffer pool和redo log,触发频繁刷脏页,挤占其他查询的内存资源
- 磁盘I/O持续满负荷,影响backup、pt-heartbeat心跳更新等后台任务
- 如果从库同时承担读流量,慢查询可能反过来锁住SQL线程(如MDL等待)
为什么Seconds_Behind_Master在大事务期间“假装正常”?
这个值只在事务提交后才计算时间差,事务执行中它保持冻结状态。你看到Seconds_Behind_Master: 0,不代表没延迟——可能SQL线程正卡在第300万行的update上,而主库已经又写了2万个新事务,这些全堆在relay log里没人处理。
真正危险的是这种“静默延迟”:监控告警不触发,DBA以为一切正常,直到切换失败或数据不一致暴露出来。











