最近遇到一個故障和磁盤滿有關係,而且同事也發現常常有磁盤滿致使操做hang住無響應的狀況,因而抽時間研究了一下這2種狀況。mysql
1、磁盤滿了以後MySQL會作什麼?web
咱們看下官方的說法sql
When a disk-full condition occurs, MySQL does the following: * It checks once every minute to see whether there is enough space to write the current row. If there is enough space,it continues as if nothing had happened.
* Every 10 minutes it writes an entry to the log file, warning about the disk-full condition.
其實MySQL自己並不會作任何操做,如官方文檔說說,只會每分鐘check一次是否有空閒空間,而且10分鐘寫一次錯誤日誌。數據庫
可是再次期間因爲磁盤滿了,意味着binlog沒法更新,redo log也沒法更新,全部buffer pool中的數據沒法被flush上,若是不幸的服務器重啓,或者實例被kill了,那必然會形成數據丟失,這幾乎是必定的。因此,處理磁盤滿的問題最好是先釋放出來必定空間讓dirty數據刷新下來。服務器
2、磁盤滿了爲何會致使操做hang住?app
一、select測試
首先通過經驗和實際測試,select操做不會因爲磁盤滿致使問題,也就是全部select操做都會正常運行。spa
二、insert.net
通過不通的測試發現,當磁盤滿了以後,並非第一個insert就卡住,而是會在n個以後出現卡住的狀況。日誌
經過查看error日誌,發現卡住現象和刷磁盤的操做有關係。
[ERROR] /usr/local/mysql-5.1.42/libexec/mysqld: Disk is full writing './test/cj_webex.MYD' [ERROR] /usr/local/mysql-5.1.42/libexec/mysqld: Disk is full writing './mysql-bin.000017'
爲了驗證推論是否正確,咱們將sync_binlog設置爲1,在這種狀況下,insert第一條就卡住了,而且error log中直接報錯提示寫binlog失敗。看來卡住確實和刷磁盤有關係。
目前已知和刷磁盤有關係的參數有3個,分別是sync_binlog,innodb_flush_log_tr_commit,和duoblewrite。
三、show slave status
在從庫通過測試,操做會被卡住,這主要是因爲執行show slave status須要得到LOCK_active_mi鎖,而後鎖上mi->data_lock,可是因爲磁盤滿了沒法將io_thread中的數據寫入到relay log中,致使io_thread持有mi->data_lock鎖,這就致使了死鎖。
因此,這就致使在磁盤滿的狀況下,執行show slave status操做會卡住。
四、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《MySQL源代碼管中窺豹(一):磁盤寫滿以後,數據庫show status受到阻塞的緣由》http://my.oschina.net/llzx373/blog/224175