为什么MySQL 删除表数据 磁盘空间还一直被占用


Posted in MySQL onOctober 16, 2021

最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多。

为了节约成本,定期进行数据备份,并通过delete删除表记录。

明明已经执行了delete,可表文件的大小却没减小,令人费解

项目中使用Mysql作为数据库,对于表来说,一般为表结构和表数据。表结构占用空间都是比较小的,一般都是表数据占用的空间。

当我们使用 delete删除数据时,确实删除了表中的数据记录,但查看表文件大小却没什么变化。

1、Mysql数据结构

凡是使用过mysql,对B+树肯定是有所耳闻的,MySQL InnoDB 中采用了 B+ 树作为存储数据的结构,也就是常说的索引组织表,并且数据时按照页来存储的。因此在删除数据时,会有两种情况:

  • 删除数据页中的某些记录
  • 删除整个数据页的内容

2、表文件大小未更改和mysql设计有关

比如想要删除 R4 这条记录:

为什么MySQL 删除表数据 磁盘空间还一直被占用

InnoDB 直接将 R4 这条记录标记为删除,称为可复用的位置。如果之后要插入 ID 300 700 间的记录时,就会复用该位置。

由此可见,磁盘文件的大小并不会减少。

通用删除整页数据也将记录标记删除,数据就复用用该位置,与删除默写记录不同的是,删除整页记录,当后来插入的数据不在原来的范围时,都可以复用位置,而如果只是删除默写记录,是需要插入数据符合删除记录位置的时候才能复用。

因此,无论是数据行的删除还是数据页的删除,都是将其标记为删除的状态,用于复用,所以文件并不会减小。

3、那怎么才能让表大小变小

DELETE只是将数据标识位删除,并没有整理数据文件,当插入新数据后,会再次使用这些被置为删除标识的记录空间,可以使用OPTIMIZE TABLE来回收未使用的空间,并整理数据文件的碎片。

OPTIMIZE TABLE 表名;

注意:OPTIMIZE TABLE只对MyISAM, BDBInnoDB表起作用。

另外,也可以执行通过ALTER TABLE重建表

ALTER TABLE 表名 ENGINE=INNODB

有人会问OPTIMIZE TABLEALTER TABLE有什么区别?

alter table t engine = InnoDB(也就是recreate),而 optimize table t 等于 recreate+analyze

4、Online DDL

最后,再说一下Online DDLdba的日常工作肯定有一项是ddl变更,ddl变更会锁表,这个可以说是dba心中永远的痛,特别是执行ddl变更,导致库上大量线程处于“Waiting for meta data lock”状态的时候。因此在 5.6 版本后引入了 Online DDL

Online DDL推出以前,执行ddl主要有两种方式copy方式和inplace方式,inplace方式又称为(fast index creation)。相对于copy方式,inplace方式不拷贝数据,因此较快。但是这种方式仅支持添加、删除索引两种方式,而且与copy方式一样需要全程锁表,实用性不是很强。Online方式与前两种方式相比,不仅可以读,还可以支持写操作。

执行online DDL语句的时候,使用ALGORITHMLOCK关键字,这两个关键字在我们的DDL语句的最后面,用逗号隔开即可。示例如下:

ALTER TABLE tbl_name ADD COLUMN col_name col_type, ALGORITHM=INPLACE, LOCK=NONE;

ALGORITHM选项

  • INPLACE:替换:直接在原表上面执行DDL的操作。
  • COPY:复制:使用一种临时表的方式,克隆出一个临时表,在临时表上执行DDL,然后再把数据导入到临时表中,在重命名等。这期间需要多出一倍的磁盘空间来支撑这样的 操作。执行期间,表不允许DML的操作。
  • DEFAULT:默认方式,有MySQL自己选择,优先使用INPLACE的方式。
  • LOCK选项
  • SHARE:共享锁,执行DDL的表可以读,但是不可以写。
  • NONE:没有任何限制,执行DDL的表可读可写。
  • EXCLUSIVE:排它锁,执行DDL的表不可以读,也不可以写。
  • DEFAULT:默认值,也就是在DDL语句中不指定LOCK子句的时候使用的默认值。如果指定LOCK的值为

DEFAULT,那就是交给MySQL子句去觉得锁还是不锁表。不建议使用,如果你确定你的DDL语句不会锁表,你可以不指定lock或者指定它的值为default,否则建议指定它的锁类型。
执行DDL操作时,ALGORITHM选项可以不指定,这时候MySQL按照INSTANTINPLACECOPY的顺序自动选择合适的模式。也可以指定ALGORITHM=DEFAULT,也是同样的效果。如果指定了ALGORITHM选项,但不支持的话,会直接报错。

OPTIMIZE TABLE ALTER TABLE 表名 ENGINE=INNODB都支持Oline DDL,但依旧建议在业务访问量低的时候使用

5、总结

delete 删除数据时,其实对应的数据行并不是真正的删除,仅仅是将其标记成可复用的状态,所以表空间不会变小。

可以重建表的方式,快速将delete数据后的表变小(OPTIMIZE TABLE ALTER TABLE),在 5.6 版本后,创建表已经支持 Online 的操作,但最好是在业务低峰时使用

到此这篇关于为什么MySQL 删除表数据 磁盘空间还一直被占用的文章就介绍到这了,更多相关MySQL 删除表数据 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL性能压力基准测试工具sysbench的使用简介
Apr 21 MySQL
MySQL8.0.24版本Release Note的一些改进点
Apr 22 MySQL
MySQL 角色(role)功能介绍
Apr 24 MySQL
Mysql数据库值的添加、修改、删除及清空操作实例
Jun 20 MySQL
SQL IDENTITY_INSERT作用案例详解
Aug 23 MySQL
MySQL修炼之联结与集合浅析
Oct 05 MySQL
MySQL表锁、行锁、排它锁及共享锁的使用详解
Apr 02 MySQL
为什么MySQL不建议使用SELECT *
Apr 03 MySQL
mysql查询结果实现多列拼接查询
Apr 03 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
mysql sock文件存储了什么信息
Jul 15 MySQL
SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
May 08 MySQL
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
MySQL数据库必备之条件查询语句
Oct 15 #MySQL
MySQL实例精讲单行函数以及字符数学日期流程控制
MySQL数据库超时设置配置的方法实例
MyBatis 动态SQL全面详解
MySQL中datetime时间字段的四舍五入操作
You might like
php中CI操作多个数据库的代码
2012/07/05 PHP
PHP输出缓存ob系列函数详解
2014/03/11 PHP
举例详解PHP脚本的测试方法
2015/08/05 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
2017/06/30 PHP
PHP基于方差和标准差计算学生成绩的稳定性示例
2017/07/04 PHP
PHP Laravel 上传图片、文件等类封装
2017/08/16 PHP
PHP http请求超时问题解决方案
2020/11/13 PHP
toString()一个会自动调用的方法
2010/02/08 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
jQuery常见开发技巧详细整理
2013/01/02 Javascript
js QQ客服悬浮效果实现代码
2014/12/12 Javascript
js中遍历对象的属性和值的方法
2016/07/27 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
微信小程序实现缓存根据不同的id来进行设置和读取缓存
2017/06/12 Javascript
基于AngularJS实现表单验证功能
2017/07/28 Javascript
二维码图片生成器QRCode.js简单介绍
2017/08/18 Javascript
JavaScript 点击触发复制功能实例详解
2018/11/02 Javascript
深入解析koa之异步回调处理
2019/06/17 Javascript
详解Vue 项目中的几个实用组件(ts)
2019/10/29 Javascript
[02:01]BBC DOTA2国际邀请赛每日综述:八强胜者组鏖战,中国队喜忧参半
2014/07/19 DOTA
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
python实现连接mongodb的方法
2015/05/08 Python
python中threading超线程用法实例分析
2015/05/16 Python
Python实现多线程抓取妹子图
2015/08/08 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
彻底解决pip下载pytorch慢的问题方法
2021/03/01 Python
css3背景图片透明叠加属性cross-fade简介及用法实例
2013/01/08 HTML / CSS
HTML5教程之html 5 本地数据库(Web Sql Database)
2014/04/03 HTML / CSS
德国高品质男装及配饰商城:Cultizm(Raw Denim原色牛仔裤)
2018/04/16 全球购物
日本乐天德国站:Rakuten.de
2019/05/16 全球购物
财务工作者先进事迹材料
2014/01/17 职场文书
优秀党员先进事迹材料
2014/12/18 职场文书
项目安全员岗位职责
2015/02/15 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书
pandas中DataFrame检测重复值的实现
2021/05/26 Python
pandas数值排序的实现实例
2021/07/25 Python