
MySQL主从复制出现延迟时,常见现象是主库已经写入数据,但从库查询仍返回旧结果;读写分离业务可能短暂读到旧数据,备份、报表和故障切换也会受到影响。
复制延迟并不等于网络一定有问题。MySQL复制链路至少可以拆成两段:接收线程从源库获取二进制日志并写入中继日志,应用线程再读取中继日志并在副本上执行事务。任何一段变慢,都会表现为“副本落后”。
一、先确认延迟发生在哪一段
在副本执行:
SHOW REPLICA STATUS\G
较旧版本仍可能使用:
SHOW SLAVE STATUS\G
优先检查以下字段:
| 字段 | 关注点 |
|---|---|
| Replica_IO_Running | 接收线程是否正常运行 |
| Replica_SQL_Running | 应用线程是否正常运行 |
| Seconds_Behind_Source | 副本应用进度相对源库的大致时间差 |
| Last_IO_Error | 接收二进制日志时的最近错误 |
| Last_SQL_Error | 执行中继日志时的最近错误 |
| Relay_Log_Space | 已积压的中继日志空间 |
Seconds_Behind_Source适合快速观察趋势,但不能单独作为最终判断。它可能为NULL,也可能受线程状态、时钟和事务执行方式影响。排查时应同时观察线程状态、GTID或日志位点是否持续推进,以及中继日志是否不断增长。
二、接收线程异常:先查网络、账号和源库日志
如果Replica_IO_Running不是Yes,或者Last_IO_Error有内容,问题通常发生在源库到副本的日志传输阶段。
建议依次检查:
- 副本能否访问源库的MySQL端口。
- 复制账号是否仍有正确权限,密码或认证方式是否被修改。
- 源库主机名、端口和TLS配置是否正确。
- 源库所需的二进制日志是否已经被清理。
- 网络是否存在持续丢包、抖动或跨地域延迟。
不要在未确认日志位置和数据一致性的情况下直接跳过事务。接收中断时间较长时,还要核对副本需要的二进制日志是否仍然保留;如果日志已经缺失,通常需要重新建立副本,而不是反复启动复制线程。
三、接收正常但应用落后:重点看慢事务和资源瓶颈
如果接收线程正常,中继日志持续写入,但Replica_SQL_Running虽然为Yes,应用位置推进很慢,说明瓶颈更可能位于副本执行阶段。
可以从Performance Schema查看复制工作线程:
SELECT
CHANNEL_NAME,
WORKER_ID,
SERVICE_STATE,
LAST_ERROR_NUMBER,
LAST_ERROR_MESSAGE,
APPLYING_TRANSACTION
FROM performance_schema.replication_applier_status_by_worker;
同时检查副本当前正在执行的语句:
SHOW FULL PROCESSLIST;
常见原因包括:
- 源库一次提交了大事务,副本必须花较长时间重放。
- 缺少合适索引,源库写入很快,但副本更新或删除时扫描大量数据。
- 副本同时承担报表、备份或高并发查询,CPU、磁盘I/O或内存资源被争用。
- 表结构变更、批量更新或批量删除占用应用线程。
- 并行复制能力不足,多个可并行事务没有得到充分执行。
- 副本硬件规格明显低于源库,长期无法追上写入速度。
四、检查是否存在大事务
复制延迟突然升高,并且在一段时间后又恢复,往往与大事务有关。可以结合二进制日志、应用发布记录和业务批处理时间确认。
需要特别留意:
- 一次更新或删除大量行。
- 将大量数据放在一个事务中提交。
- 没有索引条件的
UPDATE或DELETE。 - 定时归档、数据修复和批量导入任务。
更稳妥的做法是将可拆分的批处理改成小批次提交,并限制每批影响行数。这样可以缩短单个事务占用复制工作线程的时间,也便于暂停和重试。但拆批会改变事务边界,必须先确认业务允许。
五、检查副本的CPU、磁盘和查询负载
复制应用需要实际执行源库上的变更,因此副本并不是只“保存日志”。当副本磁盘延迟高、CPU长期繁忙,或同时承担复杂查询时,复制速度会明显下降。
Linux上可以结合以下命令观察:
top
vmstat 1
iostat -xz 1
重点判断:
- CPU是否持续接近饱和。
iowait是否长期偏高。- 数据盘延迟和队列是否持续增长。
- 是否有备份、报表或全表扫描与复制争用资源。
如果延迟只在备份窗口或报表高峰出现,应先调整任务时间或把分析查询迁移到专用副本,再考虑升级实例规格。
六、并行复制可以优化,但不要盲目调大线程数
MySQL可以使用多个应用工作线程并行执行符合条件的事务。先查看当前配置:
SHOW VARIABLES LIKE 'replica_parallel_workers';
SHOW VARIABLES LIKE 'replica_preserve_commit_order';
如果确认副本CPU和I/O仍有余量,而且积压主要来自大量可并行的小事务,可以评估提高replica_parallel_workers。线程数并不是越大越好:并行度受到事务依赖关系、热点表、锁竞争和硬件资源限制;设置过高还可能增加调度开销。
调整前应记录原值,在测试环境验证,并观察延迟、CPU、I/O和事务冲突是否改善。不同MySQL版本支持的动态修改方式和默认值可能不同,应以当前版本官方文档为准。
七、临时恢复时应怎么做
业务已经受到影响时,可以按风险从低到高处理:
- 暂停副本上的非必要报表、备份和批处理任务。
- 找出并终止明显占用资源的非复制查询,但要先确认业务影响。
- 修复接收线程的网络、账号或日志缺失问题。
- 为副本补充必要索引,或先在测试环境验证DDL影响。
- 在资源允许且事务具备并行条件时调整并行复制配置。
- 长期算力不足时升级副本规格,或拆分报表和读流量。
不要为了让延迟数字快速归零而随意执行跳过错误、重置复制或重新指定日志位点。这些操作可能让副本表面恢复运行,却留下数据缺失或不一致。
八、修复后如何验证
修复后至少完成以下检查:
Replica_IO_Running与Replica_SQL_Running均为Yes。Last_IO_Error和Last_SQL_Error没有新的错误。- GTID集合或日志位点持续推进。
Relay_Log_Space不再持续扩大。Seconds_Behind_Source总体回落并保持稳定。- 抽查关键业务数据,确认源库与副本结果一致。
- 观察一个完整业务高峰,而不是只看几分钟。
对于重要系统,还应建立复制线程状态、延迟、日志积压、磁盘延迟和副本只读状态的监控。告警阈值应结合业务对数据新鲜度的要求设置,不能把某个固定秒数套用到所有系统。
总结
MySQL主从复制延迟的核心,是先分清“日志没有及时收到”还是“日志收到了但执行不过来”。接收线程异常时,重点检查网络、账号和二进制日志;应用线程落后时,重点检查大事务、索引、资源争用和并行复制能力。
Seconds_Behind_Source只是入口指标。把线程状态、错误信息、日志位点、Performance Schema和系统资源放在一起观察,才能找到真正的瓶颈,并避免用高风险操作掩盖数据一致性问题。
参考资料
- MySQL 8.4 Reference Manual:SHOW REPLICA STATUS Statement
- MySQL 8.4 Reference Manual:Replication Tables in the Performance Schema
- MySQL 8.4 Reference Manual:Replication and Replica Options and Variables
- MySQL 8.4 Reference Manual:Monitoring Replication
资料核验日期:2026年9月8日




