关于MySQL数据被删除后空间重用的问题实验
以前知道,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数据被删除后空间重用的问题实验的更多相关文章
- MySQL误操作删除后,怎么恢复数据?
MySQL误操作删除后,怎么恢复数据?登陆查数据库mysql> select * from abc.stad;+----+-----------+| id | name |+----+----- ...
- Linux磁盘空间被占用问题 (分区目录占用空间比实际空间要大: 资源文件删除后, 空间没有真正释放)
问题说明:IDC里的一台服务器的/分区使用率爆满了!已达到100%!经查看发现有个文件过大(80G),于是在跟有关同事确认后rm -f果断删除该文件.但是发现删除该文件后,/分区的磁盘空间压根没有释放 ...
- WINDOWS下更改MYSQL数据路径(datadir)后服务启动1067解决不能改变mysql数据库存储位置
晚上安装完MYSQL(系统:深度WINXPSP2, MYSQL版本:5.1.32)后,用MYSQL自带的配置工具配置完发现默认的数据存放路径是:C:/Documents and Settings/Al ...
- LINUX运维实战案例之文件已删除但空间不释放问题的分析与解决办法
1.错误现象 运维的监控系统发来通知,报告一台服务器空间满了,登陆服务器查看,根分区确实没有空间了,如下图所示: 这里首先说明一下服务器的一些删除策略,由于Linux没有回收站功能,我们的线上服务器所 ...
- Java基础87 MySQL数据约束
1.默认值 -- 创建表student1,设置address字段有默认值 create table student1 ( id int, name ), address ) default '广东省深 ...
- RDS for MySQL 删除数据后空间没有减少处理方法
公司的程序和数据库部署在阿里云上,数据库使用的是阿里云的RDS,这天,经理在开发群中发了一个信息: 您的RDS实例rm********0oq的磁盘在过去一周平均使用率已超过80.%,建议您对实例规格进 ...
- mysql 清空或删除表数据后,控制表自增列值的方法
http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增 ...
- 解决在mysql表中删除自增id数据后,再添加数据时,id不会自增1的问题
https://blog.csdn.net/shaojunbo24/article/details/50036859 问题:mysql表中删除自增id数据后,再添加数据时,id不会紧接.比如:自增id ...
- 学习笔记:MySQL Big DELETEs 删除大量数据
原文地址:http://mysql.rjweb.org/doc.php/deletebig Table of Contents The ProblemWhy it is a ProblemInnoDB ...
随机推荐
- 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业
<Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...
- SpringBoot应用操作Rabbitmq(fanout广播高级操作)
一.广播模式fanout.不需要指定路由key. 注:与topic和direct区别是:fanout广播模式会两个队列同时发送相同的消息,并非由交换器转发到某一个队列 二.实战(广播模式) 1.引入m ...
- Axure遮罩 or 灯箱
2019独角兽企业重金招聘Python工程师标准>>> 在做原型设计的时候,常常需要设计弹窗(比如confirm.alert或者弹出面板),加一个全屏的遮罩可以突出要展示的内容,效果 ...
- 【阅读笔记】Ranking Relevance in Yahoo Search (一)—— introduction & background
ABSTRACT: 此文在相关性方面介绍三项关键技术:ranking functions, semantic matching features, query rewriting: 此文内容基于拥有百 ...
- 图论--树的重心(DFS) 模板
const int maxn=500005; int tot=0,n; int ans,size; int sx[maxn],head[maxn]; int vis[maxn]; struct edg ...
- [LOJ2865] P4899 [IOI2018] werewolf 狼人
P4899 [IOI2018] werewolf 狼人 LOJ#2865.「IOI2018」狼人,第一次AC交互题 kruskal 重构树+主席树 其实知道重构树的算法的话,难度就主要在主席树上 习惯 ...
- Python第三方库之Numpy库
概述 Numpy 最基本的库,是用于处理含有同种元素的多维数组运算的第三方库 —科学计算包,python数据分析及科学计算的基础库,几乎支撑所有其他库 —支持N维数组运算.处理大型矩阵.成熟的广播函 ...
- Thinkphp 缓存RCE
5.0.0<=ThinkPHP5<=5.0.10 . 漏洞利用条件: 1.基于tp5开发的代码中使用了Cache::set 进行缓存 2.在利用版本范围内 3.runtime目录可以 ...
- C. The Big Race
\(给出数n,a,b\) \(在[1,n]区间内随机选数,选出的数被a,b除后同余的概率\) \(这题的精度问题真的是烦炸了~\) \(设最小公倍数lcm=a*b/gcd(a,b)\) \(所以在区间 ...
- thinkphp操作phpexcel问题
一.thinkphp引入PHPExcel到/Thinkphp/Library/Vendor/ 二.在控制器中引用 public function get_detail() { Vendor(" ...