MySQL主从延迟大需优先检查binlog_format=ROW和binlog_row_image=MINIMAL;调优slave_parallel_workers(设为CPU核数1.5–2倍)、relay_log_recovery=ON;用pt-heartbeat监控,主库限流大事务;GTID模式下禁用sql_slave_skip_counter,应通过gtid_executed与auto_position协同恢复。

主从复制延迟大,先看 binlog_format 和 row_image 配置
MySQL 主从延迟高,很多时候不是网络或硬件问题,而是 binlog 日志格式和行记录粒度不合理。默认 binlog_format=STATEMENT 在某些函数、临时表、非确定性语句下会出错或被降级,反而触发全表扫描;而 ROW 格式虽安全,但若 binlog_row_image=FULL(默认),每条 UPDATE/DELETE 都会记录整行前镜像和后镜像,日志体积暴增,IO 和网络压力同步上升。
-
binlog_format必须设为ROW,这是现代主从稳定复制的底线 - 将
binlog_row_image改为MINIMAL:只记录 WHERE 条件列(前镜像)和变更列(后镜像),大幅减少日志量,尤其对宽表 UPDATE 场景效果明显 - 注意:改完需重启 MySQL 或执行
SET GLOBAL binlog_row_image = 'MINIMAL',且从库slave_parallel_type为LOGICAL_CLOCK时才真正生效并提升并行回放效率
从库回放慢?检查 slave_parallel_workers 和 relay_log_recovery
5.7+ 默认开启并行复制,但常因配置不当形同虚设。核心是两个参数没调对:slave_parallel_workers 控制工作线程数,relay_log_recovery 决定崩溃后是否自动重建中继日志——若为 OFF,从库重启后可能跳过部分 relay log,导致数据不一致,进而触发全量校验或人工干预,间接拉长“感知延迟”。
-
slave_parallel_workers建议设为 CPU 核心数的 1.5–2 倍(如 8 核设 12),但不超过 32;值为 0 表示关闭并行,务必避免 -
slave_parallel_type必须为LOGICAL_CLOCK(而非DATABASE),否则跨库事务无法并行,实际并发度极低 - 确保
relay_log_recovery=ON,配合relay_log_purge=ON,避免 relay log 积压占满磁盘,也防止异常重启后状态错乱
大事务卡住从库?用 pt-heartbeat 监控 + 主库限流
单个事务更新百万行,从库只能串行回放,延迟瞬间飙升到小时级。这不是调参能解决的,得从源头控制事务粒度。但业务代码一时难改,就得靠外部工具监控和主库主动限流。
- 用
pt-heartbeat每秒在主库写时间戳、从库读取比对,比Seconds_Behind_Master更准(后者在 IO 线程卡住时会归零) - 主库启用
max_execution_time(8.0.12+)或触发器 + 存储过程拦截超长事务,例如超过 30 秒的 UPDATE 强制 KILL - 对已存在的大事务,可手动拆分:加
LIMIT+WHERE id BETWEEN ? AND ?分批提交,避免锁表和 binlog 爆涨
GTID 开启后复制中断,别急着跳过,先查 gtid_executed 和 auto_position
开启 GTID 后,SET GLOBAL sql_slave_skip_counter 失效,强行跳过会导致 GTID 集不一致,后续无法切换主从或做故障转移。真正可靠的恢复方式依赖 gtid_executed 和 auto_position=1 的协同。
- 从库报错 “The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs…”:说明主库 binlog 被清理,但从库还没拉取完
- 此时不能跳过,应先在主库查
SELECT @@global.gtid_executed;,再在从库执行SET GLOBAL gtid_purged = 'xxx'(填入主库最小未同步 GTID 集),然后CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1 - 务必确认
master_info_repository和relay_log_info_repository都设为TABLE,否则 GTID 位置信息重启后丢失
auto_position=1 看似省事,实则对 binlog 生命周期管理和运维响应速度要求更高。











