主库写入压力导致从库单线程SQL回放瓶颈是延迟主因;应启用LOGICAL_CLOCK多线程复制、调大workers数,并避免长事务;需严格事务路由、监控binlog位点差值、预防断连与数据不一致。

主库写入时从库延迟高,Seconds_Behind_Master 一直涨
根本原因不是网络或硬件,而是主库的写入压力直接转化为从库的单线程 SQL 线程回放瓶颈。MySQL 5.6+ 支持基于库(slave_parallel_type=DATABASE)或多线程(slave_parallel_type=LOGICAL_CLOCK),但默认仍是单线程复制。
- 确认当前模式:
SHOW VARIABLES LIKE 'slave_parallel_type';,若为DATABASE,需确保业务表严格分库(否则并行无效) - 推荐改用
LOGICAL_CLOCK(MySQL 5.7+ 默认),同时调大slave_parallel_workers(如设为 4 或 8) - 注意:启用多线程后,
Seconds_Behind_Master的语义会变——它只反映 coordinator 线程和最慢 worker 的差距,不代表所有事务都已应用 - 避免在主库执行超长事务(如单条
UPDATE扫描千万行),这类事务会阻塞整个并行队列
应用层路由读请求到从库,但偶尔读到旧数据
这不是“最终一致性”的合理表现,而是没处理好事务边界和读写分离中间件的感知能力。主从延迟天然存在,但事务内刚写完就立刻读,必须走主库。
- 不要依赖“写完 sleep(1) 再读”这种不可靠方式;
sleep无法覆盖网络抖动或突发延迟 - 在应用中明确标记事务上下文:比如 Spring 的
@Transactional方法内所有 DB 操作强制走主库 - 如果用 MyCat 或 ShardingSphere,检查其
master-slave规则是否支持/*+ FORCE_MASTER */这类 hint 注释;没有的话,得在代码里显式获取主数据源 - 监控
SHOW SLAVE STATUS\G中的Exec_Master_Log_Pos和主库SHOW MASTER STATUS的Position差值,比Seconds_Behind_Master更准
新增从库时 CHANGE MASTER TO 报错 Got fatal error 1236
这是典型的 binlog 位置不匹配,主库的 binlog 文件已被清理,而从库还想从一个不存在的位置拉取日志。
- 先查主库保留了哪些 binlog:
SHOW BINARY LOGS;,再看从库报错里提到的文件名是否还在列表中 - 如果不在,不能硬改
CHANGE MASTER TO MASTER_LOG_FILE指向一个新文件——那会丢数据;必须重做从库:用mysqldump --single-transaction --master-data=2导出,或更优的物理备份(xtrabackup) - 预防措施:调大主库
expire_logs_days(建议至少 7 天),并定期检查从库复制状态(Seconds_Behind_Master > 300就告警) - 注意
--master-data=2会在 dump 文件里写死CHANGE MASTER TO语句,恢复时别漏掉source它
一主三从,其中一台从库频繁断连又自动重连
表面是网络问题,实际大概率是主库连接数打满或从库 I/O 线程卡在磁盘写入上。自动重连(MASTER_AUTO_POSITION=1 + CHANGE MASTER TO ... AUTO_POSITION = 1)掩盖了底层资源不足。
- 查主库
SHOW PROCESSLIST里有没有大量Binlog Dump状态的线程,若有且数量接近max_connections,说明主库扛不住了 - 查从库磁盘 IO:用
iostat -x 1看%util是否长期 100%,尤其是await高说明磁盘响应慢 - 从库参数要调优:
innodb_flush_log_at_trx_commit=2(接受短时崩溃丢失)、sync_binlog=0(不强制刷盘),降低写入压力 - 别把所有从库都设成
read_only=0——万一误操作写入,后续主从数据会彻底不一致,且很难发现


















