面试官问:MySQL 删除表数据,磁盘空间还一直被占用,为什么?

最近有个 "上位机" 获取 "下位机" 上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多。

为了节约成本,定期进行数据备份,并通过delete删除表记录。

明明已经执行了delete,可表文件的大小却没减小,令人费解

项目中使用Mysql作为数据库,对于表来说,一般为表结构和表数据。表结构占用空间都是比较小的,一般都是表数据占用的空间。

当我们使用 delete 删除数据时,确实删除了表中的数据记录,但查看表文件大小却没什么变化。

Mysql数据结构 

凡是使用过mysql,对B+树肯定是有所耳闻的,MySQL InnoDB 中采用了 B+ 树作为存储数据的结构,也就是常说的索引组织表,并且数据是按照页来存储的。因此在删除数据时,会有两种情况: 

  • 删除数据页中的某些记录
  • 删除整个数据页的内容​​​​​​​​​​​​​​​​​​​​​​​​

​​​​​​​表文件大小未更改和mysql设计有关 

比如想要删除 R4 这条记录:

图片

InnoDB 直接将 R4 这条记录标记为删除,称为可复用的位置。如果之后要插入 ID 在 300 到 700 间的记录时,就会复用该位置。

扫描二维码关注公众号,回复: 13462888 查看本文章

通用删除整页数据也会将记录标记为删除,数据就复用该位置,与删除默写记录不同的是,删除整页记录,当后来插入的数据不在原来的范围时,都可以复用位置,而如果只是删除默写记录,是需要插入数据符合删除记录位置的时候才能复用。

因此,无论是数据行的删除还是数据页的删除,都是将其标记为删除的状态,用于复用,所以文件并不会减小。

那怎么才能让表大小变小

DELETE 只是将数据标识为删除,并没有整理数据文件,当插入新数据后,会再次使用这些被置为删除标识的记录空间,可以使用OPTIMIZE TABLE来回收未使用的空间,并整理数据文件的碎片。

OPTIMIZE TABLE 表名;

注意:OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。

另外,也可以执行通过ALTER TABLE重建表

ALTER TABLE 表名 ENGINE=INNODB

有人会问OPTIMIZE TABLE和ALTER TABLE有什么区别?

alter table t engine = InnoDB(也就是recreate),而 optimize table t 等于 recreate+analyze

​​​​​​​总结

delete 删除数据时,其实对应的数据行并不是真正的删除,仅仅是将其标记成可复用的状态,所以表空间不会变小。

​​​​​​可以用重建表的方式,快速将delete数据后的表变小(OPTIMIZE TABLE 或ALTER TABLE),在 5.6 版本后,创建表已经支持 Online 的操作,但最好是在业务低峰时使用。

猜你喜欢

转载自blog.csdn.net/JineD/article/details/121000537