(mysql)使用了删除,为什么表的空间还是不变

今天发现了一个问题,当我执行删除语句的时候,删除了表中的一些行,所占的空间是不变的。后面我干脆把整个表的给删除了,发现还是表大小不变。让我感觉有点奇妙,后面阅读了极客文章知道了原因。

innoDB表包含两部分:表结构定义和数据。MySQL8.0之前,表结构是存在 .frm 为后缀的文件里,8.0版本则允许把表结构定义放在系统数据表中了。
参数 innodb_file_per_table

参数 innodb_file_per_table 设置为OFF时,表的数据放在共享表空间,也就是跟数据字典放在一起;当设置为ON表示,每个InnoDB表数据存储在一个以.idb为后缀的文件中。从MySQL5.6.6开始,默认为ON。

建议设置该值为ON。因为单独存储为一个文件更容易管理,可以通过drop table命令直接删除这个文件。如果放在共享表空间中,即使表删掉了,空间也是不会回收的。
未解放空间的原因
当我们执行delete语句去删除某行的时候,不是直接把这行所占用的空间所删除,而是把这一行的标记为可以复用,当有新的数据插入的时候,就可以不用创建新的空间,而有可能去复用这个功能。为什么说有可能能,比如你删除的是60~100之间的89这一行,而你插入时103这一行,他是复用不到的。

如果用delete命令把整个表的数据删除,那么所有的数据页都被标记为可复用。但磁盘上,文件不会变小。

delete命令只是把记录的位置,或者数据页标记为“可复用”,但磁盘文件的大小是不会变的。这些可复用,而没有被利用的空间,看起来就像是“空洞”。

不仅删除数据会造成空洞,插入数据,更新索引上的值也会造成空洞。当一个在一个已满的数据页上插入数据,就会申请一个新的页面保存数据,页分裂完成后,老的数据页尾就留下了空洞。更新索引值,可以理解为删除一个旧的值,再插入一个新值。
如何去除空洞,收缩表空间:重建表

可以使用 alter table A engine=InnoDB命令来重建表。该命令的执行流程是:新建一个与表A结构相同的表B,然后按照主键ID递增的顺序,把数据一行一行从表A读出插入表B。表B就没有像表A中的空洞了,索引更加紧凑。完成后用表B替换表A。
在这里插入图片描述

在MySQL5.5之前,流程和上述描述差不多,区别是临时表B不需要你自己创建,MySQL会自动完成上述操作。在上述往临时表插入数据过程中,如果有新的数据要写入表A的话,就会造成数据丢失。因此在整个DDL过程中,表A不能有更新,也就是DDL不是Online的。

MySQL5.6版本开始引入Online DDL,对操作流程做了优化:

  1. 建立一个临时文件,扫描表A主键的所有数据页;
  2. 用数据页中表A的记录生成B+树,存储到临时文件中;
  3. 生成临时文件的过程中,将所有对A的操作记录在一个日志文件(rowlog)中,对应的是图 中state2的状态;
  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表A相同的 数据文件,对应的就是图中state3的状态;
  5. 用临时文件替换表A的数据文件。
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值