TFdream / blog

个人技术博客,博文写在 Issues 里。
Apache License 2.0
129 stars 18 forks source link

什么是MySQL表空洞? #434

Open TFdream opened 1 year ago

TFdream commented 1 year ago

InnoDB的底层是B+树,B+树的叶子节点存储数据,因为磁盘预读原理,一般叶子节点的大小会和page的大小保持一致。

当我们删除了数据后,并没有把申请的空间还给操作系统,而是将当前空间标记为“可复用”,这样当新数据插入时,就不用重新再申请空间,可以直接将数据插入到“可复用”的空间中; 这样“可复用”的空间,就称为数据空洞。

MySQL官方文档对此的解释如下:

After deleting a large part of a MyISAM or ARCHIVE table, or making many changes to a MyISAM or ARCHIVE table with variable-length rows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns).

Deleted rows are maintained in a linked list and subsequent INSERT operations reuse old row positions.

数据空洞的好处是尽可能的复用表空间结构,带来的问题也是显而易见,当删除数据后,表空间并未及时的释放,当长时间没有新的数据填充,会造成空间浪费的情况。

如何清理空洞

  1. myisam 可以使用 optimize table table_name 命令进行碎片整理,去除空洞,会锁表(innodb无法使用optimize)
  2. 使用 alter table table_name engine=innodb ,可以释放空洞,这是由于在转换数据引擎(即使没有真正转换)的时候,会将表中的所有数据读取,再重新写入,这个过程中,会释放空洞(效率慢)

注:效率慢,谨慎使用

参考资料