本文来自:http://www.woqutech.com/?p=1116

MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的复制延迟,但是 今天碰到了一个场景,发现 Seconds_Behind_Master 为 0 , 备库的 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 线程一切正常,复制延迟一直是 0 。

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

二、原理分析

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 设置的过小也有问题,这样会导致如果主库的变更确实比较少的时候,备库频繁的重新连接主库,造成资源浪费。

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

请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间【转】的更多相关文章

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

    链接:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的 ...

  2. mysql之 误用SECONDS_BEHIND_MASTER衡量MYSQL主备的延迟时间

    链接:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的 ...

  3. LVS+MYCAT+读写分离+MYSQL主备同步部署手册

    LVS+MYCAT+读写分离+MYSQL主备同步部署手册 1          配置MYSQL主备同步…. 2 1.1       测试环境… 2 1.2       配置主数据库… 2 1.2.1  ...

  4. 【转载】LVS+MYCAT+读写分离+MYSQL主备同步部署手册(邢锋)

    LVS+MYCAT+读写分离+MYSQL主备同步部署手册 1          配置MYSQL主备同步…. 2 1.1       测试环境… 2 1.2       配置主数据库… 2 1.2.1  ...

  5. mysql主备切换[高可用]

    到这一步的时候, 是主备部署已经处理好, 请关注:mysql主备部署[高可用] 这次使用的是keepalived-1.2.22.tar.gz版, 官网地址:keeplived官网 笼统知识请自行查询百 ...

  6. MySQL主备复制原理、实现及异常处理

    复制概述 MySQL支持三种复制方式:基于行(Row)的复制.基于语句(Statement)的复制和混合类型(Mixed)的复制. 基于语句的复制早在3.23版本中就存在,而基于行的复制方式在5.1版 ...

  7. LVS+Keepalived+Mysql+主备数据库架构[4台]

    这是一个坑...磨了不少时间.见证自己功力有待提升... 架构图 数据库 1.安装数据库 这块不难, 直接引用:mysql安装 2.数据库主备 这块不难, 直接引用: mysql主备 虚拟VIP 重点 ...

  8. mysql主备配置

    目录 mysql主备2 一.master配置:2 1. 修改配置文件 2 2. 登录添加账号并赋权限 2 3. 查看master信息 2 二.slave配置:2 1. 修改配置文件 2 2. 重启登录 ...

  9. mysql主备搭建

    mysql主备搭建参考文档https://www.cnblogs.com/clsn/p/8150036.html前提条件:系统:Ubuntu 16.04.6 LTSMySQL版本:5.7.24主库IP ...

随机推荐

  1. jQuery EasyUI API 中文文档 - ValidateBox验证框

    jQuery EasyUI API 中文文档 - ValidateBox验证框,使用jQuery EasyUI的朋友可以参考下.   用 $.fn.validatebox.defaults 重写了 d ...

  2. 【转载】linux lftp命令 详解

     站在前辈的肩上,别人会的你要尽快的学会练好!   lftp比ftp要好用,mget的时候,迹象要比较明显的迹象,比如下载进度!     linux lftp命令   1.登录ftp代码:lftp 用 ...

  3. linux 关机命令总结

    linux下常用的关机命令有:shutdown.halt.poweroff.init:重启命令有:reboot.下面本文就主要介绍一些常用的关机命令以及各种关机命令之间的区别和具体用法. 首先来看一下 ...

  4. linux的bash 终端操作快捷键

    bash中的快捷键操作: 分为两大类, 一是移动, 另一个是删除 一. 移动 1. 按字符移动: ctrl+f, ctrl+b 3. 按行移动: ctrl+a, ctrl+e 二. 删除: 1. 按字 ...

  5. PHP CLI下接受参数的几种方法

    PHP CLI(命令行模式下)接受参数有多种方法: (1)使用$argv接受参数 <?php //变量仅在 register_argc_argv 打开时可用. print_r($argc); / ...

  6. php防注入

    引发 SQL 注入攻击的主要原因,是因为以下两点原因: 1. php 配置文件 php.ini 中的 magic_quotes_gpc选项没有打开,被置为 off 2. 开发者没有对数据类型进行检查和 ...

  7. codevs4096 删数问题

    题目描述 Description 键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N 和S,寻找一种方案使得剩下的数字组成的新数最小. 输入 ...

  8. ggplo2学习笔记——基本图形类型

    1.散点图:又称散点分布图,是以一个变量为恨坐标,另一个变量为纵坐标,利用散点(坐标点)的分布形态反映变量统计关系的一种图形.可以用来确认两个变量之间的关系.绘制自由曲线.矩阵关联分析等. 2.条形图 ...

  9. Ruby中Block, Proc, 和Lambda

    Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...

  10. ZOJ 3201 Tree of Tree

    树形DP.... Tree of Tree Time Limit: 1 Second      Memory Limit: 32768 KB You're given a tree with weig ...