数据库占用空间太大,把一个最大的表删掉了一半的数据,怎么表文件大小还是没变?接下来将讨论数据表的空间回收,看如何解决这个问题。
这里还是针对 MySQL 应用最广泛的 InnoDB 引擎展开讨论。一个 InnoDB 表包含两部分,即:表结构定义和数据。在 MySQL8.0 版本以前,表结构是存在。frm 为后缀的文件里。而 MySQL8.0 版本,则已经允许把表结构定义放在系统数据表中了。因为表结构定义占用的空间很小,所以主要讨论表数据。
参数 innodb_file_pre_table
表数据既可以存在共享表空间,也可以是单独的文件。这个行为时有参数 innodb_file_per_table 控制的:
- OFF,表的数据放在系统共享表空间,也就是跟数据字典放在一起;
- ON,每个 InnoDB 表数据存在在一个以。ibd 为后缀的文件中。
从 MySQL5.6.6 版本开始,它的默认值就是 ON 了。建议不论使用 MySQL 的哪个版本,都将这个值设置为 ON。因为一个表单独存储为一个文件更容易管理,而且在你不需要这个表的时候,通过 drop table 命令,系统就会直接删除这个文件。而如果是放在共享表空间中,即使表删掉了,空间也是不会回收的。
数据删除过程
InnoDB 里的数据都是用 B+ 树的结构组织的。假设现在要删掉 R4 这个记录,InnoDB 引擎只会把 R4 这个记录标记为删除。如果之后要再插入一个 ID 在 300 和 600 之间的记录时,可能会复用这个位置。但是,磁盘的文件的大小并不会缩小。
InnoDB 的数据是按页存储的,那么如果删掉一个数据页上的所有记录,会怎么样?答案是,整个数据页就可以被复用了。
但是,数据页的复用和记录的复用是不同的
记录的复用,只限于符合范围条件的数据。比如上面的例子 R4 这条记录被删除后,如果插入一个 ID 是 400 的行,可以直接复用这个空间。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于