解决 MySQL 主从延时问题

 更新时间:2026年09月04日 09:20:58   作者:程序员托尼  
本文主要介绍了解决 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 产生 binlog,binlog 是顺序写,所以效率很高。

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,或者关闭 binlog,innodb_flushlog 也可以设置为 0,来提高 sql 的执行效率。

架构方案:使用多台 slave 来分摊读请求,再从这些 slave 中取一台专用的服务器,只作为备份用,不进行其他任何操作,比如设置 sync_binlog 为0,或者关闭 binglog 等,提升从库查询性能。

到此这篇关于解决 MySQL 主从延时问题的文章就介绍到这了,更多相关MySQL 主从延时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • MySQL数据库中的嵌套查询实例详解

    MySQL数据库中的嵌套查询实例详解

    这篇文章主要给大家介绍了关于MySQL数据库中嵌套查询的相关资料,嵌套查询是SQL中的一种技术,允许在一个查询语句的某个部分嵌入另一个查询,它主要用于处理复杂的逻辑,如多层条件过滤和数据对比,需要的朋友可以参考下
    2024-12-12
  • mysql8.0.19忘记密码处理方法详解

    mysql8.0.19忘记密码处理方法详解

    这篇文章主要介绍了mysql8.0.19忘记密码处理方法详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • MySQL无法启动几种常见问题小结

    MySQL无法启动几种常见问题小结

    在群里看到有新同学还在问MySQL无法启动的问题,于是总结了几个常见情况与解决方法,需要的朋友可以参考下
    2013-09-09
  • MySQL中的约束Constraint解读

    MySQL中的约束Constraint解读

    这篇文章详细介绍了MySQL中的各种约束类型,包括非空约束、默认约束、检查约束、唯一约束和主键约束,以及外键约束,每种约束类型都有其特定的用途和语法,并且可以是列级约束或表级约束,文章还探讨了如何给约束命名、删除约束
    2025-01-01
  • 把MySQL卸载干净的超详细步骤

    把MySQL卸载干净的超详细步骤

    这篇文章主要介绍了把MySQL卸载干净的超详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考价值,需要的朋友们下面跟着小编来一起学习吧
    2024-02-02
  • Mysql ID生成策略的三种方法选择及优缺点

    Mysql ID生成策略的三种方法选择及优缺点

    mysql ID生成策略一般常用的有三种,包括自增、UUID 以及雪花算法,本文主要介绍了Mysql ID生成策略的三种方法选择及优缺点,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • Linux下启动多个mysql服务器例子

    Linux下启动多个mysql服务器例子

    这篇文章主要介绍了Linux下启动多个mysql服务器例子,本文还包括了3个可能遇到的问题及解决方法,需要的朋友可以参考下
    2014-07-07
  • 如何清除mysql注册表

    如何清除mysql注册表

    在本篇文章里小编给大家整理的是关于如何清除mysql注册表的相关知识点内容,有需要的朋友们可以参考下。
    2020-08-08
  • CentOS 7中源码安装MySQL 5.7.6+详细教程

    CentOS 7中源码安装MySQL 5.7.6+详细教程

    最近在CentOS 7中源码安装MySQL 5.7.6+,发现MySQL5.7.6+以后的安装方式真的与以前版本的MySQL安装方式大大的不同呀。不自己安装一把,你都不知道不同之处在哪,下面这篇文章是通过自己的安装过程总结的一篇安装教程,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • Ubuntu系统安装mysql超详细步骤

    Ubuntu系统安装mysql超详细步骤

    这篇文章主要给大家介绍了关于Ubuntu系统安装mysql的相关资料,现在的软件越来越好安装,尤其是在ubuntu下安装软件,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-09-09

最新评论