mysql in 宕机_一条SQL引起的mysql宕机
背? 景
MySQL引入了Materialization(物化)這一關鍵特性用于子查詢(比如在IN/NOTIN子查詢以及 FROM子查詢)優化,其關鍵點在于對子查詢只需要執行一次。具體實現方式為:
在SQL執行過程中,第一次需要子查詢結果時執行子查詢并將子查詢的結果保存為臨時表。
后續對子查詢結果集的訪問將直接通過臨時表獲得。
與之相對的執行方式是對外表的每一行都對子查詢進行調用,其執行計劃中的查詢類型為“DEPENDENTSUBQUERY”。雖然物化子查詢有利于提高SQL的執行效率,但如果使用不當,會引起意想不到的后果,比如數據庫宕機,今天所講的案例就是這樣一個場景。案例分析
一MySQL-5.7.17測試環境,業務發出一條查詢sql語句后,直接引起數據庫的宕機,查看err日志,發現sql語句如下:
問題sql為包括兩個子查詢的多表關聯select語句。
分析執行計劃
執行計劃相對簡單,值得注意的是select_type為“SUBQUERY”,它表明該sql可能使用了物化子查詢功能,為了得到確切的信息,查看warning信息:
當包含“materialize”和”materialized-subquery“時,已表明該sql語句使用了物化子查詢。為了看清物化子查詢是如何使用的,格式化上述信息如下:
該sql語句被MySQL進行了重寫,并且兩個子查詢都使用了物化子查詢進行了優化,分配兩個臨時表用于存放子查詢的結果,并且為每個臨時表創建hashindex,用于關聯其它表時,提高效率。
查看optimizer_switch參數
“materialization=on”表明啟用物化子查詢功能,”derived_merge=on”表明改寫sql,將子查詢合并至外部語句。難道是物化子查詢這個功能引起的嗎?
關閉物化子查詢功能
重新發起上述sql語句
執行計劃表明,該sql語句沒再使用物化子查詢功能
該sql語句執行成功,而且數據庫也并沒有宕機,看起來真的是物化子查詢這個功能的原因。
查看文檔
在查看5.7.23的變更文檔中發現如下這個bug
上述bug說明,物化子查詢可能會導致mysql服務宕機,5.7.23及以上版本修復了該問題,運行這樣的sql語句將會報錯,而不會再導致mysql宕機。
測試
為了驗證這個bug,將上述sql語句運行于5.7.23版本中
5.7.23版本中確實產生了錯誤,并且要求關閉物化子查詢功能。
總結
啟用物化子查詢功能,可以提升包含子查詢sql的執行效率,但也會觸發一些潛在問題,如上述的導致MySQL宕機bug,雖通過升級MySQL至5.7.23或最新版本,可以避免該問題;或閉關物化子查詢功能,使sql回退至原始的”DEPENDENT SUBQUERY“執行方式,但相應的sql執行效率也會下降很多,特別是外層結果特別巨大時。所以在生產環境,避免子查詢的使用,才是解決該問題的王道。
總結
以上是生活随笔為你收集整理的mysql in 宕机_一条SQL引起的mysql宕机的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一阶段.C语言
- 下一篇: 《Patterns, Principle