最近遇到一个故障和磁盘满有关系,而且同事也发现常常有磁盘满致使操做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