起因:

测试公司的保障MySQL高可用组件时发现一个异常。

停止从库,高可用组件将从库自动启动后,主库发生重启。而正常情况下主库不应发生重启。

环境:

  1. OS: CentOS release 6.7 (Final)
  2. MySQL:Ver 14.14 Distrib 5.7.13, for linux-glibc2.5 (x86_64) using EditLine wrapper
  3. 主从实例开启半同步 MySQL semi-sync配置文档

分析:

首先,先分析log文件

在主库的mysql-error.log中我们可以发现如下几点:

1. 主库的semi-sync在崩溃前做了启停动作。

2017-07-25T16:02:38.636061+08:00 40 [Note] Semi-sync replication switched OFF.2017-07-25T16:02:38.636105+08:00 40 [Note] Semi-sync replication disabled on the master.2017-07-25T16:02:38.636137+08:00 0 [Note] Stopping ack receiver thread2017-07-25T16:02:38.638008+08:00 40 [Note] Semi-sync replication enabled on the master.2017-07-25T16:02:38.638131+08:00 0 [Note] Starting ack receiver thread

2. 主库的semi-sync启动后立即引发了semi-sync插件崩溃,并抛出Assert异常。

mysqld: /export/home/pb2/build/sb_0-19016729-1464157976.67/mysql-5.7.13/plugin/semisync/semisync_master.cc:844: int ReplSemiSyncMaster::commitTrx(const char*, my_off_t): Assertion `entry' failed.08:02:38 UTC - mysqld got signal 6 ;

3. 这里还有一个相当重要的复现故障的线索。简单说明一下,这条SQL语句是为了检测主从数据差,而由高可用中间件不断的向数据库更新时间戳。

Trying to get some variables.Some pointers may be invalid and cause the dump to abort.Query (7f408c0054c0): update universe.u_delay set real_timestamp=now(), logic_timestamp = logic_timestamp + 1 where source = 'ustats'Connection ID (thread ID): 61Status: NOT_KILLED

到这里初步判断是这个故障应与设置rpl_semi_sync_master_enabled开关相关,并且应该当时是有事务提交的。

进一步验证,这里只部署一组开启semi-sync的MySQL实例,而不安装高可用组件。利用bash脚本向主库不断插入数据:

/opt/mysql/base/bin/mysql -uroot -p1 -S /opt/mysql/data/3306/mysqld.sock -e "create database if not exists test;use test;drop table if exists t1;create table t1(id int) "

i=0

while true

do

/opt/mysql/base/bin/mysql -uroot -p1 -S /opt/mysql/data/3306/mysqld.sock -e "insert into test.t1 values($i)"

i=$((i+1))

done

在主库的机器上,反复运行如下命令,启停semi-sync master,不超过5次必能复现这个故障。

/opt/mysql/base/bin/mysql -uroot -p1 -S /opt/mysql/data/3306/mysqld.sock -e'SET GLOBAL rpl_semi_sync_master_enabled = OFF;SET GLOBAL rpl_semi_sync_master_enabled = ON'

所以这个故障复现有了两个必要条件:

  1. 启停semi-sync master
  2. 数据库当时有事务提交

其次,分析MySQL源码

至于为什么不能每次启停semi-sync master都能触发这个故障,那我们就要看看MySQL的源码了

还好mysql-error.log明确的指出了抛出异常的位置:

mysqld: /export/home/pb2/build/sb_0-19016729-1464157976.67/mysql-5.7.13/plugin/semisync/semisync_master.cc:844: int ReplSemiSyncMaster::commitTrx(const char*, my_off_t): Assertion `entry' failed.08:02:38 UTC - mysqld got signal 6 ;This could be because you hit a bug. It is also possible that this binaryor one of the libraries it was linked against is corrupt, improperly built,or misconfigured. This error can also be caused by malfunctioning hardware.Attempting to collect some information that could help diagnose the problem.As this is a crash and something is definitely wrong, the informationcollection process might fail.

找到MySQL源码,抛出异常的的位置 mysql-5.7.13 semisync_master.cc#L844

看来是这个‘entry’的值为NULL,才抛出的异常,但是这还没有回答我的疑问。

再看MySQL的报错信息,MySQL自己也认识到这应该是个BUG,那它有没有修复这个故障呢?

我找到MySQL最新5.7.19的版本,查看它的历史记录mysql-5.7.19 semisync_master.cc history

这正是我想要的修复和提交,打开看看有没有对产生故障原因的分析。Bug#22202516: ENABLING SEMI-SYNC DURING COMMIT CAN CAUSE MASTER TO ASSERT.

为了方便解释这个BUG, 这里先简单的介绍一下MySQL binlog提交过程:

MySQL 在5.6版本引入了Binary Log Group Commit,二进制日志的提交由此可以简化为三个阶段:

Flush stage:将事务的日志写入binlog文件的缓存中

Sync stage: 将binlog文件中的缓存数据写入磁盘

Commit stage:根据顺序调用存储引擎提交事务。

MYSQL_BIN_LOG::ordered_commit,这个是事务在binlog阶段提交的核心函数。通过该函数,实现了事务日志写入binlog文件,以及触发dump线程将binlog发送到从库,在最后将事务设置为提交状态。

事实上,有没有semi-sync机制,上面介绍的MySQL的有关事务提交中关于binlog的流程都是一样的。semi-sync的作用只是主从之间的一个确认过程,主库等待从库返回相关位置的binlog已经同步到从库的确认,没有得到确认之前,事务提交则在该函数(步骤)上等待直至获得返回。

在半同步复制中,为了在主库提交事务时等待从库的确认,才引出了由‘entry’组成的active transaction链表。

在BUG分析中提到:

  • 首先在flush stage,由semi-sync创建一个‘entry’,并关联一个或一组处于flush stage的事务。这个‘entry’被插入一个active transaction链表。 参考: create entry

搜图

编辑

  • 接下来是sync stage,在sync stage每个处于这个阶段的线程将会设置trx_wait_binlog_name和trx_wait_binlog_pos为事务对应binlog的相对位置
  • 最后再commit stage,semi-sync为了等从库的确认,会用trx_wait_binlog_name和trx_wait_binlog_pos获取这个位置关联的'entry', 参考: find entry

这里有两个场景会出现‘entry’找不到的状况:

1. 从库已经确认的事务在binlog位置比当前等待从库确认的事务在binlog的位置要大

2. 当事务进入flush stage的时候semi-sync还没有开启,也就没有‘entry’被创建,然后插入active transaction链表

这里情况1永远也不会进入等待阶段,因为它已经被从库确认过了。情况2则会导致上述的断言异常,因为这里他无法在active transaction链表找到相应的’entry‘

到这里我的疑问终于解开,原来开启semi-sync master的时机很重要,要恰巧撞到事务提交过了flush stage但还没有到commit stage这个缝隙

结论:

最终修复的结果也很明显,就是遇到找不到‘entry’,并且从库也没有确认的情况,这个事务提交就被认为是一次异步提交。

再看一眼在哪些版本修复了这个BUG:

所以升级MySQL版本可以解决问题。

复盘:

最后总结一下我的诊断路径:

  1. 观察故障出现的现象,分析MySQL的error log
  2. 通过猜想和实验,构成简单的复现场景
  3. 通过日志和MySQL源码的对应关系, 搜索代码历史, 定位BUG号
  4. 通过阅读BUG的分析,了解异常发生的原理并知道了详细的复现条件

崩溃重启_semi-sync插件崩溃导致MySQL重启的故障分析-爱可生相关推荐

  1. mysql function_MySQL里event_ scheduler导致复制中断的故障分析-爱可生

    问题背景 在5.6.29和5.7.11版本之前,当binlog格式设置成mixed时,创建event事件中包含sysdate函数时,会导致复制中断. 与此bug相关:https://bugs.mysq ...

  2. mysql insert 错误码_利用 MySQL 自身错误诊断区域-爱可生

    原标题:利用 MySQL 自身错误诊断区域-爱可生 背景 本篇文章来源于今天客户问的一个问题. 问题大概意思是:我正在从 Oracle 迁移到 MySQL,数据已经转换为单纯的 INSERT 语句.由 ...

  3. MySQL专场沙龙,爱可生首次解析告警系统

    7月28日,由上海爱可生信息技术股份有限公司赞助支持,高效运维社区举办的「2018高效运维社区数据库专场沙龙」在上海顺利举行.此次活动聚集五位行业大咖,他们从多维度为在座的技术小伙伴们分享最新干货.启 ...

  4. udf mysql 重启_lib_mysqludf_json导致mysql重启原因分析

    在<mysqludf_json将关系数据以JSON编码>提到使用lib_mysqludf_json会引起数据库重启.mysql错误日志如下: mysqld_safe Number of p ...

  5. mysql 硬盘死机_磁盘空间不够导致mysql崩溃重启

    起因: 群里有人提了句pt-ioprofile,我不知道,就查了查,想测一测,想以后可能会有帮助. 为了能看到效果,我选择了我虚拟机上最大的压测表Sbtest1,该表有100w数据,执行update ...

  6. mysql崩溃恢复过程_一起看下MySQL的崩溃恢复到底是怎么回事

    思考一个问题 为什么在你当update时,事物提交之前先不断的写redo log呢? 如果你看过白日梦前面介绍buffer pool的文章,这个问题的答案想必你也能很快的想出来:MySQL为了提高性能 ...

  7. no such file or directory什么意思_为什么这次 MySQL 崩溃恢复要这么久-爱可生

    作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源. 一.现象 有个 MySQL 5.7 开发库异常挂掉后,崩溃恢复一直处于如下位置,且持 ...

  8. 【技术贴】火狐QQ空间音乐插件下载+火狐进空间没背景音乐崩溃解决+火狐浏览器插件推荐...

    火狐QQ空间没声音火狐QQ空间崩溃火狐空间没音乐崩溃火狐QQ空间没音乐没声音 火狐进入QQ空间音乐不能播放以及进入空间崩溃的解决办法.见文章末尾. 火狐浏览器需要添加的插件.大集合下载地址.以及文字说 ...

  9. mysql sys库 oom_MySQL 5.6因为OOM导致数据库重启

    MySQL 5.6因为OOM导致数据库重启 发布时间:2020-08-09 08:29:53 来源:ITPUB博客 阅读:89 作者:feelpurple 线上的一套MySQL 5.6的从库,因为OO ...

最新文章

  1. Tomcat中文乱码问题的原理和解决方法
  2. 国际色卡c色号查询_怎幺提取图片中的潘通色卡?图片找色卡
  3. TensorFlow模型保存和加载方法
  4. VC实现微秒(十万分之一秒)休眠
  5. SAP Hybris的Convertor, Populator, Facade和DTO这几个概念是如何协同工作的
  6. 十五、详述 IntelliJ IDEA 插件的安装及使用方法
  7. (需求实战_进阶_06)SSM集成RabbitMQ 订阅模式 关键代码讲解、开发、测试
  8. TortoiseGit 修改密码
  9. python爬虫案例——根据网址爬取中文网站,获取标题、子连接、子连接数目、连接描述、中文分词列表
  10. 服务器各项指标的图形化显示
  11. 数学逻辑习题集(1)
  12. 逍遥安卓模拟器android,逍遥安卓模拟器
  13. 卫星运动的基础及GPS卫星星历
  14. linux 组建raid0教程,用两块硬盘组建RAID0磁盘阵列简单教程(图文详解)
  15. html点击下一页表单,在scray/python中单击html表单按钮进入下一页
  16. When Color Constancy Goes Wrong:Correcting Improperly White-Balanced Images阅读札记
  17. 【JavaWeb】JQuery实现广告显示和隐藏动画效果
  18. winxpnbsp;sp3
  19. 基于DCT变换图像去噪算法的进一步优化(100W像素30ms)
  20. Appium v1.17.1-1报错:pkg: /data/local/tmp/appium_cache/8d4156e508daae39c3f4815552e22e311432ff1f.apk

热门文章

  1. 【Python刷题】_10
  2. LeetCode-链表-142. 环形链表 II
  3. JAVA API实现HDFS操作(二)操作函数
  4. android 4.3 操作源码实现系统截屏(暂无移植性)
  5. Redis 的源码分析
  6. 微框架spark--api开发利器
  7. 探索 ConcurrentHashMap 高并发性的实现机制--转
  8. Sklearn(v3)——朴素贝叶斯(1)
  9. 【采用】规则引擎Pyke与PyClips对比研究报告(高大上啊,第一次听说pyke和pyclips这俩词~)
  10. 人一样自然流畅地说话,下一代智能对话系统还有多长的路要走?