回馈开源,我如何排查一个MySQL Bug


X-Engine是阿里巴巴自研的高性能低成本存储引擎,经过多年的努力,我们在集团内部以AliSQL(X-Engine)的形式(AliSQL是阿里的MySQL分支)支持了许多业务,为用户带来了显著的成本和性能收益。时至今日,阿里巴巴数据库团队已经向MySQL官方提交了许多有价值的bug及修复方案。我们继承了这一优良传统,在生产、测试中遇到MySQL相关的问题,总是积极地思考解决方案,并迅速与官方交流沟通,为开源社区的发展贡献自己的力量。下文将介绍我们刚发现的一个MySQL问题及修复方案。遇到相同情况的朋友需要注意了,也许不符合规范的数据已经写入你们的数据库了。背景知识如果MySQL参数sql_mode包含以下3项:NO_ZERO_DATENO_ZERO_IN_DATESTRICT_TRANS_TABLES向DATE类型列,插入’0000-00-00’或者年/月/日3部分任意一部分为0,都将失败异常:‘0000-00-00’竟然插入成功了在MySQL 8.0.16上依次执行以下语句:
set sql_mode=”;create table test (mydate DATE NOT NULL DEFAULT ‘0000-00-00’);
set sql_mode=default;
show variables like “sql_mode”;ins开发云主机域名ert into test values();select * from test;这里先将sql_mode设为空的目的是:建表时将mydate的default value设为’0000-00-00’,否则会因default value不符合NO_ZERO_DATE而建表失败。建表成功后将sql_mode设回default,包含:ONLY_FULL_GROUP_BYNO_ZERO_DATENO_ZERO_IN_DATESTRICT_TRANS_TABLESERROR_FOR_DIVISION_BY_ZERONO_ENGINE_SUBSTITUTION然而,这时竟然成功向test库里插入了一条’0000-00-00’的DATE。显然,NO_ZERO_DATE的语义被打破了。抽丝剥茧,原来问题出在这首先,我们定位到MySQL插入路径,检查default value是否合法的函数。这个函数比较简单,找出用户insert lists不包含的、且有default value的列,检查它们的default value是否合法。write_set是一个bitmap,标识了用户insert lists里包含哪些列。我用gdb在该函数处加了断点,执行上述case,竟然发现write_set里全部bit被设为了1。这显然不正常的现象,我的插入SQL语句insert into test values();insert list明明为空,write_set全为0才合理。看来有函数错误地修改了它。于是乎,我用gdb给write_set的地址加了一个watchpoint,重新执行insert语句。这次定位到了修改write_set的地方:
该函数在检查default value是否合法前执行,其作用是当binlog_format为ROW且binlog_row_image为FULL时,write_set会被全部设置为1。参数binlog_format指定了binlog格式,有三个备选项:ROW代表主备之间通过log_event同步;STATEMENT代表主备之间通过SQL语句同步;MIXED则是混合格式,默认用STATEMENT方式,一些特殊情况下用ROW方式。由于主备通过STATEMENT同步(虽然它产生的binlog数量小),可能因上下文信息、环境不同等因素,导致结果不一致,因此安全起见,binlog_format默认为ROW。参数binlog_row_image指定了ROW格式binlog要记录哪些信息。它也有三个备选项:FULL表示binlog记录变更前后的所有列;MINIMAL表示binlog只记录唯一标识列和修改列;NOBLOB表示BLOB是修改列或唯一标识列,才记录,其它列与FULL相同全部记录。binlog_row_image默认为FULL。当binlog_format为ROW且binlog_row_image为FULL 时,为了保证所有列都写到binlog里,write_set竟然被全部设置为1。write_set变量本是用来标识用户插入列,又被赋予了控制写binlog的重任。多重语义交织,很容易出bug。这也给我们编码带来启示:每个变量应当有确切的语义。修复建议导致这个bug的原因是write_set用处太多。因此可以创建一个新的bitmap:binlog_write_set,专门用于控制写binlog。

相关推荐: 浅谈怎样在UNIX系统下安装MySQL数据库(转)

推荐内容:Unix系统挂载ntfs格式免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@if98.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。开发云公众号手机网…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 06/05 19:58
下一篇 06/05 19:58

相关推荐