mysql从库延迟严重怎么办_mysql同步异常分析

来源:这里教程网 时间:2026-02-28 20:43:23 作者:

主从延迟怎么看:先确认是不是真延迟

很多情况下所谓“延迟严重”,其实是监控误报或误读

Seconds_Behind_Master
。这个值在从库 SQL 线程空闲、IO 线程也空闲时才准确;一旦从库正在执行大事务、或主库写入突增,它可能长时间卡在某个值不动,甚至为
NULL
(比如 SQL 线程已停止)。

先执行
SHOW SLAVE STATUS\G
,重点看
Slave_IO_Running
Slave_SQL_Running
是否都为
Yes
如果
Seconds_Behind_Master
NULL
,大概率是 SQL 线程挂了,不是慢,是停了
对比主库
SHOW MASTER STATUS
File
/
Position
和从库的
Master_Log_File
/
Read_Master_Log_Pos
(IO 进度)以及
Relay_Master_Log_File
/
Exec_Master_Log_Pos
(SQL 执行到哪),能更准判断是否真落后

SQL 线程卡住:常见原因和快速定位

真正拖慢同步的,90% 是 SQL 线程执行慢,而不是网络或磁盘 IO。MySQL 5.7+ 可以用

performance_schema
查正在执行的复制事件:

SELECT * FROM performance_schema.replication_applier_status_by_worker\G

重点关注

LAST_SEEN_TRANSACTION
LAST_ERROR_NUMBER
。常见卡点:

Lock wait timeout exceeded
:从库有长事务或未提交事务锁表,阻塞了 SQL 线程回放
Duplicate entry
:主从数据不一致导致唯一键冲突,SQL 线程直接 stop
大事务回放:主库一个
UPDATE
影响 500 万行,从库单线程重放,耗时数小时
从库开了
binlog_format = STATEMENT
但用了非确定函数(如
NOW()
UUID()
),导致日志无法安全重放

加速同步的实操手段:别只盯着并行复制

开启并行复制(

slave_parallel_workers > 0
)确实有用,但前提是主库写入本身能按库/表拆分。如果所有写都在一个库一个表,开再多 worker 也没用——全串行。

确认主库
binlog_format
ROW
(必须,STATEMENT 模式下并行复制基本无效)
设置
slave_parallel_type = LOGICAL_CLOCK
(比 DATABASE 更细粒度)
调高
slave_parallel_workers
(建议设为 CPU 核数 -1,不要盲目设 64)
临时跳过非关键错误(慎用):
SET GLOBAL sql_slave_skip_counter = 1;
或用
gtid_next
跳过指定事务
对已知大事务,可在主库拆成小批量(比如每次
UPDATE ... LIMIT 10000
+
SLEEP(0.1)

容易被忽略的底层瓶颈:磁盘和 relay log 配置

很多人查完 SQL 线程、开了并行,延迟还是下不去——这时候要看 I/O。

从库
relay_log
文件默认写在 MySQL 数据目录,如果和
datadir
共用同一块慢盘(尤其是机械盘),relay log 写入 + 回放读取会互相抢占
检查
relay_log_space_limit
:设得太小会导致频繁轮转 relay log,触发 fsync,拖慢 SQL 线程
sync_relay_log = 1
是安全的,但每写一次 relay log 就刷盘一次;生产环境可考虑设为
10000
(每 10000 次写刷一次),代价是 crash 后最多丢 10000 条 relay event
确保从库
innodb_flush_log_at_trx_commit = 1
(主库也是),否则主从数据一致性无法保证,加速反而埋雷

真正卡住的时候,往往不是配置没开,而是磁盘扛不住、事务太大、或者从库上跑了备份脚本把 IO 打满了。先看

iostat -x 1
,再看
SHOW PROCESSLIST
,比改参数管用得多。

相关推荐