Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL主从复制延迟

MySQL主从复制延迟原因分析、判断方法与优化方案

作者:·云扬·

在 MySQL 主从架构的生产环境中,主从复制延迟是最常见、最影响业务稳定性的问题之一,今天我把实战中总结的延迟核心原因、精准判断方法、可落地优化方案全流程整理出来,希望能帮大家彻底搞定主从延迟问题,需要的朋友可以参考下

在 MySQL 主从架构的生产环境中,主从复制延迟是最常见、最影响业务稳定性的问题之一。轻则导致读写分离后数据查询不一致,重则引发业务逻辑异常、报警频发。

今天我把实战中总结的延迟核心原因、精准判断方法、可落地优化方案全流程整理出来,全部是生产可直接使用的干货,希望能帮大家彻底搞定主从延迟问题。

一、深度解析:主从复制延迟的 5 大核心原因

主从复制的核心流程:主库写入 Binlog → 从库 IO 线程拉取 Binlog 生成 Relay Log → 从库 SQL 线程回放 Relay Log

延迟的本质:主库写入速度 > 从库同步 + 回放速度

主库增删改并发过高,从库单线程 “接不住”
主库可多线程并发写入,从库默认单 SQL 线程回放;主库并发突破从库处理能力,延迟会持续累积。
可通过 Sysbench 压测复现:

sysbench --db-driver=mysql --mysql-host=192.168.184.151 --mysql-port=3306 --mysql-user='repl_rw' --mysql-password='Uda_dQc63' --mysql-db=sysbench_db --threads=4 --table_size=500000 --tables=4 --time=100 oltp_write_only prepare

大表 DDL 操作:元数据锁 + 同步机制导致延迟
ALTER TABLE 等 DDL 会生成元数据锁,主库执行完才写入 Binlog;从库单线程回放时,所有事务排队,延迟骤增。
建议:大表 DDL 优先用 Online DDL,或在业务低峰期执行。

从库备份:FLUSH TABLE 阻塞写入
mysqldump、xtrabackup 备份会触发FLUSH TABLES WITH READ LOCK,长时间持有锁会阻塞从库 SQL 线程,直接引发延迟。

大事务:从库单线程 “卡脖子”
主库可并发执行大事务,从库单线程必须等大事务完整回放才能处理后续事务;批量插入百万级数据,延迟会快速扩大。

从库硬件 “拖后腿”
从库 CPU、内存、磁盘 IO 配置低于主库,无法跟上主库 Binlog 生成速度,是最容易被忽略的底层瓶颈。

二、科学判断:3 种主从延迟检测方法(含 GTID 脚本)

避免单一指标误判,推荐组合使用以下方法:

  1. 基础指标:Seconds_Behind_Master
    从库执行show slave status\G,该值 > 0 代表有延迟;
    局限:网络异常时可能误判,无法查看落后事务数。
  2. 精准对比:基于位点的复制校验
    通过 4 个参数判断同步状态:
    • Master_Log_File:IO 线程读取的主库 Binlog 文件
    • Read_Master_Log_Pos:IO 线程读取的位点
    • Relay_Master_Log_File:SQL 线程执行的 Binlog 文件
    • Exec_Master_Log_Pos:SQL 线程执行的位点
      文件 / 位点不一致,说明 IO 或 SQL 线程未追平。
  3. 高效方案:基于 GTID 的事务数校验(生产首选)
    对比Retrieved_Gtid_SetExecuted_Gtid_Set,精准计算落后事务数。

实操:GTID 延迟检测脚本

1)主库创建监控用户

CREATE USER 'delay_check'@'%' IDENTIFIED BY 'Yd_asdfa15';
GRANT REPLICATION CLIENT ON *.* TO 'delay_check'@'%';
FLUSH PRIVILEGES;

2)从库编写脚本check_rel_delay.sh

#!/bin/bash
MYSQL_USER="delay_check"
MYSQL_PASS="Yd_asdfa15"
MYSQL_HOST="192.168.12.162"
MYSQL_PORT="3306"

while true; do
RETRIEVED=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -h${MYSQL_HOST} -P${MYSQL_PORT} -N -e "show slave status\G" | grep "Retrieved_Gtid_Set" | awk -F: '{print $3}' | awk -F- '{print $2}')
EXECUTED=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -h${MYSQL_HOST} -P${MYSQL_PORT} -N -e "show slave status\G" | grep "Executed_Gtid_Set" | awk -F: '{print $3}' | awk -F- '{print $2}')
DELAY=$((RETRIEVED - EXECUTED))
echo "$(date +'%Y-%m-%d %H:%M:%S') - 从库落后主库事务数:${DELAY}"
sleep 1
done

3)赋权并运行

chmod +x /data/script/check_rel_delay.sh
sh /data/script/check_rel_delay.sh

三、落地优化:6 种主从延迟解决方案

对症下药,以下方案可直接上线:

  1. 开启多线程复制(MTS)
    MySQL 5.7 + 推荐配置:
slave_parallel_workers=4
slave_parallel_type=LOGICAL_CLOCK
slave_preserve_commit_order=1

配置后重启 SQL 线程:

stop slave sql_thread; start slave sql_thread;
  1. 调整参数降低 IO 压力
    从库临时优化(平衡性能与安全):
set global innodb_flush_log_at_trx_commit=2;
set global sync_binlog=100;
  1. 升级从库硬件
    • CPU:与主库同规格
    • 内存:innodb_buffer_pool_size设为物理内存 50%~70%
    • 磁盘:更换 SSD 提升 IO 速度
  2. 拆分大事务
    单次操作控制在 1 万行内,避免长事务阻塞:
DELIMITER //
CREATE PROCEDURE batch_insert()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 100 DO
insert into sbtest1(k,c,pad) select k,c,pad from sbtest1 limit 10000;
COMMIT;
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
CALL batch_insert();
  1. 无锁 DDL:pt-online-schema-change
    避免大表 DDL 锁表延迟:
pt-online-schema-change D=sysbench_db,t=sbtest1 --alter="add column d char(10) after c" -u repl_rw -p Uda_dQc63 -h 192.168.12.161 --port 3306 --execute
  1. 架构分流:拆分专用从库
    大表单独同步,原从库忽略大表,彻底摆脱大表延迟影响。

四、总结:主从延迟处理核心原则

  1. 先定位原因:用 GTID 脚本 / 位点对比精准找到瓶颈(并发 / 大事务 / 硬件)。
  2. 平衡取舍:调参需兼顾性能与数据安全。
  3. 长期规范:拆分大事务、低峰期 DDL、开启多线程复制,从源头减少延迟。

掌握以上流程,就能稳定解决 MySQL 主从复制延迟,保障业务数据一致与高可用。

以上就是MySQL主从复制延迟原因分析、判断方法与优化方案的详细内容,更多关于MySQL主从复制延迟的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文