如何解决 MySQL 主从延时问题?

发布时间:2026/9/2 16:30:23
如何解决 MySQL 主从延时问题? MySQL 主从延时的原因是什么具体哪个环节发生延时如何解决呢对于这“三连问”极少有同学能通关甚至有同学连主从复制原理都不清楚。这个并不是存粹的八股文因为在实际工作场景中很多同学都遇到过。不 BB上文章目录。01 什么是主从延时有时候我们遇到从数据库中获取不到信息的诡异问题时会纠结于代码中是否有一些逻辑会把之前写入的内容删除但是你又会发现过了一段时间再去查询时又可以读到数据了这基本上就是主从延迟在作怪。主从延迟其实就是“从库回放” 完成的时间与 “主库写 binlog” 完成时间的差值会导致从库查询的数据和主库的不一致。02 为什么会主从延时探讨这个问题前我们需要知道主从复制的原理。2.1 主从复制原理MySQL 的主从复制是依赖于 binlog也就是记录 MySQL 上的所有变化并以二进制形式保存在磁盘上二进制日志文件。主从复制就是将 binlog 中的数据从主库传输到从库上一般这个过程是异步的即主库上的操作不会等待 binlog 同步地完成。详细流程如下主库写 binlog主库的更新 SQL(update、insert、delete) 被写到 binlog主库发送 binlog主库创建一个 log dump 线程来发送 binlog 给从库从库写 relay log从库在连接到主节点时会创建一个 IO 线程以请求主库更新的 binlog并且把接收到的 binlog 信息写入一个叫做 relay log 的日志文件从库回放从库还会创建一个 SQL 线程读取 relay log 中的内容并且在从库中做回放最终实现主从的一致性。2.2 主从延时原因我们分析一下主从复制的过程。MySQL 的主从复制都是单线程的操作主库对所有 DDL 和 DML 产生 binlogbinlog 是顺序写所以效率很高。Slave 的 Slave_IO_Running 线程会到主库取日志放入 relay log效率会比较高。Slave 的 Slave_SQL_Running 线程将主库的 DDL 和 DML 操作都在 Slave 实施DML 和 DDL 的 IO 操作是随机的不是顺序的因此成本会很高。还可能是 Slave 上的其他查询产生 lock 争用由于 Slave_SQL_Running 也是单线程的所以一个 DDL 卡住了需要执行 10 分钟那么所有之后的 DDL 会等待这个 DDL 执行完才会继续执行这就导致了延时。总结一下主从延迟的主要原因主从延迟主要是出现在 “relay log 回放” 这一步当主库的 TPS 并发较高产生的 DDL 数量超过从库一个 SQL 线程所能承受的范围那么延时就产生了当然还有就是可能与从库的大型 query 语句产生了锁等待。03 如何解决主从延时3.1 主从延迟情况我们先看看哪些情况会导致主从延时从库机器性能从库机器比主库的机器性能差只需选择主从库一样规格的机器就好。从库压力大可以搞了一主多从的架构还可以把 binlog 接入到 Hadoop 这类系统让它们提供查询的能力。从库过多要避免复制的从节点数量过多从库数据一般以3-5个为宜。大事务如果一个事务执行就要 10 分钟那么主库执行完后给到从库执行最后这个事务可能就会导致从库延迟 10 分钟啦。日常开发中不要一次性 delete 太多 SQL需要分批进行另外大表的 DDL 语句也会导致大事务。网络延迟优化网络比如带宽 20M 升级到 100M。MySQL 版本低低版本的 MySQL 只支持单线程复制如果主库并发高来不及传送到从库就会导致延迟可以换用更高版本的 MySQL支持多线程复制。3.2 主从延时解决方案面试时有些同学能回答出使用缓存、查询主库、提升机器配置等仅仅这些么最容易想到的方法缩短主从同步时间提升从库机器配置可以和主库一样甚至更好避免大事务搞多个从库即一主多从分担从库查询压力优化网络宽带选择高版本 MySQL支持主库 binlog 多线程复制。也可以从业务场景考虑使用缓存我们在同步写数据库的同时也把数据写到缓存查询数据时会先查询缓存不过这种情况会带来 MySQL 和 Redis 数据一致性问题。查询主库直接查询主库这种情况会给主库太大压力核心场景可以使用比如订单支付。如果能把上面基本回答出来就已经非常厉害了还有么其实还可以在 MySQL 架构上来考虑。主库对数据安全性较高设置配置如下sync_binlog 1 innodb_flush_log_at_trx_commit 1而 slave 不需要这么高的数据安全完全可以将 sync_binlog 设置为 0或者关闭 binloginnodb_flushlog 也可以设置为 0来提高 sql 的执行效率。架构方案使用多台 slave 来分摊读请求再从这些 slave 中取一台专用的服务器只作为备份用不进行其他任何操作比如设置 sync_binlog 为0或者关闭 binglog 等提升从库查询性能。