接着上篇中遇到的mysql子查詢,在問題的診斷中,丹臣注意到一個較為嚴重的問題,就是我們生産庫中全部的資料庫通路請求都處于waiting for tables的狀态,在将大查詢kill掉後,所有的請求恢複正常;簡單的了解為大查詢阻塞了其他通路請求,但是這個理論是不可信,如果阻塞該表的dml還可以了解,但是把該資料庫上的所有請求都阻塞了,這還是說不通的。那麼我們就來看看所有的請求處于waiting for tables這個狀态是什麼原因導緻的:
the thread got a notification that the underlying structure for a table has changed and it needs to reopen the table to get the new structure. however, to reopen the table, it must wait until all other threads have closed the table in question.
this notification takes place if another thread has used <code>flush tables</code> or one of the following statements on the table in question: <code>flush tables <code>tbl_name</code></code>, <code>alter table</code>, <code>rename table</code>, <code>repair table</code>, <code>analyze table</code>, or<code>optimize table</code>.
從文檔上的解釋來看,是主庫做了一個flush tables的操作,導緻所有的表都需要打開,但是由于在10-07号放假,應該不會有人在主庫上執行flush tables,而且從日志中可以看到:
1044 system user connect 27406 flushing tables flush tables
是以可以判斷是系統自己執行了這個操作,那麼既然不是主庫上執行而來,那麼這個flush tables操作是從slave上複制過來的(m-m結構),
那麼備庫的什麼操作會有flush tables,真的百思不其解,我們備庫在6點之前做的是什麼,後端應用的dump?還是資料庫的備份?是不是xtrabackup,很有可能是xtrabackup在備份的時候做的fulsh tables,檢視備份腳本,應該輪到mysqldump做邏輯備份操作了,并不是xtrabackup,檢查了mysqldump的備份腳本,腳本裡:
-uroot -p$port –protocol=tcp –single-transaction –master-data=2是這樣的
single-transaction這個選項是加上了的,希望再一次被打破 >_<
最後想還是想到到官網上去看看,mysqldump+flush tables是否有bug,
唉,搜尋了一下果然發現了蹊跷:
http://bugs.mysql.com/bug.php?id=35157
when using the –master-data option with mysqldump, mysqldump uses a flush tables command. however, this statement got replicated to the slave(s), which caused the slave(s) to block unnecessarily while the flush tables command completed.
在5.0存在的bug很好的解釋了這個問題,在mysqldump加入了–master-data就會将flush tables記錄到binglog中,然後在被同步到主庫,主庫執行binglog後,由于有一個大查詢正在
執行,這個子查詢由于執行了很長時間,阻塞了flush tables的操作,最後導緻了雪崩,所有的請求都被阻塞:
the thread got a notification that the underlying structure for a table has changed and it needs to reopen the table to get the new structure. however, to reopen the table,
it must wait until all other threads have closed the table in question.
綜合上篇的所寫,mysqldump的在5.0的bug加上資料庫的低效子查詢構成這次故障的原因。
峰回路轉,山窮水盡,哈哈