背景

MySQL的数据存储在表空间中,有的时候我们删除了一张表的一半的数据,但是发现表空间文件的大小并没有减少,这是什么原因呢?

MySQL数据空洞

当对一条数据执行delete操作时,MySQL将数据删除后,并未将数据占用的空间返还给操作系统,而是将当前空间标记为"可复用",当有新的数据插入时,则不会重新申请空间,而是插入到"可复用"空间中,这种"可复用"空间,称之为数据空洞。

MySQL官方文档对此的解释如下:

After deleting a large part of a MyISAM or ARCHIVE table, or making many changes to a MyISAM or ARCHIVE table with variable-length rows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns).

Deleted rows are maintained in a linked list and subsequent INSERT operations reuse old row positions.

数据空洞的好处是尽可能的复用表空间结构,带来的问题也是显而易见,当删除数据后,表空间并未及时的释放,当长时间没有新的数据填充,会造成空间浪费的情况。

OPTIMIZE TABLE命令

MySQL提供了命令OPTIMIZE TABLE来整理表空间结构,来清理释放未使用的表空间结构,以此提升表的性能。

MySQL官方文档对此的解释如下:

You can use OPTIMIZE TABLE to reclaim the unused space and to defragment the data file. After extensive changes to a table, this statement may also improve performance of statements that use the table, sometimes significantly.

OPTIMIZE TABLE works for InnoDB, MyISAM, and ARCHIVE tables.
OPTIMIZE TABLE is also supported for dynamic columns of in-memory NDB tables. It does not work for fixed-width columns of in-memory tables, nor does it work for Disk Data tables.

对于InnoDB,OPTIMIZE TABLE等价于ALTER TABLE...FORCE,相当于对数据表的聚簇索引进行重建,清理未使用的空间。

下面来看一下执行OPTIMIZE TABLE的效果:

mysql> OPTIMIZE TABLE foo;
+----------+----------+----------+-------------------------------------------------------------------+
| Table    | Op       | Msg_type | Msg_text                                                          |
+----------+----------+----------+-------------------------------------------------------------------+
| test.foo | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.foo | optimize | status   | OK                                                                |
+----------+----------+----------+-------------------------------------------------------------------+

OPTIMIZE TABLE背后细节

1、OPTIMIZE TABLE使用online DDL机制,以此来降低并发DML操作场景下的停顿时间。
2、OPTIMIZE TABLE操作会在preparecommit两个阶段对表加锁。
3、在prepare阶段,会对数据表的元数据进行更新,并创建临时表。
4、在commit阶段,数据表的元数据更新会进行提交。
5、online DDL机制不支持InnoDB引擎的FULLTEXT索引,如果使用FULLTEXT索引,那么将会变为表数据拷贝的方式进行重建。

MySQL官方文档对此的解释如下:

OPTIMIZE TABLE uses online DDL for regular and partitioned InnoDB tables,
which reduces downtime for concurrent DML operations.
The table rebuild triggered by OPTIMIZE TABLE is completed in place.
An exclusive table lock is only taken briefly during the prepare phase and the commit phase of the operation.
During the prepare phase, metadata is updated and an intermediate table is created.
During the commit phase, table metadata changes are committed.

参考文档:
OPTIMIZE TABLE Statement:
https://dev.mysql.com/doc/refman/8.0/en/optimize-table.html

InnoDB and Online DDL
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl.html

MYSQL 5.7 到底 OPTIMIZE Table 塞不塞 DML
https://cloud.tencent.com/developer/article/1606990

什么是MySQL数据空洞?相关推荐

  1. 记一次delete MySQL数据释放磁盘空间

    某日收到数据库服务器磁盘报警超过75%,突然想到架构师让每月清理一次流水表这个月还没有清理,于是在18:00提交变更申请清理上个月之前的数据. 执行操作为: mysql> delete from ...

  2. mysql备份psb文件怎么打开_Navicat for MySQL 数据备份教程

    原标题:Navicat for MySQL 数据备份教程 一个安全和可靠的服务器与定期运行备份有密切的关系,因为错误有可能随时发生,由攻击.硬件故障.人为错误.电力中断等都会照成数据丢失.备份功能为防 ...

  3. binlog流程 mysql_小米 MySQL 数据实时同步到大数据数仓的架构与实践

    背景MySQL由于自身简单.高效.可靠的特点,成为小米内部使用最广泛的数据库,但是当数据量达到千万/亿级别的时候,MySQL的相关操作会变的非常迟缓:如果这时还有实时BI展示的需求,对于mysql来说 ...

  4. 软件测试实验--数据工厂DataFactory+MySQL数据构造

    数据工厂---DataFactory+MySQL数据构造 显示成功,但测出来的是啥...

  5. PHPExcel使用-使用PHPExcel导出文件-导出MySQL数据

    现在数据库里面有一组数据,我们将它按照不同的难度进行分sheet. 首先我们需要写一个mysql的配置文件- db.config.php(utf-8编码) : <?php $dbconfig= ...

  6. solr5.5.4 添加mysql数据,实现同步更新

    相关文章:第一篇要是安装部署,第二篇如何定时同步mysql数据.第三篇solr实战关键字查询全库 1.导入jar包.将目录E:\solr\test\solr-5.5.4\dist下的两个jar包,so ...

  7. 我艹,MySQL数据量大时,delete操作无法命中索引。

    来自:Java面试那些事儿 最近,在脉脉上看到一个楼主提出的问题:MySQL数据量大时,delete操作无法命中索引:并且还附上了相关案例截图. 最终,楼主通过开启MySQL分析优化器追踪,定位到是优 ...

  8. Case Study: 利用JS设计高级检索功能通过PHP获取MySQL数据

    一.目标 该笔记的目的是引导读者借助WampServer平台和MySQL数据库,利用HTML/CSS/JS/PHP设计一个含有高级检索功能的数据库网页.该功能效果如图1所示.用户在文本框中输入相应内容 ...

  9. Sqoop在导入MySQL数据时遇到Timestamp列为0000-00-00 00:00:00报错

    为什么80%的码农都做不了架构师?>>>    Sqoop在导入MySQL数据时遇到Timestamp列为'0000-00-00 00:00:00'时报错,解决方法是:在JDBC连接 ...

  10. 运维工程师必备之MySQL数据的主从复制、半同步复制和主主复制详解

    一.MySQL复制概述 ⑴.MySQL数据的复制的基本介绍 目前MySQL数据库已经占去数据库市场上很大的份额,其一是由于MySQL数据的开源性和高性能,当然还有重要的一条就是免费~不过不知道还能免费 ...

最新文章

  1. split()的使用
  2. Algorithm之PGM之BNet:贝叶斯网络BNet的相关论文、过程原理、关键步骤等相关配图
  3. closehandle()函数
  4. Python 如何创建多维的list
  5. 触发器-当表1插入数据时将表1的数据插入表2
  6. 一种非常简单的静态网页生成方法介绍
  7. Hadoop组件之-HDFS(HA实现细节)
  8. SAP屏幕设计器专题:表格控件属性的设定(七)
  9. 超级计算机与人工智能:大国超算,无人领航
  10. java day38【Servlet 、HTTP协议 、Request】
  11. 基于Python+OpenCV的人脸口罩识别检测
  12. Java程序设计案例教程
  13. ROS智能车定位导航仿真(原赛道自主导航,构建地图再导航)
  14. 计算机cpu位数是啥,怎么看电脑cpu的位数
  15. 1179: 带参宏定义(函数专题)
  16. codeforces gym100851 Generators 暴力+贪心
  17. c语言小游戏 贪吃蛇
  18. 使用c语言实现后缀表达式计算器
  19. 数组最大值和最小值的求法
  20. 算法笔记 简单贪心(月饼问题)

热门文章

  1. 30岁哥大计算机博士生遇刺身亡,论文刚被顶会接收,曾留学中国
  2. 国庆假期微信大数据报告
  3. 简单的LED恒流电路
  4. hacker 入门指南
  5. 2021年福建高考成绩什么时候可以查询,2021年福建高考成绩排名及成绩公布时间什么时候出来...
  6. Relative Ranks问题及解法
  7. Attempted reconnect 3 times. Giving up
  8. 我的vim的vimrc配置文件,保存用 - 飞在天空的鱼 - 博客频道
  9. 从bilibili下载视频,取其音频
  10. 有关Windows10中诊断和反馈隐私设置