主从延迟飙升需排查SQL线程瓶颈、启用LOGICAL_CLOCK多线程复制、校验半同步插件与配置,并避免多线程与半同步隐性冲突。

主从延迟突然飙升,Seconds_Behind_Master 一直不归零怎么办
这不是 MySQL 自己能“慢慢追上”的问题,得看它卡在哪。常见现象是 Seconds_Behind_Master 持续增长、甚至卡死不动,但 Slave_IO_Running 和 Slave_SQL_Running 都显示 Yes。本质是 SQL 线程单点串行回放太慢,尤其遇到大事务、DDL 或写入热点表时。
实操建议:
- 先查
SHOW PROCESSLIST看State字段,如果长期停在Waiting for table metadata lock或Updating,说明是锁等待或单条语句执行慢 - 用
SELECT * FROM performance_schema.replication_applier_status_by_worker;确认是否启用了多线程复制(WORKER_ID多于 1 表示启用) - 别只看
Seconds_Behind_Master数值——它在 GTID 模式下可能不准,优先看Retrieved_Gtid_Set和Executed_Gtid_Set的差集
开启 slave_parallel_workers 后没效果,还是单线程跑
开了参数 ≠ 自动生效。MySQL 5.7+ 默认用 DATABASE 级并行策略,但前提是每个事务只修改一个库;如果业务用 USE db1; UPDATE t1... + USE db2; UPDATE t2... 混着来,或者所有表都在同一个库下,那压根分不出并行度。
实操建议:
- 确认
slave_parallel_type设为LOGICAL_CLOCK(比默认的DATABASE更激进,按事务提交顺序分组) - 设置
slave_parallel_workers为 CPU 核数的 1–2 倍(比如 4 核设 4 或 8),但别超过 16,否则线程调度开销反超收益 -
slave_preserve_commit_order=ON必须打开,否则并行回放会破坏事务提交顺序,导致主从数据逻辑不一致 - 检查 binlog 格式:必须是
ROW,MIXED或STATEMENT下LOGICAL_CLOCK不工作
半同步复制 开了却没生效,Rpl_semi_sync_master_status 显示 OFF
半同步不是“一配就稳”,它依赖插件加载、网络连通性、从库响应速度三重条件。最常踩的坑是:主库插件装了,但从库没装 semisync_slave.so,或者主库配置里漏了 rpl_semi_sync_master_enabled=1,只改了从库。
实操建议:
- 主从两端分别执行
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';和INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; - 主库设
rpl_semi_sync_master_enabled=1,从库设rpl_semi_sync_slave_enabled=1,重启复制线程(STOP SLAVE; START SLAVE;) - 用
SHOW VARIABLES LIKE '%semi%';和SHOW STATUS LIKE '%semi%';双查状态,重点盯Rpl_semi_sync_master_status和Rpl_semi_sync_slave_status是否都为ON - 别把
rpl_semi_sync_master_timeout设太高(比如 10s),否则主库等太久会退化为异步,失去保护意义;建议 1000ms 起步,观察失败率再调
多线程复制 + 半同步一起上,为什么延迟反而更大了
两个机制叠加不是简单相加,而是存在隐性冲突:半同步要求主库等至少一个从库 ACK 回放完成,而多线程回放会让 ACK 时间变得不可预测——某个 worker 卡住,整个半同步就卡住。结果就是主库写入被拖慢,binlog 积压,反过来加剧从库追赶压力。
实操建议:
- 先确保半同步稳定(
Rpl_semi_sync_master_status=ON且失败率 - 监控
Rpl_semi_sync_master_no_times和Rpl_semi_sync_master_yes_times的比值,如果频繁 fallback,说明网络或从库负载已到瓶颈,强行加并发只会恶化 - 考虑用
replica_compression_type=zstd(8.0.20+)压缩 binlog 网络传输,比调并发更直接降低 IO 延迟 - 真正高一致性场景,别只靠半同步——应用层做写后读(read-after-write)路由,或用 ProxySQL 做强一致性读分离
延迟问题从来不是单点参数能解决的,主从之间那条链路上,任何一个环节的微小抖动都会被放大。最容易被忽略的是从库磁盘 IO 能力——和主库同配置的机器,用普通 SATA 盘跑从库,遇到批量导入就必然积压,这时候调 slave_parallel_workers 没用,换 NVMe 才是正解。










