最近遇到一個故障和磁盤滿有關系,並且同事也發現經常有磁盤滿導致操作hang住無響應的情況,於是抽時間研究了一下這2種情況。
我們看下官方的說法
a every minute see whether there enough write the row. there enough ,it continues * minutes it writes an entry the , warning about the condition.
其實MySQL本身並不會做任何操作,如官方文檔說說,只會每分鐘check一次是否有空閒空間,並且10分鐘寫一次錯誤日志。
但是再次期間由於磁盤滿了,意味著binlog無法更新,redo log也無法更新,所有buffer pool中的數據無法被flush上,如果不幸的服務器重啟,或者實例被kill了,那必然會造成數據丟失,這幾乎是一定的。所以,處理磁盤滿的問題最好是先釋放出來一定空間讓dirty數據刷新下來。
1、select
首先經過經驗和實際測試,select操作不會由於磁盤滿導致問題,也就是所有select操作都會正常運行。
2、insert
經過不通的測試發現,當磁盤滿了之後,並不是第一個insert就卡住,而是會在n個之後出現卡住的情況。
通過查看error日志,發現卡住現象和刷磁盤的操作有關系。
usrlocalmysql.libexecmysqld: writing usrlocalmysql.libexecmysqld: writing
為了驗證推論是否正確,我們將sync_binlog設置為1,在這種情況下,insert第一條就卡住了,並且error log中直接報錯提示寫binlog失敗。看來卡住確實和刷磁盤有關系。
目前已知和刷磁盤有關系的參數有3個,分別是sync_binlog,innodb_flush_log_tr_commit,和duoblewrite。
3、show slave status
在從庫經過測試,操作會被卡住,這主要是由於執行show slave status需要獲得LOCK_active_mi鎖,然後鎖上mi->data_lock,但是由於磁盤滿了無法將io_thread中的數據寫入到relay log中,導致io_thread持有mi->data_lock鎖,這就導致了死鎖。
所以,這就導致在磁盤滿的情況下,執行show slave status操作會卡住。
4、show status
測試可以正常操作,但是如果先執行了show slave status操作的情況下,show status也會被卡住。這是因為執行show status需要鎖上LOCK_status,而由於status狀態中包含slave status,所以還需要鎖上LOCK_active_mi。如果限制性了show slave status,這時候由於mi->data_lock死鎖問題,導致io_thread不會釋放LOCK_active_mi鎖。這時候就導致show status和show slave status爭搶同一把LOCK_active_mi鎖,也形成了死鎖。
所以,在磁盤滿的情況下,如果先執行show slave status,後執行show status,連個操作都會卡住。
ps:3和4的結果可以參考,這篇blog《》http://my.oschina.net/llzx373/blog/224175