MySQL 8.0.23上遇到一个FIND_IN_SET的BUG
本文为网友投稿。
作者:蓝树叶(成伟),运维工程师。
1、背景
在MySQL 8.0.23出现执行SQL超时的报错,而在MySQL8.0.18版本上未出现,故做个记录,以飨读者。
2、故障提要
在客户MySQL版本8.0.23,在部署客户测试环境时出现SQL执行超时报错。通过慢日志查询,找到对应的SQL。SQL如下:
SELECT * FROM t_dict WHERE FIND_IN_SET(id,(SELECT getDictChildrenNew(
(select id from t_dict where code = 'metadata_classify'
and root_code = 'metadata_classify' ),
(select code from t_dict where code = 'metadata_classify'
and root_code = 'metadata_classify' ),
(select root_code from t_dict where code = 'metadata_classify'
and root_code = 'metadata_classify' )
)))
order by dict_level,dict_order asc;
这个SQL用到了一个自定义函数getDictChildrenNew。函数内容如下:(真实的账号使用user_name代替了,已脱敏)
CREATE DEFINER=`user_name`@`%` FUNCTION `user_name`.`getDictChildrenNew`(iid varchar(255),icode varchar(255),ircode varchar(255)) RETURNS varchar(5000) CHARSET utf8mb4
READS SQL DATA
BEGIN
DECLARE oTemp VARCHAR(5000);
DECLARE oTempChild VARCHAR(5000);
DECLARE oTempId VARCHAR(5000);
DECLARE oRootCode VARCHAR(5000);
SET oTemp = '';
SET oTempChild = icode;
SET oTempId = iid;
SET oRootCode = ircode;
WHILE oTempChild IS NOT NULL
DO
SET oTemp = CONCAT(oTemp,',',oTempId);
SELECT GROUP_CONCAT(ID) INTO oTempId
FROM t_dict
WHERE ROOT_CODE = oRootCode AND FIND_IN_SET(PARENT_CODE,oTempChild);
SELECT GROUP_CONCAT(CODE) INTO oTempChild
FROM t_dict
WHERE ROOT_CODE = oRootCode AND FIND_IN_SET(PARENT_CODE,oTempChild);
END WHILE;
RETURN oTemp;
END
3、测试现象
我单独将where子句中这部分单独执行只需要122ms
SELECT getDictChildrenNew(
(select id from t_dict where code = 'metadata_classify' #58
and root_code = 'metadata_classify' ),
(select code from t_dict where code = 'metadata_classify' #metadata_classify
and root_code = 'metadata_classify' ),
(select root_code from t_dict where code = 'metadata_classify' #metadata_classify
and root_code = 'metadata_classify' )
)
或者我单独将这个查询的值以字符串形式作为FIND_IN_SET的第二个参数传入执行也很快。仅需79ms。
而我单独执行上面完整的SQL就会出现超时报错:(这为了演示,我就没有等到报错再截图了)
奇怪的是这个SQL在MySQL8.0.18上没有出现问题。能快速正常的计算出结果(67ms):
4、总结
为此,我们目前给客户的建议是降低MySQL版本。
之所以给客户用8.0.18的旧版,是因为我们的产品在旧版上进行了很多轮次的测试都是正常的。而这一次客户现场测试环境的MySQL版本是客户定的,我们产品没在这个版本跑过,所以才给出这个建议的。后续我会在新版做一轮测试看看。
此外,我们也会尝试去MySQL官网报告bug(#105277)。
《实战MGR》视频课程
视频已全部上线,这是免费视频,放在腾讯课堂平台上,共有500多人报名学习了。
目前是第一期内容,相信有很多不足,甚至错漏的地方,也欢迎各位不吝留言帮忙提建议、意见,帮忙改进完善,感谢。
戳此小程序即可直达
或用微信/QQ扫码
或复制链接在浏览器中打开 GreatSQL社区《实战MGR》https://ke.qq.com/course/3677969
文章推荐:
扫码加入GreatSQL/MGR交流QQ群
点击文末“阅读原文”直达老叶专栏