以前知道,MySQL在通过delete语句删除数据后,空间并不会被腾出,而只是在数据文件中被标记为已删除,除非执行optimize table。前两天听说,虽然delete数据后硬盘空间不会被腾出,但是在以后插入的行,会使用被删除的数据的空间。换句话说,尽管硬盘空间没有被腾出,新插入数据也不会受影响,因为他们根本不会使用剩余的磁盘空间。这个在之前还真是从没听说过。

对于这个问题,我做了一个实验,通过分析数据插入和删除后ibd文件的变化,来分析空间重用的情况。

创建表 :

CREATE TABLE `test` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`a` varchar(30) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

行格式为默认的compact

第一步,插入数据:

先插入30条一样的数据

insert into test (a) values (‘jwx’);

然后查看test.ibd文件

hexdump  -C -v test.ibd > tmp

可以看到,数据已经正常写入,如截图所示

因为只插入了30条数据,所以只占用一个数据页,这也是为了看起来方便。

根据上图可以通过数据页的page header 看出最后插入的位置的偏移量PAGE_LAST_INSERT是 03 70,然后可以看到0xc370的位置就是最后一行所在的位置,如图

同时可以看到,PAGE_HEAP_TOP为03 84,指向0xc384,后面的内容就都是空闲空间了。

第二步,删除一行数据

delete from test where id = 1

删除id为1的数据

然后观察ibd文件

可以看到位于0xc079位置的数字变成了20,这是表示改行已被删除,后面可以看到行索引id为 00 00 00 01,此时id为1的行已被删除,同时可以注意到0xc08f到0xc091为 6a 77 78,这三个字节即为’jwx’,行内容仍然保留着。然后PAGE_HEAP_TOP保持不变,而PAGE_LAST_INSERT则变为0x0000,大概是因为本次操作为delete(这个是猜的,不过和后面的结论关系不大)。

第三步,插入一行数据

insert into test (a) values (‘ss’)

观察ibd文件

可以看到,第一行的信息有了明显的变化,0xc078从03变成了02,该字节表示本行变长字段的长度,从03(’jwx’)变成了02(’ss’) 0xc08f到0xc091变成了73 73 78(‘ssx’),索引列字段变成了00 00 00 1f(31),而PAGE_LAST_INSERT则是00 7e,指向第一行的开头,而不是堆顶,可以看出被删除的数据空间被重用了。

通过上面的实验可以看出mysql行被删除后可以重用空间,其实在页的PAGE_HEADER部分有一个PAGE_FREE字段就是用来记录可重用空间的首指针位置的,0xc02c开始的两个字节即为PAGE_FREE字段。mysql官方文档是这样描述这个字段的:

当然,空间重用还有一个条件,就是被删除的行长度至少要和新插入的行长度一样,如果小于新插入的行,则空间就没法重用了。

关于这个问题,stackoverflow上也有回答,详情可以看以下链接

http://stackoverflow.com/questions/634257/does-the-space-occupied-by-deleted-rows-get-re-used

关于MySQL数据被删除后空间重用的问题实验的更多相关文章

  1. MySQL误操作删除后,怎么恢复数据?

    MySQL误操作删除后,怎么恢复数据?登陆查数据库mysql> select * from abc.stad;+----+-----------+| id | name |+----+----- ...

  2. Linux磁盘空间被占用问题 (分区目录占用空间比实际空间要大: 资源文件删除后, 空间没有真正释放)

    问题说明:IDC里的一台服务器的/分区使用率爆满了!已达到100%!经查看发现有个文件过大(80G),于是在跟有关同事确认后rm -f果断删除该文件.但是发现删除该文件后,/分区的磁盘空间压根没有释放 ...

  3. WINDOWS下更改MYSQL数据路径(datadir)后服务启动1067解决不能改变mysql数据库存储位置

    晚上安装完MYSQL(系统:深度WINXPSP2, MYSQL版本:5.1.32)后,用MYSQL自带的配置工具配置完发现默认的数据存放路径是:C:/Documents and Settings/Al ...

  4. LINUX运维实战案例之文件已删除但空间不释放问题的分析与解决办法

    1.错误现象 运维的监控系统发来通知,报告一台服务器空间满了,登陆服务器查看,根分区确实没有空间了,如下图所示: 这里首先说明一下服务器的一些删除策略,由于Linux没有回收站功能,我们的线上服务器所 ...

  5. Java基础87 MySQL数据约束

    1.默认值 -- 创建表student1,设置address字段有默认值 create table student1 ( id int, name ), address ) default '广东省深 ...

  6. RDS for MySQL 删除数据后空间没有减少处理方法

    公司的程序和数据库部署在阿里云上,数据库使用的是阿里云的RDS,这天,经理在开发群中发了一个信息: 您的RDS实例rm********0oq的磁盘在过去一周平均使用率已超过80.%,建议您对实例规格进 ...

  7. mysql 清空或删除表数据后,控制表自增列值的方法

    http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增 ...

  8. 解决在mysql表中删除自增id数据后,再添加数据时,id不会自增1的问题

    https://blog.csdn.net/shaojunbo24/article/details/50036859 问题:mysql表中删除自增id数据后,再添加数据时,id不会紧接.比如:自增id ...

  9. 学习笔记:MySQL Big DELETEs 删除大量数据

    原文地址:http://mysql.rjweb.org/doc.php/deletebig Table of Contents The ProblemWhy it is a ProblemInnoDB ...

随机推荐

  1. [Qt] Release模式下产生调试信息

    分两步,设置Qt配置文件,设置VS. https://blog.csdn.net/itas109/article/details/83652387 F:\Qt\Qt5.7.1\5.7\msvc2015 ...

  2. POJ1475 推箱子---模块化思想

    自古逢秋悲寂寥,我言秋日胜春朝. 晴空一鹤排云上,便引诗情到碧霄. --刘禹锡 题目:推箱子 网址:http://poj.org/problem?id=1475 推箱子游戏相信大家都不陌生,在本题中, ...

  3. 【Linux常见命令】tee命令

    tee - read from standard input and write to standard output and files tee命令用于读取标准输入的数据,并将其内容输出成文件. t ...

  4. Babel 在浏览器环境使用方法

    Babel 也可以用于浏览器环境.但是,从 Babel 6.0 开始,不再直接提供浏览器版本,而是要用构建工具构建出来.如果你没有或不想使用构建工具 1.通过安装5.x版本的babel-core模块获 ...

  5. Golang-filepath使用

    Golang-filepath 使用 获取当前目录 os.GetPWD() filepath.Abs(path) # 绝对目录 filepath.Dir(path) # 相对目录 可以 filepat ...

  6. bfs—迷宫问题—poj3984

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20591   Accepted: 12050 http://poj ...

  7. 使用ScriptX控件进行Web横向打印

    一个需求需要采用横向打印,目前采用IE自身的打印功能(WebBrowser.ExecWB控件)很难进行横向设置,默认需要调用document.all.WebBrowser.ExecWB(8,1);打开 ...

  8. 在Jetson TX2上安装OpenCV(3.4.0)

    参考文章:How to Install OpenCV (3.4.0) on Jetson TX2 与参考文章大部分都是相似的,如果不习惯看英文,可以看看我下面的描述 在我们使用python3进行编程时 ...

  9. Jenkins 节点配置

    1.配置代理 系统管理---configure Global Security(全局安全设置)---Tcp port for inbound agents---指定端口 服务器防火墙中开放此端口(li ...

  10. Java通过反射技术动态创建对象(有参、无参构造)

    实现类: package com.ljy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTarge ...