点击上方“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 删除后,为何还占用存储空间?相关推荐

  1. hive导数据到mysql 自增主键出错_面试官:MySQL表设计要注意什么?

    本文公众号来源:孤独烟 作者:孤独烟 引言 这篇文章的很多问题,都是面试中实打实会问到的! 比如 OK,具体有下面这些问题 1.为什么一定要设一个主键? 2.你们主键是用自增还是UUID? 3.主键为 ...

  2. 基于Solr DIH实现MySQL表数据全量索引和增量索引

    实现MySQL表数据全量索引和增量索引,基于Solr DIH组件实现起来比较简单,只需要重复使用Solr的DIH(Data Import Handler)组件,对data-config.xml进行简单 ...

  3. oracle删除库里的所有表,清空mysql指定库里全部表数据-自动删除所有表,有外键约束的表优先删除...

    清空mysql指定库里所有表数据-自动删除所有表,有外键约束的表优先删除 由于要清空数据库数据 ,手动非常麻烦.网上找了一下,有一个Oracle的,参照它,在其上修改一下用于Mysql,把代码奉献如下 ...

  4. mysql数据删除后无法恢复数据恢复_Mysql数据库delete删除后数据恢复报告

    原标题:Mysql数据库delete删除后数据恢复报告 数据库环境部署与故障原因: 本次恢复的数据库安装在客户本地服务器上,服务器操作系统为windows2008 r2 .在当前环境内安装有mysql ...

  5. solr mysql 增量索引_基于Solr DIH实现MySQL表数据全量索引和增量索引

    实现MySQL表数据全量索引和增量索引,基于Solr DIH组件实现起来比较简单,只需要重复使用Solr的DIH(Data Import Handler)组件,对data-config.xml进行简单 ...

  6. 随机从mysql中读取_如何实现MySQL表数据随机读取?从mysql表中读取随机数据

    文章转自 http://blog.efbase.org/2006/10/16/244/ 如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysq ...

  7. 利用Flume将MySQL表数据准实时抽取到HDFS

    转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...

  8. mysql 表数据转储_在MySQL中仅将表结构转储到文件中

    mysql 表数据转储 For this exercise, we will use the mysqldump utility the same as if we were backing up t ...

  9. flume mysql hdfs_利用Flume将MySQL表数据准实时抽取到HDFS

    一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取从MySQL数据库增量抽取数据到HDFS,然后用HAWQ的外部表进行访问.这种方式只需要很少量的配置即可完成数据抽 ...

最新文章

  1. 暂缓上市!小马智行SPAC赴美上市计划推迟,自驾IPO路漫漫
  2. SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
  3. Unity iPhone Touch Animation Tutorial,untiy3d iphone简单动画开发教程
  4. java中jsp页面foreach遍历输出的使用
  5. 科比狂轰全场最高27分 联手鲨鱼同捧MVP奖杯
  6. java 静态 二维数组 转化hashmap_将一个二维数组转换为 hashmap 哈希表
  7. ppt课堂流程图_4个超实用的PPT制作技巧:开学提升备课质量,资深老师都在用
  8. centos安装python3_CentOS安装Python3-阿里云开发者社区
  9. CentOS好玩的代码
  10. java s_java中\s什么意思?
  11. 超市条码扫描枪使用前如何进行参数设置
  12. 高频故障-office背景有水印的解决方案
  13. edge 浏览器打开总跳向 hao.360
  14. 助力NBA复赛背后,NBA与可穿戴设备的纠葛缠斗
  15. sizebox模型下载_css盒子模型:内联盒模型、width、height、替换元素、边距、border...
  16. 高德vue-amap使用(一)标记点位获取地址及经纬度
  17. 三星官方smdkv210 uboot移植到我的s5pv210开发板
  18. 基于 Matlab 的通信系统仿真――数字通信大作业
  19. Ubuntu aria2c 下载
  20. grpc+gateway使用说明

热门文章

  1. C++第一阶段项目《小公举养成记》
  2. Android隐私合规检测方法
  3. 弘辽科技:淘宝新品上架用直通车推广还是超级推荐?哪个效果好?
  4. 用pyinstaller打包pytorch环境下的深度学习模型,实现通过exe程序实现界面显示模型的分类效果
  5. css选择器优先级顺序是什么?css基本选择器优先级的介绍
  6. java实现fifo算法_java算法:FIFO队列
  7. 操作系统:FIFO算法详解及代码演示
  8. linux日志stdout开关,linux bash关掉stdout和stderr
  9. Linux - 网络服务器开发(全)
  10. 前后端交互之使用ajax方法实现form表单的提交