大事务阻塞主从复制的本质是SQL线程被单个长事务锁死,导致Seconds_Behind_Master飙升而Exec_Master_Log_Pos几乎不动;需通过SHOW SLAVE STATUS检查SQL线程状态、位点推进及延迟趋势,并结合主库INNODB_TRX确认大事务,同时确保并行复制参数配置正确,识别伪大事务并从源头拆分。

大事务导致的主从阻塞,本质是SQL线程被单个长事务锁死,Seconds_Behind_Master飙升但Exec_Master_Log_Pos几乎不动——这不是网络或IO问题,是复制架构的串行化瓶颈。
怎么看是不是大事务卡住SQL线程
别只盯Seconds_Behind_Master。先在从库执行SHOW SLAVE STATUS\G,重点看三处:
-
Slave_SQL_Running_State显示Waiting for dependent transaction to commit或Reading event from the relay log(而非空闲) -
Exec_Master_Log_Pos长时间不推进,和Read_Master_Log_Pos差距持续拉大 -
Seconds_Behind_Master稳定上涨,比如每秒+1、+2,不是跳变
再查主库确认是否存在活跃大事务:SELECT trx_id, trx_started, trx_rows_modified, trx_state FROM information_schema.INNODB_TRX WHERE trx_rows_modified > 10000 AND trx_started 。如果返回结果,基本就是它了。
为什么拆分LIMIT不能直接加在原SQL上
直接在DELETE/UPDATE里加LIMIT而不控制事务边界,等于把一个大事务拆成一堆小事务——binlog体积暴增,relay log堆积更快,反而加重从库压力。
- 必须显式
SET autocommit = 0,手动START TRANSACTION和COMMIT每批次 - WHERE条件要可复用,比如
WHERE id > ? AND id ,避免<code>OFFSET导致越删越慢 - 每次执行后必须记录最后处理的
id(写入临时表或文件),否则中断重跑会漏数据或重复 - ORDER BY + LIMIT组合必须存在,防止幻读干扰分片边界
并行复制开了也无效?检查这三个配置
启用slave_parallel_workers > 0只是第一步,没配对就等于没开:
-
slave_parallel_type必须设为LOGICAL_CLOCK(5.7+)或WRITESET(8.0+),不能是DATABASE——后者只对跨库事务有效,而大事务通常集中在单表 - 主库
binlog_format必须为ROW,binlog_order_commits保持ON(默认值,别关) - 从库执行
SELECT * FROM performance_schema.replication_applier_status_by_worker,确认有多个WORKER_ID对应非空的LAST_SEEN_TRANSACTION;全为空说明并行没真正跑起来
最容易被忽略的“伪大事务”
代码里没写BEGIN,但循环中反复执行INSERT/UPDATE又不COMMIT,autocommit=1时每句都是独立事务——看起来小,实际因网络延迟、锁等待等凑成了隐式长事务。
- 查
information_schema.INNODB_TRX时trx_query为空,且trx_state = RUNNING,大概率是这类情况 - 用
SHOW ENGINE INNODB STATUS\G看“TRANSACTIONS”部分,找lock struct(s)数量多、wait started时间长的事务 - 业务代码里搜索
INSERT.*VALUES或UPDATE.*SET循环体,确认是否遗漏COMMIT或误设autocommit=0
大事务阻塞不是靠重启或跳过能解决的,关键在源头识别和语义安全拆分——漏一条数据、多删一行,都可能引发线上资损。


















