mysql数据库存储空间与数据大小不一致

mysql数据库存储空间与数据大小不一致,第1张

阿里云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和MyISAM

2、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,连个 *** 作都会卡住。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/6121112.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-15
下一篇 2023-03-15

发表评论

登录后才能评论

评论列表(0条)

保存