MySQL主从复制延迟从哪来
主从复制延迟会导致从库读到旧数据,高并发下业务会跟着出问题。延迟本质是从库IO线程或SQL线程处理跟不上主库产生的binlog。排查思路固定:先定位延迟卡在IO还是SQL,再针对性地调整复制模式与并行复制参数。
主从复制架构与半同步复制配置
经典架构:主库写binlog,从库IO线程拉binlog到本地relay log,SQL线程再回放。异步复制下主库不管从库收没收到,故障切换时可能丢数据;半同步复制要求主库至少等一个从库确认收到binlog才提交,可靠性更高:
# 主库启用半同步(5.7+/8.0)
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;
主库的延迟只到”至少一个从库确认”就返回,牺牲一点写入延迟换数据安全。超时值设1秒:超过则退回异步模式继续服务,避免主库被拖死。
复制延迟排查:Seconds_Behind_Master与线程状态解读
先看延迟量级和两个线程状态:
SHOW SLAVE STATUS\G
# 关注:
# Slave_IO_Running: Yes —— IO线程正常拉binlog
# Slave_SQL_Running: Yes —— SQL线程正常回放
# Seconds_Behind_Master: 5
Seconds_Behind_Master只是估算值,主从时钟偏差、大事务回放都会导致失真。更可靠的方式:对比主从执行到的事件坐标(Relay_Master_Log_File + Exec_Master_Log_Pos)。
若IO线程一直卡在拉取,查网络与磁盘IO;若SQL线程追赶慢,方向是加大并行回放能力,见下一步。
并行复制(MTS)参数调优与从库写入优化
MySQL 8.0默认按数据库并行回放,跨库事务仍然串行。想提升从库回放速度,调整:
# 从库 my.cnf
slave_parallel_type = LOGICAL_CLOCK # 8.0默认,按事务提交顺序并行
slave_parallel_workers = 16
LOGICAL_CLOCK模式下,主库同一组内提交的事务可以在从库并行执行,通常能匹配大部分OLTP负载。配合下面两点效果更好:
- 从库只读:read_only=1,杜绝业务直写从库(否则SQL线程与业务写并发冲突,延迟飙升)
- 控制大事务:单事务更新几百万行的语句尽量拆批,大事务回放久且容易拖垮从库
主库binlog写入优化与一致性保证
主库的binlog落盘策略直接影响整体延迟:
sync_binlog = 1
binlog_group_commit_sync_delay = 1000 # 微秒,抖动容忍
binlog_group_commit_sync_no_delay_count = 5
sync_binlog=1保证每次事务都落盘,为强一致;若追求吞吐可调0,但故障可能丢binlog。生产一般双1(sync_binlog=1 + innodb_flush_log_at_trx_commit=1)最稳,性能不够再考虑组提交参数。
复制监控与故障切换演练
把复制状态接入监控(如pt-heartbeat或Prometheus mysqld_exporter),延迟超过阈值告警。每月做一次主从切换演练:停主库写、提升从库、应用切连接,确认切换耗时在分钟级内。演练跑通,真出故障时才不用赌运气。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/mysql-zhu-cong-fu-zhi-yan-chi-pai-cha-shi-zhan-ban-tong-bu/