早上剛走進公司的門口,快走到辦公桌的時候,開發的同事很著急的跟我說:你可來了!
我:發生什麼事情了?
開發同事:XX資料庫死掉了!
我:特別驚訝!這個庫啟動並執行一直的很好的,怎麼會死掉了?況且也沒有接收到監控的警示資訊?
別著急,等我遠端連線上去看看。
登陸到MySQL後查看一下狀態: show processlist;
然後看到至少有一千多個查詢一直在執行,根據以往的經驗是有鎖出現了,導致後來的查詢被阻塞掉了,所以應用這邊就崩潰了,返回了逾時的錯誤!
仔細一看顯示的單個SQL查詢的狀態大部分都是:.....Query26037Waiting for table flushSELECT.......
注意紅色字型的關鍵字,官網的解釋是:
Flushing tables
The thread is executing FLUSH TABLES and is waiting for all threads to close their tables.
也就是說線程執行重新整理表操作並且等待所有的線程關閉他們佔用的表。
一個超長執行時間的SQL被發現了,這個SQL大概執行了十幾個小時還沒有查出結果。
但是這樣也不應該回引起flush tables 的問題出現。
kill 掉這個SQL線程之後,慢慢的系統復原了正常查詢的狀態。
就這樣粗暴的處理完成之後,就看系統各種的日誌,開始尋找原因,突然想到今天是周末
對呀周末!!
周末會怎樣呢?
周末有一個最佳化指令碼任務執行的!
這個最佳化指令碼就是使用analyze去分析每張表,analyze會收集表的統計資訊。
會導致mysql檢測到對應的table做了修改,必須執行flush操作,close和reopen表
由此可以推斷出,是因為那個執行時間超長的SQL在執行過程中,我的最佳化指令碼任務也啟動了,對SQL佔用的表進行了analyze 那張表就需要被close和reopen。但是SQL寫的太爛,一直沒有執行完成,也就不能釋放對錶的佔用。以至於後面的SQL就要排隊等待。
只要將那個SQL給kill掉就關閉了表,然後續的SQL就重新開啟了那個表,正常!
我根據推斷做了一個測試,首先手工執行那個爛SQL等待了一會兒沒有查出結果的跡象,在這個時候使用analyze table table_name;
show processlit 查看狀態,果然如此!中紅色框部分
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/140207/22415225P-0.jpg" title="1.jpg" alt="wKioL1LkuZqzmw-5AAPWQXlp6PY602.jpg" />
實驗證明了是analyze引起的問題,但不是主要的問題。
於是和開發商量需要改進SQL進行最佳化。搞定!
本文出自 “影子騎士” 部落格,請務必保留此出處http://andylhz2009.blog.51cto.com/728703/1354890