您现在的位置是:首页 > 加盟管理
故障分析 | 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)