前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【MySQL】IO thread和SQL thread的双Yes假象的问题

【MySQL】IO thread和SQL thread的双Yes假象的问题

作者头像
用户5522200
发布2019-06-02 15:18:25
1K0
发布2019-06-02 15:18:25
举报
文章被收录于专栏:lindalinda

1、首先讨论一下哪些现象造成:IO thread和SQL thread的双Yes假象的问题

① 正常shutdown 或者 kill mysqld

结果状态单:

代码语言:javascript
复制
         Slave_IO_Running: Connecting
        Slave_SQL_Running: Yes
            Last_IO_Errno: 2003

② kill -9 mysqld 或者 reboot 服务器 结果状态:有可能同①,也有可能是双Yes(我自己测试的是同①结果,看别人测的有的是双yes)

③ 临时断开主库的网络,并 kill 掉主库 MySQL 的 binlog dump 线程

结果状态单:

代码语言:javascript
复制
          Slave_IO_Running: Yes
         Slave_SQL_Running: Yes

说明: 网络恢复之后,binlog dump线程已不存在; 主库有新的写入,从库无法同步,但是I/O线程和SQL线程都是YES,SBM也没有延迟

2、主从同步机制

主库上记录二进制日志,也就是binlog日志。 备库将主库的二进制日志复制到其本地的中继日志中。首先,备库会启动一个工作线程,称为I/O线程,I/O线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转存(Binglog Dump)线程,这个转存线程会读取主库上的二进制日志中事件,并发送给从库的I/O线程;如果主库没有更新信息将进入休眠。 备库的SQL线程执行最后一步,该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。

3 binlog‘推’还是‘拉’

首先, MySQL 的复制是“推”的,而不是“拉”的。“拉”是指 MySQL 的备库不断的循环询问主库是否有数据更新,这种方式资源消耗多,并且效率低。“推”是指 MySQL 的主库在自己有数据更新的时候推送这个变更给备库,这种方式只有在数据有变更的时候才会发生交互,资源消耗少。如果你是程序员出身,你一定会选择“推”的方式。 那么 MySQL 具体是怎么“推”的列,实际上备库在向主库申请数据变更记录的时候,需要指定从主库Binlog 的哪个文件 ( MASTER_LOG_FILE ) 的具体多少个字节偏移位置 ( MASTER_LOG_POS ) 。对应的,主库会启动一个 Binlog dump 的线程,将变更的记录从这个位置开始一条一条的发给备库。备库一直监听主库过来的变更,接收到一条,才会在本地应用这个数据变更。

4 原因解析

从上面的分析,我们可以大致猜到为什么 show slave status 显示一切正常,但是实际上主库的变更都无法同步到备库上来: 出现问题的时候, Binlog dump 程序被我们 kill 掉了。作为监听的一方,备库一直没有收到任何变更,它会认为主库上长时间没有任何变更,导致没有变更数据推送过来。备库是无法判断主库上对应的Binlog dump 线程到底是意外终止了,还是长时间没有任何数据变更的。所以,对这两种情况来说,备库都显示为正常。 当然, MySQL 会尽量避免这种情况。比如: a.在 Binlog dump 被 kill 掉时通知备库 线程 被 kill 掉了。所以我们重现时需要保证这个通知发送不到备库,也就是说该问题重现的关键在于 Binlog dump 被 kill 的消息由于网络堵塞或者其他原因无法发送到备库。 b.备库如果长时间没有收到从主库过来的变更,它会每隔一段时间重连主库。

5 问题避免

基于上面的分析,我们知道 MySQL 在这种情况下确实无法避免,那么我们可以有哪些办法可以避开: (1) 被动处理:修改延迟的监控方法,发现问题及时处理。 (2) 主动预防:正确设置 --master-retry-count , --master-connect-retry , --slave-net-timeout 复制重试参数。

被动处理

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

主动预防

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、首先讨论一下哪些现象造成:IO thread和SQL thread的双Yes假象的问题
  • 2、主从同步机制
  • 3 binlog‘推’还是‘拉’
  • 4 原因解析
  • 5 问题避免
    • 被动处理
      • 主动预防
      相关产品与服务
      云数据库 SQL Server
      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档