走狗屎运了,MySQL占用空间竟然越删越大

第一时间获取技术干货和业界资讯!

走狗屎运了,MySQL占用空间竟然越删越大

工作996,生活669,生命886

手把手教你MySQL中查询回表

别浪,猥琐发育。一大波Redis面试题正在来临

BAT 必问的 MySQL 面试题你都会吗?

如何通过抓包实战来学习Web协议?

话说有一天,我心血来潮。登录阿里云,发现 RDS 占用的空间挺大的。想起有一张表,当初设计的不好,没用的数据挺多的。就想着删除清理一部分数据,节约空间。

说做就做,一条 delete 语句,如下:

走狗屎运了,MySQL占用空间竟然越删越大

没想到意外发生了,删除几十万条数据后,我再去查看 RDS 占用的数据空间,不仅没降,还上升了。这是怎么回事?

走狗屎运了,MySQL占用空间竟然越删越大

这个问题可能很多人都没有注意到。平时大家的关注点可能都不在这方面。

我把这个数据删除后,阿里云立马发邮件报警,说我们的 RDS 存储空间过大,没办法,当初知识水平有限。就又花公司的钱,升级了存储空间。

这个问题一直困惑着我,直到两年前看了《高性能MySQL》。而今天刚好又有一个网友私信我,我想起了这件事。所以,今天就给大家解惑一下,为什么会这样。

第一个就是网上很多人所说的那样,这是一个MySQL的BUG,直到MySQL 5.7 版本才解决。由于我们当初选的是 MySQL 5.6 的版本,出现这个问题后,也咨询了阿里云。但是阿里云给出的答复是只能进行数据迁移,虽然MySQL5.7版本,可以解决这个问题,但是阿里云的MySQL5.6的版本并不能直接升级到5.7。而迁移数据库也太浪费时间和精力了,搞不好,再把主要数据给丢失了。BOSS 非剁了我不可。

第二个我要说的就是 MySQL 5.6中默认是独立表空间,如果采用独立表存储模式,data 中还会产生 report_site_day.ibd 这类文件(存储数据信息和索引信息)。而删除的时候,它不会被删除。

第三个就是 MySQL 对于删除的功能的底层实现,并不是大家想象的那样,执行 delete 就真的给删除了。而是当你使用 delete 删除的时候,MySQL 并没有把数据文件删除,而是将数据文件的标识位删除,没有整理文件,因此不会彻底释放空间。被删除的数据将会被保存在一个链接清单中,当有新数据写入的时候,MySQL 会利用这些已删除的空间再写入。即,删除操作会带来一些数据碎片,正是这些碎片在占用硬盘空间。

走狗屎运了,MySQL占用空间竟然越删越大

关于数据迁移也会带来一些问题,这个我们下一章再说。今天我先说一下,MySQL 官方推荐的 OPTIMIZE TABLE 命令来清理优化表 InnoDB 空间的做法。

OPTIMIZE TABLE 命令的格式如下:

走狗屎运了,MySQL占用空间竟然越删越大

具体的用法如下:

走狗屎运了,MySQL占用空间竟然越删越大

或者,你也可以这样批量生成优化所有表的 SQL,再复制出来执行:

走狗屎运了,MySQL占用空间竟然越删越大

除此之外,我们还还可以把表设置为单表存储的形式,这样每个表中的数据单独存储,在删除数据的时候,会随着数据的删除而释放存储空间。

走狗屎运了,MySQL占用空间竟然越删越大

至于数据迁移,我们可以先备份后删除然后进行导入。

走狗屎运了,MySQL占用空间竟然越删越大

数据迁移也有很多坑,这也是我下一章想讲的。我们的约定,明天见!

走狗屎运了,MySQL占用空间竟然越删越大

猜你喜欢

转载自blog.51cto.com/15127565/2666212