【176期】面试官:MYSQL 表数据 delete 删除后,为何还占用存储空间?
点击上方“Java精选”,选择“设为星标”
别问别人为什么,多问自己凭什么!
下方有惊喜,留言必回,有问必答!
每天 08:35 更新文章,每天进步一点点...
最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多。
为了节约成本,定期进行数据备份,并通过delete删除表记录。
明明已经执行了delete,可表文件的大小却没减小,令人费解
项目中使用Mysql作为数据库,对于表来说,一般为表结构和表数据。表结构占用空间都是比较小的,一般都是表数据占用的空间。
当我们使用 delete删除数据时,确实删除了表中的数据记录,但查看表文件大小却没什么变化。
Mysql数据结构
凡是使用过mysql,对B+树肯定是有所耳闻的,MySQL InnoDB 中采用了 B+ 树作为存储数据的结构,也就是常说的索引组织表,并且数据时按照页来存储的。因此在删除数据时,会有两种情况:
删除数据页中的某些记录
删除整个数据页的内容
表文件大小未更改和mysql设计有关
比如想要删除 R4 这条记录:
InnoDB 直接将 R4 这条记录标记为删除,称为可复用的位置。如果之后要插入 ID 在 300 到 700 间的记录时,就会复用该位置。由此可见,磁盘文件的大小并不会减少。
通用删除整页数据也将记录标记删除,数据就复用用该位置,与删除默写记录不同的是,删除整页记录,当后来插入的数据不在原来的范围时,都可以复用位置,而如果只是删除默写记录,是需要插入数据符合删除记录位置的时候才能复用。
因此,无论是数据行的删除还是数据页的删除,都是将其标记为删除的状态,用于复用,所以文件并不会减小。
那怎么才能让表大小变小
DELETE只是将数据标识位删除,并没有整理数据文件,当插入新数据后,会再次使用这些被置为删除标识的记录空间,可以使用OPTIMIZE TABLE来回收未使用的空间,并整理数据文件的碎片。
OPTIMIZE TABLE 表名;
注意:OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。
另外,也可以执行通过ALTER TABLE重建表
ALTER TABLE 表名 ENGINE=INNODB
有人会问OPTIMIZE TABLE和ALTER TABLE有什么区别?
alter table t engine = InnoDB(也就是recreate),而optimize table t 等于recreate+analyze
Online DDL
最后,再说一下Online DDL,dba的日常工作肯定有一项是ddl变更,ddl变更会锁表,这个可以说是dba心中永远的痛,特别是执行ddl变更,导致库上大量线程处于“Waiting for meta data lock”状态的时候。因此在 5.6 版本后引入了 Online DDL。另外,公众号Java精选,回复Java面试,获取最新面试题资料,支持在线随时随地刷题。
Online DDL推出以前,执行ddl主要有两种方式copy方式和inplace方式,inplace方式又称为(fast index creation)。
相对于copy方式,inplace方式不拷贝数据,因此较快。但是这种方式仅支持添加、删除索引两种方式,而且与copy方式一样需要全程锁表,实用性不是很强。Online方式与前两种方式相比,不仅可以读,还可以支持写操作。
执行online DDL语句的时候,使用ALGORITHM和LOCK关键字,这两个关键字在我们的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按照INSTANT、INPLACE、COPY的顺序自动选择合适的模式。也可以指定ALGORITHM=DEFAULT,也是同样的效果。如果指定了ALGORITHM选项,但不支持的话,会直接报错。
OPTIMIZE TABLE 和 ALTER TABLE 表名 ENGINE=INNODB都支持Oline DDL,但依旧建议在业务访问量低的时候使用.
总结
delete 删除数据时,其实对应的数据行并不是真正的删除,仅仅是将其标记成可复用的状态,所以表空间不会变小。
可以重建表的方式,快速将delete数据后的表变小(OPTIMIZE TABLE 或ALTER TABLE),在 5.6 版本后,创建表已经支持 Online 的操作,但最好是在业务低峰时使用。
作者:低调的干货君
https://www.toutiao.com/i6935264754059477542
公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
------ THE END ------
精品资料,超赞福利!
>Java精选面试题<
3000+ 道面试题在线刷,最新、最全 Java 面试题!
期往精选 点击标题可跳转
【168期】面试官问:如果 MySQL 的自增 ID 用完了,怎么办?
【169期】面试官问:说说为什么要限流,有哪些解决方案?
【170期】MySQL 定时备份数据库(非常全),值得收藏!
【171期】面试官问:Spring 注解 @After,@Around,@Before 的执行顺序是?
【172期】从 Spring 的生产环境到 Spring Cloud 的配置
【173期】面试官问:引入 RabbitMQ 后,你如何保证全链路数据 100% 不丢失?
【174期】面试官问:StringBuider 在什么条件下、如何使用效率更高?
【175期】Nginx 详细的 nginx.conf 配置清单,一篇足够用了!
技术交流群!
最近有很多人问,有没有读者&异性交流群,你懂的!想知道如何加入。加入方式很简单,有兴趣的同学,只需要点击下方卡片,回复“加群”,即可免费加入交流群!
文章有帮助的话,在看,转发吧!
【176期】面试官:MYSQL 表数据 delete 删除后,为何还占用存储空间?相关推荐
- hive导数据到mysql 自增主键出错_面试官:MySQL表设计要注意什么?
本文公众号来源:孤独烟 作者:孤独烟 引言 这篇文章的很多问题,都是面试中实打实会问到的! 比如 OK,具体有下面这些问题 1.为什么一定要设一个主键? 2.你们主键是用自增还是UUID? 3.主键为 ...
- 基于Solr DIH实现MySQL表数据全量索引和增量索引
实现MySQL表数据全量索引和增量索引,基于Solr DIH组件实现起来比较简单,只需要重复使用Solr的DIH(Data Import Handler)组件,对data-config.xml进行简单 ...
- oracle删除库里的所有表,清空mysql指定库里全部表数据-自动删除所有表,有外键约束的表优先删除...
清空mysql指定库里所有表数据-自动删除所有表,有外键约束的表优先删除 由于要清空数据库数据 ,手动非常麻烦.网上找了一下,有一个Oracle的,参照它,在其上修改一下用于Mysql,把代码奉献如下 ...
- mysql数据删除后无法恢复数据恢复_Mysql数据库delete删除后数据恢复报告
原标题:Mysql数据库delete删除后数据恢复报告 数据库环境部署与故障原因: 本次恢复的数据库安装在客户本地服务器上,服务器操作系统为windows2008 r2 .在当前环境内安装有mysql ...
- solr mysql 增量索引_基于Solr DIH实现MySQL表数据全量索引和增量索引
实现MySQL表数据全量索引和增量索引,基于Solr DIH组件实现起来比较简单,只需要重复使用Solr的DIH(Data Import Handler)组件,对data-config.xml进行简单 ...
- 随机从mysql中读取_如何实现MySQL表数据随机读取?从mysql表中读取随机数据
文章转自 http://blog.efbase.org/2006/10/16/244/ 如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysq ...
- 利用Flume将MySQL表数据准实时抽取到HDFS
转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...
- mysql 表数据转储_在MySQL中仅将表结构转储到文件中
mysql 表数据转储 For this exercise, we will use the mysqldump utility the same as if we were backing up t ...
- flume mysql hdfs_利用Flume将MySQL表数据准实时抽取到HDFS
一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取从MySQL数据库增量抽取数据到HDFS,然后用HAWQ的外部表进行访问.这种方式只需要很少量的配置即可完成数据抽 ...
最新文章
- 暂缓上市!小马智行SPAC赴美上市计划推迟,自驾IPO路漫漫
- SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
- Unity iPhone Touch Animation Tutorial,untiy3d iphone简单动画开发教程
- java中jsp页面foreach遍历输出的使用
- 科比狂轰全场最高27分 联手鲨鱼同捧MVP奖杯
- java 静态 二维数组 转化hashmap_将一个二维数组转换为 hashmap 哈希表
- ppt课堂流程图_4个超实用的PPT制作技巧:开学提升备课质量,资深老师都在用
- centos安装python3_CentOS安装Python3-阿里云开发者社区
- CentOS好玩的代码
- java s_java中\s什么意思?
- 超市条码扫描枪使用前如何进行参数设置
- 高频故障-office背景有水印的解决方案
- edge 浏览器打开总跳向 hao.360
- 助力NBA复赛背后,NBA与可穿戴设备的纠葛缠斗
- sizebox模型下载_css盒子模型:内联盒模型、width、height、替换元素、边距、border...
- 高德vue-amap使用(一)标记点位获取地址及经纬度
- 三星官方smdkv210 uboot移植到我的s5pv210开发板
- 基于 Matlab 的通信系统仿真――数字通信大作业
- Ubuntu aria2c 下载
- grpc+gateway使用说明
热门文章
- C++第一阶段项目《小公举养成记》
- Android隐私合规检测方法
- 弘辽科技:淘宝新品上架用直通车推广还是超级推荐?哪个效果好?
- 用pyinstaller打包pytorch环境下的深度学习模型,实现通过exe程序实现界面显示模型的分类效果
- css选择器优先级顺序是什么?css基本选择器优先级的介绍
- java实现fifo算法_java算法:FIFO队列
- 操作系统:FIFO算法详解及代码演示
- linux日志stdout开关,linux bash关掉stdout和stderr
- Linux - 网络服务器开发(全)
- 前后端交互之使用ajax方法实现form表单的提交