为什么 MySQL 执行完 Delete 操作之后,空间没有释放?

文章目录

  • 为什么 MySQL 执行完 Delete 操作之后,空间没有释放?
    • Mysql数据结构
    • 表文件大小未更改和mysql设计有关
    • 那怎么才能让表大小变小
    • Online DDL
      • ALGORITHM选项
      • LOCK选项
    • 总结

为了节约成本,定期进行数据备份,并通过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。

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 的操作,但最好是在业务低峰时使用。

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、收藏,您的支持是我坚持写作最大的动力。

为什么 MySQL 执行完 Delete 操作之后,空间没有释放?相关推荐

  1. MySQL中DELETE操作磁盘空间不会减少的原因

    MySQL中delete操作 在InnoDB中,delete操作并不会真的删除数据,mysql实际上只是给要删除的数据打了标记,标记为删除.磁盘所占空间不会变小,即表空间并没有真正被释放. 这样设计的 ...

  2. Mysql delete删除表数据之后,表空间没有释放的问题

    事件起因: 今天运维人员找我,说我们的数据库磁盘空间满了.于是提供了一些删除表数据的sql给他,让他执行下. 执行之后,查询数据库,表数据是不在了,但是问题来了. 磁盘空间并没有释放,这是为啥咧??? ...

  3. 呕心沥血整理出来的mysql执行流程,一定要看!

    我曾踏足山巅,也曾进入低谷,二者都令我受益良多. -----宝石骑士-塔里克 你有多了解mysql? 说到mysql,相信很多人对他都不陌生,尤其是后端开发和DBA,更是熟悉地不能再熟悉了,什么mys ...

  4. mysql安装后第一次操作_MySQL数据库之mysql 安装成功以及第一次安装成功初始化密码操作...

    本文主要向大家介绍了MySQL数据库之mysql 安装成功以及第一次安装成功初始化密码操作 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 一 把文件解压到一个目录下 技术分享图 ...

  5. js等待异步执行完再执行,js如何让代码同步执行

    JS方法怎么同步执行 . 方法1内部用了var表示内部变量执行完一次后会自动释放:方法2内的变量cc不能与方法1重名:示例代码如下测试可以varstr='';functioncfun(obj){str ...

  6. 删除Oracle表空间,释放硬盘空间

    1.查询用户和表空间 select username,default_tablespace from dba_users; 2.删除表空间: 2.1可以先将其offline alter tablesp ...

  7. 为什么mysql的delete操作不释放磁盘空间

    在 InnoDB 中,delete 操作并不会真的删除数据,mysql 实际上只是给要删除的数据打了标记,标记为删除.磁盘所占空间不会变小,即表空间并没有真正被释放. 一. MySQL 删除数据几种情 ...

  8. MYSQL笔记:删除操作Delete、Truncate、Drop用法比较

    今天小编给大家梳理一下MYSQL删除操作Delete.Truncate.Drop用法有什么区别,到底该如何合理使用,希望对大家能有帮助! 1.执行速度比较 Delete.Truncate.Drop关键 ...

  9. MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题)

    MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题) 1.背景知识 1.1 为什么会有碎片 MySQL 中 insert 与 update 都可能导致页分裂,这样就存在碎片 ...

最新文章

  1. FT《金融时报》:中国巨头争夺企业级市场,阿里云份额已近六成
  2. 自动化测试中,测试数据如何管理?
  3. 雅虎开源发布/订阅消息平台Pulsar
  4. 使用maven快速构建SSM项目
  5. [Machine learning] 国外程序员整理的机器学习资源大全
  6. Fiori里前后台ETAG处理
  7. DOM(二)——XML DOM
  8. AdaBoost算法详解与python实现
  9. 关于java.lang.ClassNotFoundException: org.git.mm.mysql.Driver的解决办法
  10. redis专题:使用redis实现分布式锁
  11. echarts 图例太多放不下怎么办_段码液晶屏笔段太多,引脚放不下怎么办?
  12. fastble找不到手机_Android蓝牙库FastBle的基础入门使用
  13. 甘肃银行借助HDIM打造综合数据保护平台
  14. Lottie 动画AE+Bodymovin导出的JSON文件解读
  15. 全球最大的同性交友网站,竟然还有这些骚操作
  16. 项目中有时候为什么加载不出来图片
  17. PHP是TM最美的语言,我的文章是最棒的狗粮
  18. 野派,阡陌人生路,泪断愁肠,滚滚红尘中,情留心房
  19. Kafka性能压测完整版
  20. 25个最适合摄影师的WordPress主题(2020)

热门文章

  1. 吐槽西电python oj 文章检测
  2. 广工操作系统课设--多用户多级目录的文件系统
  3. 微博舆情 之 特定话题情感分析
  4. 面向对象的特点?对象模型、动态模型和功能模型3种模型之间的关系?
  5. memcached + mysql_memcached+Mysql(主从)
  6. ubuntu1804系统设置在哪里_ubuntu1804安装后设置
  7. Spring注解解析 | P/C命名空间
  8. ### Cause: java.sql.SQLSyntaxErrorException: ORA-00903: 表名无效
  9. Django框架 (一)———基本简介+基本认知
  10. DBeaver修改默认存储sql文件的位置