seconds_behind_master不准,因仅反映sql线程回放延迟,忽略网络、io线程及未提交事务;应结合exec_master_log_pos与read_master_log_pos差值、pt-heartbeat端到端测延、gtid对比及sql线程状态综合判断。

主从延迟怎么看:Seconds_Behind_Master 为什么不准
Seconds_Behind_Master 是最常被查的指标,但它只反映 SQL 线程回放 relay log 的时间差,不包含网络传输、IO 线程写 relay log、大事务未提交等真实延迟。比如主库正在执行一个 30 分钟的 UPDATE,从库 IO 线程已拉完 binlog,SQL 线程卡在事务里没提交,Seconds_Behind_Master 可能仍显示 0。
更可靠的判断方式是对比主从的 SHOW MASTER STATUS 和 SHOW SLAVE STATUS 中的 Exec_Master_Log_Pos 与 Read_Master_Log_Pos 差值,再结合 Relay_Master_Log_File 和 Master_Log_File 是否一致。若文件名不同,说明 IO 线程已落后;若文件名相同但位置差值持续增大,大概率是 SQL 线程瓶颈。
- 用
pt-heartbeat工具打点测端到端延迟(推荐,跨事务、跨网络) - 检查从库是否启用了
slave_parallel_workers > 0,但slave_parallel_type = DATABASE导致单库并发退化为串行 - 留意
Slave_SQL_Running_State值,如长期停留在Reading event from the relay log或Waiting for dependent transaction to commit,说明有依赖阻塞或大事务
SQL 线程卡住的常见原因和快速确认法
从库同步慢,90% 问题出在 SQL 线程,而不是网络或磁盘。直接看 SHOW PROCESSLIST 里 User 为 system user 的线程状态,再结合 SHOW SLAVE STATUS\G 的 Seconds_Behind_Master、SQL_Delay、Retrieved_Gtid_Set 和 Executed_Gtid_Set 对比。
- 如果
Executed_Gtid_Set明显落后于Retrieved_Gtid_Set,且Slave_SQL_Running_State是Executing event,大概率是某条语句执行慢(比如没走索引的DELETE) - 遇到
Waiting for table metadata lock:说明该表正被主库上的长事务或 DDL 持有 MDL,从库 SQL 线程必须等它释放,此时去主库查SELECT * FROM performance_schema.threads WHERE PROCESSLIST_COMMAND = 'Sleep' AND PROCESSLIST_TIME > 60 - 开启
log_slow_slave_statements = ON后,慢 SQL 会记录到从库 slow log,配合long_query_time = 1容易捕获
GTID 模式下复制中断的定位口诀
GTID 复制一旦报错,错误信息通常带 Could not execute Write_rows_v1 event on table 或 The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1,但实际缺失某个 GTID。核心思路是:先确认缺失的 GTID 是什么,再判断它是否真的在主库 binlog 里。
- 从库报错时,
Last_IO_Error或Last_SQL_Error里会明确写出缺失的 GTID,形如5d8b4e2a-1234-11ee-a7a7-00155d012345:12345 - 登录主库,执行
mysqlbinlog --base64-output=DECODE-ROWS -v binlog.000001 | grep -A 10 "5d8b4e2a-1234-11ee-a7a7-00155d012345:12345",确认该 GTID 是否存在且事件完整 - 若存在但从库跳不过去,可能是主库 binlog 被删过,或从库 relay log 损坏;此时不能直接
SET GLOBAL gtid_purged = ...,应先STOP SLAVE; RESET SLAVE ALL;,再重新CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1
并行复制为什么没加速:参数组合陷阱
MySQL 5.7+ 默认启用基于逻辑时钟的并行复制(slave_parallel_type = LOGICAL_CLOCK),但效果取决于主库是否生成足够多的“可并行组”。如果主库 binlog_group_commit_sync_delay 设得过大,或事务太小又太密集,会导致大量事务被合并进同一个组,从库只能串行回放。
- 检查主库
SHOW VARIABLES LIKE 'binlog_group_commit_sync%',binlog_group_commit_sync_delay建议设为 0(默认 0),避免人为压组 - 从库上确认
slave_parallel_workers > 0且slave_parallel_type = LOGICAL_CLOCK,同时slave_preserve_commit_order = ON(否则可能乱序提交) - 观察
SHOW STATUS LIKE 'Slave_open_temp_tables'和Slave_retried_transactions,若后者持续增长,说明并行冲突频繁触发重试,需检查是否有跨库写、或大量INSERT ... SELECT类语句
真正影响同步性能的,往往不是单个配置开关,而是主从之间事务粒度、锁竞争、索引缺失、甚至从库磁盘 IOPS 不足这些叠加因素。排查时别只盯着 Seconds_Behind_Master,先抓实时线程状态和慢日志,再反推主库行为。











