阿里云RDS服务器报硬盘磁盘空间不足(100G的磁盘空间),登录后台查看,使用了130G,使用 SELECT file_name, concat(TOTAL_EXTENTS,'M') as 'FIle_size' FROM INFORMATION_SCHEMA.FILES order by TOTAL_EXTENTS DESC 查看,只使用了60G左右。那么还有70G是怎么用了呢?
查看问题:
查询 information_schema.innodb_trx ,看是哪些语句导致的。
原因:
ibdata文件很大,MySQL实例可能会 由于长时间不结束的查询导致 ibdata1 文件过大且无法收缩,导致实例空间满 ,为避免数据丢失,RDS会对实例进行自动锁定,磁盘锁定之后,将无法进行写入 *** 作
解决方案:
重启实例即可
1、drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM2、truncate table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM 。truncate table其实有点类似于drop table 然后creat,只不过这个create table 的过程做了优化,比如表结构文件之前已经有了等等。所以速度上应该是接近drop table的速度
3、delete from table_name删除表的全部数据,对于MyISAM 会立刻释放磁盘空间 (应该是做了特别处理,也比较合理),InnoDB 不会释放磁盘空间
4、对于delete from table_name where xxx带条件的删除, 不管是innodb还是MyISAM都不会释放磁盘空间
5、delete *** 作以后使用optimize table table_name 会立刻释放磁盘空间。不管是innodb还是myisam 。所以要想达到释放磁盘空间的目的,delete以后执行optimize table *** 作。
6、delete from表以后虽然未释放磁盘空间,但是下次插入数据的时候,仍然可以使用这部分空间。
一、磁盘满了之后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,连个 *** 作都会卡住。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)