您现在的位置是:首页 > 加盟管理

故障分析 | MySQL : slave_compressed_protocol 导致 crash

加盟快讯 2025-02-18【加盟管理】33人已围观

简介现象MySQL版本:8.0.18:zabbix初始化脚本,包含建表、插入数据语句,10M+大小一个新客户,部署了一套我司的数据库管理平台,接管进来一主两从实例,其中一主一从在无锡机房,为半同步复制,另一个从库在北京机房,为异步复制。当在主库上时,会crash。但没接管进平台前,不会出现crash。说...

现象

MySQL版本:8.0.18

:zabbix初始化脚本,包含建表、插入数据语句,10M+大小

一个新客户,部署了一套我司的数据库管理平台,接管进来一主两从实例,其中一主一从在无锡机房,为半同步复制,另一个从库在北京机房,为异步复制。当在主库上时,会crash。但没接管进平台前,不会出现crash。

说明:这里提到的管理平台,不会影响理解整篇文章。

排查过程1.在测试环境进行复现

为方便排查,需要在可控的环境下进行复现:

与客户相同的

相同的MySQL版本

相同的复制架构

执行相同的

确实可以稳定复现crash,errorlog如下:

2.排除管理平台的影响

由于接管到管理平台才会出现crash,管理平台对数据库最大的操作来自于高可用组件:

延迟检测(写操作:每500ms写入一个时间戳)

状态查询(读操作)

所以接下来停用高可用、延迟检测进行测试,结果如下:

初步结论:延迟检测关闭后,不会crash。3.延迟检测影响了什么,导致crash?

在测试过程中,发现一个与crash伴生的现象:

不停用延迟检测,会crash,但是执行sql的效率高一些(毫秒级):

mysqlsource/tmp/,1rowaffected(0.21sec)QueryOK,1rowaffected(0.50sec)QueryOK,1rowaffected(0.03sec)QueryOK,1rowaffected(0.47sec)QueryOK,1rowaffected(0.51sec)QueryOK,1rowaffected(0.02sec)

而停用高可用检测,不会crash,每个sql执行时间都是1s多一点:

mysqlsource/tmp/,1rowaffected(0.01sec)QueryOK,1rowaffected(1.01sec)QueryOK,1rowaffected(1.01sec)QueryOK,1rowaffected(1.00sec)QueryOK,1rowaffected(1.01sec)QueryOK,1rowaffected(1.01sec)

这个看起来很像是组提交机制导致的,但是并没有配置组提交参数:

mysqlshowglobalvariableslike'%group_commit%';+-----------------------------------------+-------+|Variable_name|Value|+-----------------------------------------+-------+|binlog_group_commit_sync_delay|0||binlog_group_commit_sync_no_delay_count|0|+-----------------------------------------+-------+2rowsinset(0.01sec)

关闭半同步复制后,此现象也会消失。猜测:是半同步和组提交结合在一起触发的问题。

4.longblob大对象

在前面的测试中,每次复现crash,解析binlog查看最后一个事务都有一个共性:都是对同一张表插入数据:

SET@2=1/*INTmeta=0nullable=0is_null=0*/@4=

查看表结构,发现有lonngblob大对象,插入的是图片,用的是二进制格式存储:

CREATETABLE`images`(`imageid`bigint(20)unsignedNOTNULL,`imagetype`int(11)NOTNULLDEFAULT'0',`name`varchar(64)NOTNULLDEFAULT'0',`image`longblobNOTNULL,PRIMARYKEY(`imageid`),UNIQUEKEY`images_1`(`name`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_0900_ai_ci;

截取出中的images表的所有insert语句,接下来只执行这些insert语句,也能复现crash的问题:

sed-n'2031,2217p'
所以crash的第2个条件是:插入longblob大对象5.slave_compressed_protocol

前面的分析已经找到2个触发crash的条件:

插入数据时,存在longblob大对象

半同步复制,并且在insertlongblob大对象时伴随有其他外部写入流量

但是实际上用数据库管理平台自带的标准安装的同样版本的MySQL环境,并不能复现crash问题。区别在于不同,所以一定还有某个参数作为触发条件。

经过不断的测试,每次修改一批参数**(注意前面已经定位到跟半同步复制有关,所以一定要同时修改主、从库的参数)**,不断缩小范围,最终定位到是从库设置slave_compressed_protocol=on的影响。

从库slave_compressed_protocol=ON时,还会导致从库slaveiothread一直断开与主库的连接,并不断重连,从库errorlog报错如下:

主库errorlog报如下错:

相应的,因为从库slaveio线程不断重连,可以观察到主库的binlogdump线程会不断重启,有时还可以观察到2个:

showprocesslist;selectsleep(1);showprocesslist;.|2131|admin|172.16.21.3:37926|NULL|BinlogDumpGTID|3|Waitingtofinalizetermination|NULL||2132|admin|172.16.21.3:37932|NULL|BinlogDumpGTID|1|Singbinlogeventtoslave|NULL|.+-----------+|sleep(1)|+-----------+|0|+-----------+|2132|admin|172.16.21.3:37932|NULL|BinlogDumpGTID|2|Singbinlogeventtoslave|NULL|

与之相关的bug:

结论

此次crash的触发条件有3个:

插入longblob大对象;

半同步复制,并且在insertlongblob大对象时伴随有其他外部写流量;

slave_compressed_protocol=on.

为什么接管到平台之前没有发生过crash?

因为这个库还没上线,在执行时没有其他写入流量(等同于关闭延迟检测的效果)。

解决方案后续

我司研发大神后面向官方提交了一个bug:。

因为一些安全问题(更具体就不能透露了),这个bug被官方设置成了私密bug,截图如下,不过截止到今天(2021.12.28)官方还是没有修复:

很赞哦!(154)