MySQL是怎么清理表空间的(垃圾回收,释放磁盘空间)

有点类似与JVM的垃圾回收机制,当删除表中的行数据时,MySQL不会自动回收垃圾内存(没有JVM那么强大的垃圾回收机制),于是结果内存空间如下:
请添加图片描述
我们删除2,4,6行数据后,数据页中只是会将对应行的数据抹去,但是其仍然占有磁盘空间,所以我们发现有时候删除了大量的数据行后,可用的磁盘空间并没有增加,之后用户如果想插入ID值为2,4,6(要在删除行的ID区间内)的记录的话可以直接加在这张表上,但是不能在这张表中加入其余ID值不在区间内的记录行。

重建表

于是MySQL为了释放删除数据后的空间想出了一个办法,就是建立一张新表将未删除的数据都按顺序拷贝到这张新表上(重建表),然后删除旧表(此处类似于JVM垃圾回收机制的“标记整理”算法),从而释放磁盘空间,如下图
请添加图片描述

online DDL

以上过程存在一个问题,就是在拷贝表数据的时候会加锁,也就是表数据无法更新,为了改进这点,出现了另一种拷贝表数据方法(online DDL,这个就类似于JVM的G1垃圾收集器,可以并发的进行)。在表进行拷贝的时候我们不去更新表数据,但是可以先将对表的更新操作记录到一个row log中,当拷贝完成后,将拷贝期间在row log中记录的更新刷新到新表中,如下图所示:
请添加图片描述

  • 步骤一:一边拷贝原表数据到临时的新表
  • 步骤二:将临时表替换为新表,在磁盘中释放原表的空间
  • 步骤三:回放row log中的记录,更新新表中的数据

ps:
以上MySQL整理磁盘碎片空间的方法和JVM的GC算法相似(将碎片内存空间放到一起/处理拷贝时的并发问题),感觉学到后来,很多知识都是相通的,都是基于一个合理的解决方案和算法,具体的实现细节应该都大同小异。

参考文章:

https://time.geekbang.org/column/article/72388

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL或MariaDB中,当执行DELETE语句删除数据时,磁盘空间通常不会立即释放。这是因为MySQL使用了一种称为“Undo Log”的机制来实现事务的回滚和MVCC(多版本并发控制)功能。 当执行DELETE语句时,MySQL会将被删除的数据记录存储在Undo Log中,以便在需要回滚事务或提供MVCC功能时使用。这样做的好处是可以保证数据的一致性和并发性。 然而,这也导致了磁盘空间没有立即释放的情况。要释放磁盘空间,可以通过以下几种方式: 1. 执行OPTIMIZE TABLE命令:这个命令会重新组织的物理存储,包括回收已删除的空间。但是需要注意的是,OPTIMIZE TABLE命令可能会导致被锁定,并且在大上执行时可能需要较长时间。 2. 使用TRUNCATE TABLE命令:TRUNCATE TABLE命令会删除中的所有数据,并释放磁盘空间。但是需要注意的是,TRUNCATE TABLE命令是DDL语句,会自动提交事务并且无法回滚。 3. 使用ALTER TABLE命令:通过ALTER TABLE命令重建,可以释放磁盘空间。例如,可以创建一个新并将数据插入其中,然后删除原。但是需要注意的是,这种方法可能会导致结构和索引的重新构建,可能会影响性能。 4. 等待自动回收MySQL会在后台自动回收已删除数据的磁盘空间,这个过程称为垃圾回收。可以通过设置innodb_undo_log_truncate选项来控制垃圾回收的频率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值