磁盤滿了MySQL會做什么?


最近遇到一個故障和磁盤滿有關系,並且同事也發現經常有磁盤滿導致操作hang住無響應的情況,於是抽時間研究了一下這2種情況。

 

一、磁盤滿了之后MySQL會做什么?

我們看下官方的說法

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數據刷新下來。

 

二、磁盤滿了為什么會導致操作hang住?

1、select

  首先經過經驗和實際測試,select操作不會由於磁盤滿導致問題,也就是所有select操作都會正常運行。

2、insert

  經過不通的測試發現,當磁盤滿了之后,並不是第一個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。

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《MySQL源代碼管中窺豹(一):磁盤寫滿之后,數據庫show status受到阻塞的原因》http://my.oschina.net/llzx373/blog/224175


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM