磁盘满了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


MySQL数据库的磁盘空间时,会导致数据库无法写入新的数据,进而影响应用的正常运行。以下是排查和解决MySQL数据库磁盘问题的步骤: 1. **检查磁盘使用情况**: 使用命令`df -h`查看磁盘的使用情况,确认是哪个分区了。 ```sh df -h ``` 2. **查看MySQL数据目录**: 确认MySQL的数据目录所在分区是否了。使用以下命令查看MySQL的数据目录: ```sql SHOW VARIABLES LIKE 'datadir'; ``` 3. **检查数据库大小**: 使用以下命令查看各个数据库的大小: ```sql SELECT table_schema AS 'Database', SUM(data_length + index_length) AS 'Total' FROM information_schema.TABLES GROUP BY table_schema; ``` 4. **查看具体表的大小**: 使用以下命令查看具体表的大小: ```sql SELECT table_name AS 'Table', table_schema AS 'Database', ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)' FROM information_schema.TABLES WHERE table_schema = 'your_database_name' ORDER BY (data_length + index_length) DESC; ``` 5. **清理无用的数据**: 清理无用的数据表、删除不需要的记录,或者归档旧数据到其他存储介质。 6. **优化表**: 使用`OPTIMIZE TABLE`命令优化表,释放未使用的空间。 ```sql OPTIMIZE TABLE your_table_name; ``` 7. **增加磁盘空间**: 如果以上方法无法解决问题,可以考虑增加磁盘空间,或者将数据目录迁移到更大的分区。 8. **配置MySQL日志**: 检查MySQL的日志文件(如二进制日志、错误日志等),并根据需要清理或配置日志轮转。 ```sh # 查看二进制日志文件 SHOW BINARY LOGS; # 清理二进制日志 RESET MASTER; ``` 9. **定期维护**: 定期进行数据库维护,包括清理无用的数据、优化表结构、配置日志轮转等,以防止磁盘空间再次。 通过以上步骤,可以有效排查和解决MySQL数据库磁盘的问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值