一句SQL,我的数据库crash了

来源:这里教程网 时间:2026-03-01 16:48:48 作者:

 上周有人问我一个问题,数据库莫名重启了。其实是数据库crash了,然后守护进程把他马上启动了。我看了一下错误日志,很奇怪。也是第一次遇到。

看到红色框的 mysqld got signal 11,一下就感觉不好。历次数据库crash,必然有他。不过以前我遇到最多的是latch lock。这次不是。

蓝色框数据库说可能是一个bug,不少人看到这句就说,遇到bug了。我个人不这么认为,因为这是官方标准输出,都会带出这样的。就像有人说我非常抱歉(不代表这个人一定做错了) 。因为我工作这么多年实在没遇到过什么bug,即使我认为是bug的官方解释了以后,我倾向于不是了。然后始终认为即使有bug,我们可以避开。就是所谓的闭坑,因为是在特定条件下触发的。绕开就好了。

绿色表示堆栈的信息(经过多次重启发现输出都是一致的)

黄色部分从上面看,以我个人愚见应该是优化器上报的问题。经过处理的SQL大概这样:

SELECT COUNT(1) FROM (SELECT DISTINCT st.* FROM (SELECT t.*, POSITION('SW' IN t.这是一个列) AS loc FROM (SELECT DISTINCT 0 AS seq, CONCAT('这里隐去 ', f.这是一个列) AS content, (4 | 2) AS flag, 0 AS std_flag FROM (SELECT * FROM A WHERE 1 = 1 AND 某列1 = 'SECC' AND 某列2 NOT LIKE 'A%' AND 某列2 NOT LIKE 'B%' AND 某列2 NOT LIKE 'C%' AND 某列2 NOT LIKE 'D%' AND 某列2 NOT LIKE 'E%' AND 某列2 NOT LIKE 'F%' AND 某列2 NOT LIKE 'G%' AND s某列2 NOT LIKE 'H%' AND 某列2 NOT LIKE 'TOYOTA%') m, f WHERE m.列3 = f.列3 AND m.列4 = f.列4 AND m.列5 = f.列5 AND m.列6 = f.列6 AND f LIKE 'SW%') t) st WHERE st.loc > 0) TOTAL

然后我打算看一下执行计划(数据库再次重启),也就是说连执行计划都看不了。

了解了一下这个是刚从MySQL5.7升级到8,具体版本是8.0.25.反应说在5.7上还能执行。8一定是在优化器上做了优化,不过为什么出这个问题还不知道。那么就把这两个表数据导入到我自己的一个环境看看8.0.30的。这里可以看执行计划,在这个过程中发现其中A表还是空的。如果是空表这个出hash join就不应该了。这是8的新特性,当然我们可以去关闭hash join,但是也不一定是100%可以解决。所以既然8.0.30可以处理,那么还是建议升级吧。

 

升级数据库也就几分钟事情,做起来最快,影响最小。

升级以后再次执行这句SQL,一切正常,尽管这句SQL设计和编写的有较大争议。

相关推荐