主从延迟高时应先确认同步线程真实运行状态,而非直接调参;需结合SHOW PROCESSLIST、日志位置比对及InnoDB锁信息定位IO或SQL线程卡点。

主从延迟高,第一反应不是调参数,而是确认同步线程是否真在跑、有没有卡住。很多所谓“延迟1小时”,其实是 Seconds_Behind_Master 显示 NULL 或 0,但 Slave_SQL_Running_State 停在 “Waiting for dependent transaction to commit” 这类状态——线程根本没在执行 SQL。
查同步线程真实状态:别只看 SHOW SLAVE STATUS 的一眼数值
延迟高时,Seconds_Behind_Master 经常失真:主库没写 binlog、从库 IO 线程断连、SQL 线程被锁住,它都可能显示 0 或 NULL。必须结合线程运行态和日志位置比对:
- 用
SHOW PROCESSLIST查两个关键线程:system user对应的IO_THREAD和SQL_THREAD,看它们的State列是不是活跃(如 “Queueing master event to the relay log”、“Reading event from the relay log”) - 对比
Relay_Master_Log_File+Exec_Master_Log_Pos和主库当前SHOW MASTER STATUS的File+Position,算出 relay log 落后多少 event;再对比Master_Host网络延迟能否解释这个 gap - 如果
Slave_SQL_Running_State是 “Waiting for table metadata lock” 或 “Waiting for commit lock”,说明是 DDL 或长事务阻塞了 SQL 线程,不是复制本身慢
定位 SQL 线程卡点:重点盯 innodb_row_lock_waits 和大事务
SQL 线程单线程回放,一旦遇到行锁冲突或大事务,就会停住不动。这时候 Seconds_Behind_Master 会持续上涨,但 IO 线程照常拉日志。
- 查从库
SHOW ENGINE INNODB STATUS\G,重点关注TRANSACTIONS部分里是否有长时间未提交的事务,以及ROW OPERATIONS中的锁等待 - 监控
information_schema.INNODB_METRICS表里的innodb_row_lock_waits,突增说明 SQL 线程频繁等锁 - 检查主库有没有执行过
ALTER TABLE或UPDATE扫全表——这类操作在从库回放时会锁住整张表,且无法并行(即使开了slave_parallel_workers) - 临时绕过:用
STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;跳过卡住的 event(仅限测试环境或明确知道后果时)
IO 线程延迟:网络、磁盘、主库 dump 线程压力三选一
如果 Slave_IO_Running 是 Yes,但 Read_Master_Log_Pos 长时间不更新,问题在 IO 层。常见原因不是带宽不够,而是更隐蔽的瓶颈:
- 主库
binlog_dump线程卡住:查主库SHOW PROCESSLIST,看是否有状态为 “Sending binlog event to slave” 却持续很久的线程,可能是主库磁盘 I/O 拥塞或 binlog 文件太大(单个超 1GB)导致读取慢 - 从库 relay log 写入慢:检查从库磁盘是否用的是机械盘、
relay_log是否和datadir在同一块物理盘上,有竞争 - 网络抖动但没断:TCP 重传率高会导致 IO 线程反复重试,
netstat -s | grep -i "retransmitted"可辅助判断;此时Slave_IO_State可能显示 “Connecting to master” 或 “Waiting for master to send event”
真正难处理的,是那种 Seconds_Behind_Master 忽高忽低、但始终掉不下去的情况——大概率是主库有周期性大事务(比如每小时一次的归档脚本),而从库还没来得及消化完就又来了新压力。这种时候光看监控图表没用,得抓 SHOW SLAVE STATUS 的快照序列,比对 Exec_Master_Log_Pos 的推进节奏。


















