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

上篇文章结尾和小伙伴们留了一个小问题,就是关于 optimize table 命令,今天我想花点时间再来和小伙伴们聊一聊这个话题。

1. 删除空洞

1.1 案例展示

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

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

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

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

delete from film;

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

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

1.2 分析

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

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

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

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

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

2. 插入空洞

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

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

例如下面这个例子:

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

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

3. optimize table

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

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

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

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

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

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

同时,官方文档中这段介绍还提到了 optimize 操作是 online DDL 的。online DDL 意味着在执行 optimize 重整表的时候,并不会阻塞正在进行的 CURD 操作。具体流程如下:

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

好啦,这就是关于 optimize table 的操作细节,小伙伴们 GET 到了吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/27485.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

x宝评论抓取

#某宝评论接口sign参数逆向 1.接口速览 多次请求发现,t为时间戳,sign为加密参数,盲猜和data、t有关,sign为32位,盲猜是字符串的32位的MD5 2.搜索js代码 这里为搜索的是appKey,就找到了sign,然…

【CSS】常见的选择器

1.标签选择器 语法 标签 { }作用 标签选择器用于选择某种标签比如 选择p标签,并设置背景颜色 p { background-color:yellow; }例子 选择div标签,并将其字体大小设置为100px,字体设置为"微软雅黑",文字颜色设置为r…

UDP协议和TCP协议

目录 UDP TCP 通过序列号与确认应答提高可靠性 为什么TCP是三次握手 为什么是四次挥手 超时重传机制 流控制 利用窗口控制提高速度 窗口控制与重发控制 拥塞控制 延迟确认应答 捎带应答 UDP UDP是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。…

从零开始,5分钟轻松实现Spring Boot与RabbitMQ的无缝集成

🌏 环境 docker v4.16.2springboot 2.7.0RabbitMQ 3.9.1 rabbitmq_delayed_message_exchange 3.9.0 ps:代码地址 gitee 🪜 服务架构 使用maven多模块,将生产者、消费者分别以springboot项目启动,两者通过RabbitMQ…

面试总结个人版

一、面试题 java 集合 , spring springmvc springboot springcloud 数据库相关的, redis 相关 ,mq 相关 ,结合业务的场景题 1、part one 集合 HashMap底层原理 HashMap是基于哈希表的Map接口的非同步实现。元素以键值对的形式存…

AI-Prompt 1.0 版简介公测!你的AI提示词网站!

提示词(Prompt) 是什么? 在 AI 大模型中,一个 prompt 是一个输入文本,用于触发模型生成输出。例如,当我们向一个 AI 大模型提交需求时,我们的需求就是一个 prompt。 在介绍产品之前,…

CoreDX DDS应用开发指南(4)DDS实体h和主题

6 DDS实体 DDS标准定义了一个体系结构,该体系结构表示构成DDS API实体的面向对象模型。这些实体充当中间件和应用软件之间的接口。为了开发支持DDS的应用程序,开发人员必须创建、交互并销毁这些DDS实体。 本章概述了DDS实体和相关概念。 6.1 DDS实体层次结构 构成DDS API的主…

OpenELB 在 CVTE 的最佳实践

作者:大飞哥,视源电子股份运维工程师, KubeSphere 社区用户委员会广州站站长,KubeSphere Ambassador。 公司介绍 广州视源电子科技股份有限公司(以下简称视源股份)成立于 2005 年 12 月,旗下拥…

[7]PCB设计实验|认识常用元器件|电容器|19:00~19:30

目录 一、电容器的识别 电容的应用 1. 电容有通交流阻隔直流电的作用 2. 有滤波、耦合、旁路作用等 3. 有些电容是有极性,有些是没有极性 二、常见电容器 1. 贴片电容 a、材质瓷片 b、材质钽介质 c、材质电解质 2. 手插电容 a、瓷片电容 b、聚脂电容 …

Windows命令行查找并kill进程及常用批处理命令汇总

Windows命令行查找并kill进程及常用命令汇总 打开命令窗口 开始—->运行—->cmd,或者是 windowR 组合键,调出命令窗口。 cmd命令行杀死Windows进程方法 1、根据进程名称批量kill 1)、执行tasklist|more检索进程 2)、执…

使用OpenAI创建对话式聊天机器人

引言 在当今的技术世界中,人工智能(AI)的发展迅猛,为我们带来了许多令人兴奋的创新。其中,自然语言处理(NLP)领域的进展使得开发对话式聊天机器人成为可能。OpenAI是一家领先的人工智能研究实验…

常见的JS存储方式及其特点

在前端开发中,经常需要在浏览器端存储和管理数据。为了实现数据的持久化存储和方便的访问,JavaScript提供了多种数据存储方式。本文将介绍几种常见的前端JS数据存储方式及其特点。 1. Cookie Cookie是一种小型的文本文件,由浏览器保存在用户…

如何利用google的protobuf设计、实现自己的RPC框架

一、前言 这篇文章我们就来聊一聊 RPC 的相关内容,来看一下如何利用 Google 的开源序列化工具 protobuf,来实现一个我们自己的 RPC 框架,内容有点长,请耐心看完。 序列化[1]:将结构数据或对象转换成能够被存储和传输&…

基于javaweb jsp+servlet实验室设备管理系统的设计与实现

一.项目介绍 本系统分为 超级管理员、老师、学生三类角色 超级管理员:通知管理、维护用户信息、实验室管理(负责维护实验室、预约实验室)、设备管理(维护技术参数、维护运行数据、维护电子文档)、设备维修管理&am…

JavaScript 教程---互联网文档计划

学习目标: 每天记录一章笔记 学习内容: JavaScript 教程---互联网文档计划 笔记时间: 2023-6-5 --- 2023-6-11 学习产出: 1.入门篇 1、JavaScript 的核心语法包含部分 基本语法标准库宿主API 基本语法:比如操作符…

【深入理解函数栈帧:探索函数调用的内部机制】

本章我们要介绍的不是数学中的函数&#xff0c;而是C语言中的函数哟&#xff01; 本章重点 了解汇编指令深刻理解函数调用过程 样例代码&#xff1a; #include <stdio.h> int MyAdd(int a, int b) {int c 0;c a b;return c; }int main() {int x 0xA;int y 0xB;int…

N皇后问题

1题目 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。…

电商--抢购总结

文章目录 业务流程业务难点技术难点技术方案技术方向具体落地客户端流控网关流控容器流控后端接口流控数据库流控 流控总结优化读取加速异步化流程处理系统扩容 压测监控 总结参考文献 业务流程 客户端抢购流程中会涉及到商品数据的读取用于商品展示&#xff0c;运营活动数据的…

Docker 概述与命令操作

一、Docker 概述 1、Docker的概念 • Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源 • Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机” • Docker 的容器技术可以在一台主机上轻松为任何应用创建一…

【4】Midjourney常用技巧

【常用技巧】 本篇主要讲述MJ的常用技巧&#xff0c;围绕着一些常用指令的使用方法展开。 【版本切换】 在使用MJ时&#xff0c;最常用的技巧之一是版本切换。你可以在输入提示后添加"--v"加上相应的数字来实现版本切换。通常我默认使用MJ 4&#xff0c;偶尔会使用…