Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

这篇具有很好参考价值的文章主要介绍了Mysql小知识 delete 清空表之后,磁盘空间未发生变化?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 删除空洞

1.1 案例展示

首先我们先来看这样一个例子。

我现在有一个名为 sakila 的数据库,该库中有一个 film 表,这个表中有 1000 条记录,我么先来看下这 1000 条记录占用了多少存储空间:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

小伙伴们可以看到,这个文件大小是 360448 个字节。

我们现在执行 delete 命令将这个表清空:

delete from film;

然后再来查看这个文件的大小:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

小伙伴们看到,这个表中的数据没有减少,甚至还增加了!这是咋回事?

1.2 分析

以下所说的删除皆指通过 delete 命令删除,不包括通过 truncate/drop 删除。

MySQL 中的数据删除操作有点像我们平日里做业务开发时用的逻辑删除,当你想要删除掉一行数据的时候,这行数据其实并没有被真正的删除掉,只是暂时给标记为删除了而已。

经过前面文章的介绍,小伙伴们应该已经清楚,MySQL 表中的数据最终是以 B+Tree 的形式保存在磁盘中的,当你要删除一条记录的时候,那么对应的叶子上的数据就会被标记为已删除,类似下面这样:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

当 ID 为 6 的记录被删除掉之后,这块空间并不会立马被释放出来,MySQL 只是在这个位置做一个删除标记,将来要是还有一个 ID 为 6 的数据被插入进来,就会插入到这里。

因此我们看到,一张表在经过 N 多次删除之后,就会出现大量这种情况,这种就称之为删除空洞。

2. 插入空洞

前面所说的删除会造成空洞,其实插入也会造成空洞。

在之前的文章中和小伙伴们分享过,InnoDB 引擎的表中不建议使用随机字符串作为 ID,因为随机字符串插入会造成页分裂。页分裂之后,在分裂之前的叶子中,也有可能会空出来新的空间,造成空洞。

例如下面这个例子:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

在上图这个 B+Tree 中,继续插入 5,就会造成页分裂,页分裂之后,2 所在的数据页(InnoDB 操作磁盘的最小单位是数据页)就会有空余,这也是空洞的一种。

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

当然更新索引上的值也会造成空洞,因为更新相当于插入+删除。

3. optimize table

想要解决这个问题,我们可以使用 optimize table 命令来实现。该命令可以用来重新整理表空间,并优化文件碎片。接下来我们针对前面 1.1 小节中的案例,来试试 optimize table 命令是否有效:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

这上面有一句提示,说 Table does not support optimize, doing recreate + analyze instead,看这个意思,似乎是说当前这个 InndoDB 引擎的表不支持 optimize 操作,不过我们不用管,我们现在去查看表文件大小:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

可以看到,表文件数据其实已经减少了。

那么这句提示是咋回事呢?

我们以 MySQL 官方文档介绍为准来看下:

Mysql小知识 delete 清空表之后,磁盘空间未发生变化?

从这段话中可以看到,在 InnoDB 中使用 optimize 命令,相关的操作最终会被映射为 alter table ...,这也可以实现索引的重整并且释放掉未使用的空间,所以,网上有人说 optimize table 命令不适用于 InnoDB 引擎的表这个说法是不正确的。

同时,官方文档中这段介绍还提到了 optimize 操作是 online DDL 的。online DDL 意味着在执行 optimize 重整表的时候,并不会阻塞正在进行的 CURD 操作。具体流程如下:文章来源地址https://www.toymoban.com/news/detail-468348.html

  1. 首先建立一个临时文件,这个临时文件用来扫描表原始表主键的所有数据页。
  2. 根据第一步获取到的表记录生成一个 B+Tree,将这个生成的 B+Tree 存储到临时文件中。
  3. 由于第二步会比较耗时,在第二步执行过程中,如果有针对原始表的 CRUD 操作,则先将操作记录到一个日志文件中,等到第二步的临时文件生成后,在把日志文件应用到临时文件中,就可以获取到一个最新的数据表了。

到了这里,关于Mysql小知识 delete 清空表之后,磁盘空间未发生变化?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL-创建和管理表:基础知识、创建和管理数据库、创建表、修改表、重命名表、删除表、清空表、拓展

    注:此为笔者学习尚硅谷-宋红康MySQL的笔记,其中包含个人的笔记和理解,仅做学习笔记之用,更多详细资讯请出门左拐B站:尚硅谷!!! 1.1 一条数据存储的过程 存储数据是处理数据的第一步 。只有正确地把数据存储起来,我们才能进行有效的处理和分析。否则,只能是一团

    2024年04月11日
    浏览(89)
  • Vue3组件不发生变化,如何监听pinia中数据变化?

    在开发过程中,我们需要将一些跨组件使用的的数据在pinia中进行状态管理,组件在初始化的时候我们能通过onMounted,computed,watch,watchEffect获取到存储在pinia state中的内容,有一些特殊情况,在组件初始化之后我们无法通过以上四种情况获取state中的内容,这时候我们怎么做呢?

    2024年02月11日
    浏览(52)
  • 【postgresql 基础入门】update命令与delete命令,表达式作为值,带筛选条件的删除,避够清空全表

    ​ 专栏内容 : postgresql内核源码分析 手写数据库toadb 并发编程 个人主页 :我的主页 管理社区 :开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 已经存储在数据库中的数据,在日常使用过程中,在现实当中一些数据已经发生了变化,相应的我们需

    2024年04月14日
    浏览(42)
  • 浏览器输入一个URL之后发生了什么?

    URL解析 DNS解析 TCP连接 TSL连接 HTTP请求 TCP挥手 接收并解析响应 主要分为: 协议,eg http,https 域名或者ip地址,eg www.baidu.com 域名相对于ip地址来说,更方便人们记忆,但是实际的网络传输中使用的是ip地址 端口号,不同的协议对应不同的端口号,一般可以不写,eg http是80,h

    2024年02月11日
    浏览(69)
  • 在命令行按下tab键之后, 发生了什么?

    1. 引言 2. complete命令 3. 自定义补全列表 4. 动态补全列表 5. compgen命令 6. 别名的自动补全 7. 补全规则永久生效 8. 自动加载 9. 参考 当我们输入 ls 再按下TAB时, 会自动列出当前路径下 所有的文件 ; 当我们输入 ls a 再按下TAB时, 会自动列出当前路径下 所有以a开头的文件 ; 若只有

    2024年02月11日
    浏览(31)
  • 在浏览器中输入地址之后发生了什么过程?

    当我们在浏览器地址栏中输入某个网址之后,虽然页面内容几乎瞬间就显示出来,但其中经历了很多个步骤。 1.域名解析 网络上各个计算机之间相互通信均是以其IP地址来识别的,而我们输入的网址仅仅是方便我们记忆而取的别名,计算机不能直接识别,所以就需要将输入的

    2024年02月12日
    浏览(38)
  • Jenkins 监控dist.zip文件内容发生变化 触发自动部署

    为Jenkins添加plugin http://xx:xx/manage 创建一个任务 构建触发器 每3分钟扫描一次,发现指定文件build.zip文件的MD5发生变化后 触发任务    

    2024年02月13日
    浏览(35)
  • 在命令行按下tab键之后, 发生了生么?

    1. 引言 2. complete命令 3. 自定义补全列表 4. 动态补全列表 5. compgen命令 6. 别名的自动补全 7. 补全规则永久生效 8. 自动加载 9. 参考 当我们输入 ls 再按下TAB时, 会自动列出当前路径下 所有的文件 ; 当我们输入 ls a 再按下TAB时, 会自动列出当前路径下 所有以a开头的文件 ; 若只有

    2024年02月10日
    浏览(31)
  • 从Java 1.8到Java 21,发生了很多变化和改进

    从Java 1.8到Java 21,发生了很多变化和改进。以下是一些主要的变化和需要注意的事项: 模块化系统 (JEP 261) : 在Java 9中引入,这改变了Java的打包和部署方式。 使用 module-info.java 来定义模块和其依赖。 接口中的私有方法 (JEP 185) : 从Java 9开始,接口中可以定义私有方法。 局部变

    2024年04月17日
    浏览(35)
  • [20231013]为什么刷新缓存后输出记录顺序发生变化3.txt

    [20231013]为什么刷新缓存后输出记录顺序发生变化3.txt --//当年提的问题,链接http://blog.itpub.net/267265/viewspace-2763181/= [20210316]为什么刷新缓存后输出记录顺序发生变化.txt, --//正好别人问我,顺便我重复看了一下,顺便解答这个问题,实际上也许解答不对,许多行为我仅仅是猜测

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包