为什么mysql的delete操作不释放磁盘空间
在 InnoDB 中,delete 操作并不会真的删除数据,mysql 实际上只是给要删除的数据打了标记,标记为删除。磁盘所占空间不会变小,即表空间并没有真正被释放。
一、 MySQL 删除数据几种情况以及是否释放磁盘空间
1. drop ,truncate
立刻释放磁盘空间 ,不管是 Innodb 还是 MyISAM ;
truncate table 其实有点类似于 drop table 然后 creat,只不过这个 create table 的过程做了优化,比如表结构文件之前已经有了等等。所以速度上应该是接近 drop table 的速度;
2. delete 带条件
对于 delete from table_name where xxx; 带条件的删除, 不管是 innodb 还是 MyISAM 都不会释放磁盘空间;
3. delete 不带条件
delete from table_name 删除表的全部数据,对于 MyISAM 会立刻释放磁盘空间 (应该是做了特别处理,也比较合理),InnoDB 不会释放磁盘空间;
二、 碎片的产生
MySQL 中 insert 与 update 都可能导致页分裂,这样就存在碎片。
对于大量的 UPDATE,也会产生文件碎片化 , Innodb 的最小物理存储分配单位是页(page),而 UPDATE 也可能导致页分裂(page split),频繁的页分裂,页会变得稀疏,并且被不规则的填充,所以最终数据会有碎片。
delete 语句实际上只是给数据打个标记,并且记录到一个链表中,这样就形成了留白空间。
在 InnoDB 中,删除一些行,这些行只是被标记为“已删除”,而不是真的从索引中物理删除了,因而空间也没有真的被释放回收。InnoDB 的 Purge 线程会异步的来清理这些没用的索引键和行。
当执行插入操作时,MySQL 会尝试使用空白空间,但如果某个空白空间一直没有被大小合适的数据占用,仍然无法将其彻底占用,就形成了碎片;
三、 这样设计的思考
1. mysql 的 delete 操作,只是做了逻辑上的标记删除,在磁盘上数据并没有被真正删除。
2. 这样的设计是因为:如果在磁盘上移除之后,很多其它的记录需要在磁盘上重新排列,这会消耗大量的性能。(例如:一个大表,存在索引,删除了其中一行,那么整个索引结构就会发生变化,随之而来的改变索引结构,必将带来磁盘 IO)
3. 所有被删除的记录会组成一个垃圾链表,这个链表记录占用的空间叫可重用空间。新插入的记录可覆盖此空间。
四、 如何查看数据库的碎片情况
-- 查看数据库中每个存在碎片的表
select concat('optimize table ',table_schema,'.',table_name,';'),data_free,engine from information_schema.tables where data_free>0 and engine !='MEMORY';
--查看指定表的碎片情况
show table status like 't_user'--找到碎片化最严重的表
SELECT table_schema, TABLE_NAME, concat(data_free/1024/1024, 'M') as data_free
FROM `information_schema`.tables
WHERE data_free > 3 * 1024 * 1024AND ENGINE = 'innodb'
ORDER BY data_free DESC
五、 如何清理碎片
- alter table tb_test engine=innodb
这其实是一个 NULL 操作,表面上看什么也不做,实际上重新整理碎片了.当执行优化操作时,实际执行的是一个空的 ALTER 命令,但是这个命令也会起到优化的作用,它会重建整个表,删掉未使用的空白空间。
- optimize table xxx;
OPTIMIZE TABLE 语句可以重新组织表、索引的物理存储,减少存储空间,提高访问的 I/O 效率。类似于碎片整理功能。
MySQL 可以通过 optimize table 语句释放表空间,重组表数据和索引的物理页,减少表所占空间和优化读写性能
使用语法:
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] …
参考资料:
https://blog.csdn.net/levae1024/article/details/121791757
https://www.php.cn/mysql-tutorials-493459.html转载自:https://www.luoxx.top/archives/mysql-free-disk
为什么mysql的delete操作不释放磁盘空间相关推荐
- MySQL DELETE 操作后没有释放磁盘空间
最近遇到一个问题,项目对应的的数据库频繁报警,报警内容为数据库磁盘空间达到85%.后来经过查看发现数据库中有20多个表数据量特别大,每张表大约3亿数据,共70亿左右数据(存储的内容为坐标记录整体来说不 ...
- mysql 释放空间_Mysql InnoDB删除数据后释放磁盘空间的步骤详解
Mysql InnoDB删除数据后释放磁盘空间的方法 Innodb数据库对于已经删除的数据只是标记为删除,并不真正释放所占用的磁盘空间,这就导致InnoDB数据库文件不断增长. 如果在创建数据库的时候 ...
- MySQL中DELETE操作磁盘空间不会减少的原因
MySQL中delete操作 在InnoDB中,delete操作并不会真的删除数据,mysql实际上只是给要删除的数据打了标记,标记为删除.磁盘所占空间不会变小,即表空间并没有真正被释放. 这样设计的 ...
- 记一次delete MySQL数据释放磁盘空间
某日收到数据库服务器磁盘报警超过75%,突然想到架构师让每月清理一次流水表这个月还没有清理,于是在18:00提交变更申请清理上个月之前的数据. 执行操作为: mysql> delete from ...
- mysql删除数据后释放磁盘空间
drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM : truncate table table_name立刻释放磁盘空间 ,不管是 Innodb和My ...
- mysql drop table 释放空间_MySQL删除数据几种情况以及是否释放磁盘空间【转】
MySQL删除数据几种情况以及是否释放磁盘空间: 1.drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ; 2.truncate table tabl ...
- MySQL删除数据后,释放磁盘空间
drop table table_name 立刻释放磁盘空间 , Innodb和MyISAM: truncate table table_name 立刻释放磁盘空间, Innodb和MyISAM,t ...
- Mysql定义DELETE操作触发器,将删除数据存入历史表
Mysql定义DELETE操作触发器,将删除数据存入历史表 SQL如下: // An highlighted blockDELIMITER $$ CREATE TRIGGER <触发器名称> ...
- Windows 8.1下释放磁盘空间的指南
This is an "updated for Windows 8.1" version of my popular original article Guide to Freei ...
最新文章
- 用css绘制各种形状
- 11.2.0.2 asmcmd lsdg show incorrect diskgroup number
- bzoj 1705: [Usaco2007 Nov]Telephone Wire 架设电话线【dp】
- php return 返回html_【php socket通讯】php实现http服务
- 如何写python脚本抓取数据并计算_【小工具】利用Python脚本从Gaussian计算结果中提取信息...
- VMware VDI部署攻略之四:域用户配置及验收
- 看完这篇,你应该知道什么是Linux了~
- gearman初探(一、编译和安装)
- 常见Eclipse SVN插件报错解决方法
- android 监听安装来源_Android编程监听APK安装与删除等过程的方法
- 西南石油大学硕导携研究生野外考察遭遇泥石流,师生4人不幸遇难
- 【Cocos2d-X(2.x) 游戏开发系列之二】cocos2dx最新2.0.1版本跨平台整合NDK+Xcode编译到Android...
- 【java】java中的线程池 ThreadPoolExecutor源码分析
- 微软开放技术发布开源 Jenkins 插件以将 Windows Azure Blob 服务用的开作存储库
- idea报错Cannot resolve jdk.tools:jdk.tools:1.7
- 批量输出lib文件名(PCL或者opencv等环境配置)
- NLTK was unable to find the megam file!
- 用力和应变片计算弹性模量_电阻应变片粘贴及弹性模量的测定实验报告徐姗.doc...
- 电商系统中商品模型与类目体系设计
- 傅一平:业务流程的数字化到底是什么?