一句SQL,我的資料庫crash了

xuexiaogang發表於2022-09-19

 上週有人問我一個問題,資料庫莫名重啟了。其實是資料庫crash了,然後守護程式把他馬上啟動了。我看了一下錯誤日誌,很奇怪。也是第一次遇到。

一句SQL,我的資料庫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,我的資料庫crash了 

升級資料庫也就幾分鐘事情,做起來最快,影響最小。

升級以後再次執行這句SQL,一切正常,儘管這句SQL設計和編寫的有較大爭議。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/637517/viewspace-2915185/,如需轉載,請註明出處,否則將追究法律責任。

相關文章