主从复制延迟高需先验证seconds_behind_master是否真实延迟,再检查io/sql线程状态;并行复制需合理配置slave_parallel_workers和参数匹配;sync_binlog与innodb_flush_log_at_trx_commit须协调;大事务会阻塞并行回放,应拆分处理。

主从复制延迟高,先看 Seconds_Behind_Master 是不是真延迟
很多情况下 Seconds_Behind_Master 显示几百秒,但实际是误报:比如从库 SQL 线程空闲、IO 线程卡在重连、或者主库 binlog 刷盘慢导致位点没更新。先执行 SHOW SLAVE STATUS\G,重点核对三处:Slave_IO_Running: Yes、Slave_SQL_Running: Yes、Seconds_Behind_Master 是否持续增长。如果 IO 线程为 No,问题根本不在复制性能,而是网络、权限或主库 binlog 关闭。
启用并调优 slave_parallel_workers 并非开得越多越好
MySQL 5.6+ 支持基于库(database)或事务(LOGICAL_CLOCK)的并行复制,但默认值是 0(即关闭)。开启前必须确认:slave_parallel_type 设为 LOGICAL_CLOCK(推荐),且主库 binlog_transaction_dependency_tracking 为 WRITESET 或 WRITESET_SESSION(MySQL 8.0+)。否则并行线程会退化成串行。
-
slave_parallel_workers建议从 4 开始试,最大不宜超过 CPU 核数的 75%(例如 16 核服务器设为 12) - 值过大反而增加线程调度开销,尤其当大事务占比高时,可能引发频繁的
Waiting for dependent transaction等待 - 修改后需执行
STOP SLAVE; START SLAVE;才生效,不能热加载
sync_binlog 和 innodb_flush_log_at_trx_commit 不匹配会拖慢主库写入
迁移后主库压力变大,若 sync_binlog=1(每事务刷 binlog)但 innodb_flush_log_at_trx_commit=2(每秒刷 redo),会导致主库事务提交被 binlog 强制阻塞——因为 MySQL 要求 binlog 和 innodb redo 日志严格一致(组提交机制依赖二者同步点)。这种不匹配会让主库 TPS 下降,间接拉长从库追赶时间。
- 生产环境建议统一设为
sync_binlog=1+innodb_flush_log_at_trx_commit=1(强一致性) - 若追求性能可设为
sync_binlog=1000+innodb_flush_log_at_trx_commit=2,但主从延迟波动会变大,且崩溃可能丢最多 1 秒事务 - 检查命令:
SELECT @@sync_binlog, @@innodb_flush_log_at_trx_commit;
大事务和单表热点更新是并发复制的硬伤
即使开了 slave_parallel_workers=16,只要有一个 20 分钟的 UPDATE 单表语句,整个 SQL 线程池就会被锁住——因为 MySQL 的并行逻辑要求同一表的 DML 必须串行回放,避免冲突。这类事务在 SHOW PROCESSLIST 中常表现为 Reading event from the relay log 后长时间卡住。
- 拆分大事务:用
LIMIT分批更新,配合SLEEP(0.1)控制节奏 - 避免在从库执行
ALTER TABLE或CREATE INDEX,这类操作会阻塞所有并行线程 - 监控长期运行事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60;
真正难处理的是跨库事务少、但单库内高频小事务+偶发大事务混杂的场景——这时并行参数调再细也没用,得靠业务层控制写入节奏或引入中间件分流。











