请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的复制延迟,但是今天碰到了一个场景,发现 Seconds_Behind_Master 为 0 , 备库的 show slave status 显示 IO/SQL 线程都是正常的 , MySQL 的主库上的变更却长时间无法同步到备库上。

MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的复制延迟,但是今天碰到了一个场景,发现 Seconds_Behind_Master 为 , 备库的 show slave status 显示 IO/SQL 线程都是正常的 , MySQL 的主库上的变更却长时间无法同步到备库上。如果没有人为干预,直到一个小时以后, MySQL 才会自动重连主库,继续复制主库的变更。

影响范围: MySQL , Percona , MariaDB 的所有版本。


虽然这种场景非常特殊,遇到的概率并不高,但是个人觉得有必要提醒一下使用 MySQL 的 DBA 们。通过对这个场景的分析,也有助于我们更加深入的理解 MySQL replication 重试机制。


   一、重现步骤

搭建主备的复制,临时断开主库的网络,并 kill 掉主库 MySQL 的 binlog dump 线程。

此时观察备库的复制情况, show slave status 中:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Seconds_Behind_Master: 0

但是此时你把网络恢复以后,在主库做任何变更,备库都无法获得数据更新了。而且备库上的show slave status 显示: IO 线程 SQL 线程一切正常,复制延迟一直是 

一切正常,普通的监控软件都不会发现备库有数据延迟。


   二、原理分析

MySQL 的 Replication 是区别于其他数据库很关键的地方。也是可扩展性和高可用的基础。它本身已经非常智能化,只需要我们调用 Change Master 指定 Binlog 文件名和偏移位置就可以搭建从主库到备库的复制关系。

MySQL 复制 线程 会自动将目前复制位置记录下来,在主备复制中断的时候自动连上主库,并从上次中断的位置重新开始复制。这些操作都是全自动化的,不需要人为的干预。这给了 MySQL DBA 带来了很多便利,同时却也隐藏了很多细节。

要真正的理解前面问题的真相以及怎么解决这个问题,我们还是需要真正的理解 MySQL  复制的原理。


   2.1“推”还是“拉”

首先, MySQL 的复制是“推”的,而不是“拉”的。“拉”是指 MySQL 的备库不断的循环询问主库是否有数据更新,这种方式资源消耗多,并且效率低。“推”是指 MySQL 的主库在自己有数据更新的时候推送这个变更给备库,这种方式只有在数据有变更的时候才会发生交互,资源消耗少。如果你是程序员出身,你一定会选择“推”的方式。

那么 MySQL 具体是怎么“推”的列,实际上备库在向主库申请数据变更记录的时候,需要指定从主库Binlog 的哪个文件 MASTER_LOG_FILE 的具体多少个字节偏移位置 MASTER_LOG_POS 。对应的,主库会启动一个 Binlog dump 的线程,将变更的记录从这个位置开始一条一条的发给备库。备库一直监听主库过来的变更,接收到一条,才会在本地应用这个数据变更。


   2.2 原因解析

从上面的分析,我们可以大致猜到为什么 show slave status 显示一切正常,但是实际上主库的变更都无法同步到备库上来:

出现问题的时候, Binlog dump 程序被我们 kill 掉了。作为监听的一方,备库一直没有收到任何变更,它会认为主库上长时间没有任何变更,导致没有变更数据推送过来。备库是无法判断主库上对应的Binlog dump 线程 到底是意外终止了,还是长时间没有任何数据变更的。所以,对这两种情况来说,备库都显示为正常。

当然, MySQL 会尽量避免这种情况。比如:

l  在 Binlog dump 被 kill 掉时通知备库 线程 被 kill 掉了。所以我们重现时需要保证这个通知发送不到备库,也就是说该问题重现的关键在于 Binlog dump 被 kill 的消息由于网络堵塞或者其他原因无法发送到备库。

l  备库如果长时间没有收到从主库过来的变更,它会每隔一段时间重连主库。


   2.3 问题避免

基于上面的分析,我们知道 MySQL 在这种情况下确实无法避免,那么我们可以有哪些办法可以避开列:

1.  被动处理:修改延迟的监控方法,发现问题及时处理。

2.  主动预防:正确设置 --master-retry-count ,  --master-connect-retry ,  --slave-net-timeout 复制重试参数。


l  被动处理

MySQL 的延迟监控大部分直接采集 show slave status 中的  Seconds_Behind_Master 。这种情况下,Seconds_Behind_Master 就无法用来真实的衡量主备之间的复制延迟了。我们建议通过在主库轮询插入时间信息,并通过复制到备库的时间差来获得主备延迟的方案。 Percona 提供了一种类似的方案 pt-heartbeat 

发现这个问题以后,我们只需要 stop slave; start slave; 重启复制就能解决这个问题。


l  主动预防

MySQL 可以指定三个参数,用于复制线程重连主库: --master-retry-count ,  --master-connect-retry ,  --slave-net-timeout 

其中 master-connect-retry 和 master-retry-count 需要在 Change Master 搭建主备复制时指定,而 slave-net-timeout 是一个全局变量,可以在 MySQL 运行时在线设置。

具体的重试策略为:备库过了 slave-net-timeout 秒还没有收到主库来的数据,它就会开始第一次重试。然后每过 master-connect-retry 秒,备库会再次尝试重连主库。直到重试了 master-retry-count 次,它才会放弃重试。如果重试的过程中,连上了主库,那么它认为当前主库是好的,又会开始 slave-net-timeout 秒的等待。

slave-net-timeout 的默认值是 3600 秒, master-connect-retry 默认为 60 秒, master-retry-count 默认为 86400 次。也就是说,如果主库一个小时都没有任何数据变更发送过来,备库才会尝试重连主库。这就是为什么在我们模拟的场景下,一个小时后,备库才会重连主库,继续同步数据变更的原因。

这样的话,如果你的主库上变更比较频繁,可以考虑将 slave-net-timeout 设置的小一点,避免主库Binlog dump 线程 终止了,无法将最新的更新推送过来。

当然 slave-net-timeout 设置的过小也有问题,这样会导致如果主库的变更确实比较少的时候,备库频繁的重新连接主库,造成资源浪费。

沃趣科技的 Monitor 监控中对主备复制的延迟监控,并不是通过 Seconds_Behind_Master 来监控主备的。它采用了类似于 pt-heartbeat 的方式对主备进行复制延迟监控。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
SQL 运维 关系型数据库
如何对比MySQL主备数据的一致性?
如何在数据库世界中处理大批量数据变更操作,而不影响业务运行。NineData的OnlineDML解决方案通过无锁方式实现数据变更,确保在线业务的顺畅运行。只需两步操作即可开启OnlineDML功能,让NineData自动处理大型DML操作,分批执行并根据数据库压力进行智能调整,简化操作流程并提供直观操作界面。
366 2
如何对比MySQL主备数据的一致性?
|
6月前
|
SQL 监控 关系型数据库
MySQL 如何保证主备的数据一致性的?
MySQL通过使用主从复制(Master-Slave Replication)来实现主备的数据一致性。主从复制是一种常见的数据复制技术,它将一个MySQL数据库服务器(主服务器)的数据复制到一个或多个其他MySQL数据库服务器(从服务器),以实现数据的冗余备份、读写分离等目的。以下是MySQL保证主备数据一致性的一些关键点: 1. **二进制日志(Binary Log)**:主服务器将所有的数据更改操作(如INSERT、UPDATE、DELETE)以二进制日志的形式记录下来,并定期将这些日志发送给从服务器。从服务器收到二进制日志后,按照主服务器的执行顺序逐条应用这些日志,从而保持数据的一致性
1205 0
|
SQL 存储 关系型数据库
京东二面:MySQL 主备延迟有哪些坑?主备切换策略
一、什么是高可用? 维基百科定义: 高可用性(high availability,缩写 HA),指系统无中断地执行其功能的能力,代表系统的可用性程度。高可用性通常通过提高系统的容错能力来实现。 MySQL 的高可用是如何实现的呢?
|
6月前
|
存储 监控 关系型数据库
mysql 主备延迟的原因及解决思路,优化方法
MySQL 主备延迟(replication delay)是指主服务器(master)上的数据更新操作与备服务器(slave)上相同数据更新操作之间的时间差。这种延迟可能会导致数据不一致,影响系统的可用性和可靠性。以下是主备延迟的常见原因、解决思路和优化方法: ### 常见原因 1. **网络延迟**:主备服务器之间的网络不稳定或带宽不足。 2. **硬件性能**:备服务器的硬件性能不足,如 CPU、内存、磁盘 I/O 等。 3. **大量数据写入**:主服务器上的大量数据写入操作导致备服务器难以同步。 4. **复杂的查询**:备服务器执行复杂的查询操作,影响同步速度。 5. **二进制
417 0
|
数据采集 关系型数据库 MySQL
【MySQL】你还不会在Docker下安装MySQL主备吗?
那什么时候就要开始考虑搭建主备架构呢, 一方面是随着业务增长,读写请求已经到达了一定的瓶颈时,我们需要考虑,另一方面为了保证数据的完整性,以保证主宕机的时候,可以快速切换。
|
SQL 负载均衡 监控
关于Linux下MySQL主备集群负载均衡之读写分离(MaxScale)的一些记笔
分享一些MySQL(MariaDB)集群主从结构数据读写分离的笔记,关于读写分离: 一如果对于读密集型应用,可以容忍从库异步复制延迟导致的脏数据,读写分离是一种不错的负载均衡方式 如果对于脏数据零容忍,不建议这样搞,出了故障还需要考虑这个因素,不太方便定位问题 二是读写分离需要做体量评估,不能为了读写分离去读写分离,系统负载正常,完全没必要,如果扩了资源还是频繁的sql timeout,读写分离是解决方法之一 博文偏实战,内容涉及: 为什么需要负载均衡? MaxScale配置主从集群的读写分离 食用方式:了解Linux,MySQL 理解不足小伙伴帮忙指正
526 0
关于Linux下MySQL主备集群负载均衡之读写分离(MaxScale)的一些记笔
|
关系型数据库 MySQL Linux
Mysql主从复制与高可用主备切换搭建完整详细版
Mysql主从复制与高可用主备切换搭建完整详细版
|
Cloud Native 关系型数据库 分布式数据库
PolarDB-X 1.0-用户指南-私有RDS管理-主备切换
您可以设置主备实例切换,切换后原来的主实例会变成备实例。
197 0
PolarDB-X 1.0-用户指南-私有RDS管理-主备切换
|
关系型数据库 MySQL 数据库
MySQL主备模式的数据一致性解决方案
数据一致性对于在线业务的重要性不言而喻,本专题系列,主要从阿里巴巴“去IOE”的后时代讲起,来看下阿里巴巴数据库在数据一致性解决方案
2304 0
|
SQL MySQL 关系型数据库
MySQL备份与主备配置
本文详细讲述了如何进行 MySQL 的全量备份、增量备份、主从备份、双主备份以及如何通过 binlog 对误操作数据进行恢复,包含大量代码和截图。
1745 0