首页 > 数据库 >MySQL Delete 表数据后,磁盘空间并未释放,为什么?

MySQL Delete 表数据后,磁盘空间并未释放,为什么?

时间:2024-03-26 09:15:51浏览次数:38  
标签:删除 记录 MySQL 磁盘空间 DDL TABLE 数据 Delete

有开发小哥咨询了一个问题,记录一下处理过程分享给有需要的朋友。

问题如下:

MySQL数据库中有几张表增删比较频繁、数据变动剧烈且数据量大,导致数据增长过快,磁盘占用多。为了节约成本,定期进行数据备份,并通过delete删除表记录,但是执行delete操作后发现磁盘空间并未释放,这是为什么?

MySQL数据结构

MySQL数据库中的表,一般为表结构和表数据。表结构占用空间都是比较小的,一般都是表数据占用的空间。

InnoDB 中采用了 B+ 树作为存储数据的结构,也就是常说的索引组织表。在InnoDB中,delete操作并不会真的删除数据,MySQL实际上只是给要删除的数据打了标记,标记为删除。磁盘所占空间不会变小,即表空间并没有真正被释放。

这样的设计是因为:如果在磁盘上移除之后,很多其它的记录需要在磁盘上重新排列,这会消耗大量的性能。(例如:一个大表,存在索引,删除了其中一行,那么整个索引结构就会发生变化,随之而来的改变索引结构,必将带来磁盘IO)

所有被删除的记录会组成一个垃圾链表,这个链表记录占用的空间叫可重用空间。新插入的记录可覆盖此空间。

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

 

 

 

InnoDB 直接将 R4 这条记录标记为删除,称为可复用的位置。如果之后要插入 ID 在 300 到 700 间的记录时,就会复用该位置。由此可见,磁盘文件的大小并不会减少。

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

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

数据空洞

这些被标记为删除的记录,就是数据空洞。不仅浪费空间,还影响查询效率。

MySQL底层是以数据页为单位来存储和读取数据的,每次向磁盘读一次数据就是读一个数据页,每访问一个数据页就对应一次IO操作,磁盘IO访问速度是很慢的。

如果一个表上存在大量的数据空洞,原本只需要一个数据页就保存的数据,由于被很多空洞占用了空间。不得不增加其它数据页来保存数据,相应的MySQL在查询相同数据的时候,就不得不增加磁盘IO操作,从而影响查询速度。

不仅删除会造成数据空洞,插入和更新同样会造成数据空洞。因此一个表在经过大量频繁的增删改后,难免会产生数据空洞,影响查询效率。在生产环境中直接表现为原本查询很快的表变的越来越慢。

那怎么才能让表大小变小

可以使用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

DBA的日常工作肯定有一项是ddl变更,ddl变更会锁表,这个可以说是dba心中永远的痛,因此在 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,否则建议指定它的锁类型。

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

 

标签:删除,记录,MySQL,磁盘空间,DDL,TABLE,数据,Delete
From: https://www.cnblogs.com/ataoxz/p/18095820

相关文章

  • [附源码]计算机毕业设计高校教材管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍随着高校教育资源的不断扩充和教育体系的日益复杂化,高效的教材管理变得尤为重要。一个专业的高校教材管理系统能够实现教材信息的集中管理、库存状态实时监控、......
  • [附源码]计算机毕业设计大学生创新项目管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍随着高等教育的不断发展,大学生创新项目成为培养学生创新能力和实践能力的重要途径。有效的项目管理对于确保创新项目的顺利进行和高质量完成至关重要。然而,目前......
  • [附源码]计算机毕业设计疫情下高校学生离校系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍疫情的突发和持续影响使得高校学生离校管理面临前所未有的挑战。为了确保校园疫情防控的有效进行,同时保障学生的健康安全和合理流动,一个计算机毕业设计的疫情下......
  • C-04.MySQL逻辑架构
    C-04.逻辑架构1.逻辑架构剖析1.1服务器处理客户端请求首先MySQL是典型的C/S架构,即Client/Server架构,客户端使用的是mysql,服务器端程序使用的mysqld。不论客户端进程和服务器进程是采用那种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(SQL语句),服务器......
  • Oracle与MySQL的差异和对比
    Oracle与MySQL的差异和对比:配套hands-on参考脚本。方便客户针对培训课件内容进行动手实践,加强理解。-----------------------------------主题:Oracle与MySQL的差异和对比--一、MySQL的基础特性--二、重要特性差异对比--三、性能对比和优化技巧--------------......
  • 15. sysbench和MySQL IO
    MySQL的IO使用情况 iotopiotop-umysql#-u表示监控哪个user的进程,所以前提是你的mysql服务是用mysql用户启动的该命令只能看到MySQL的线程ID(ThreadID) performance_schema.threadsroot@mysqldb13:42:[performance_schema]>selectname,type,PROCESSLIST_ID,......
  • MySQL索引18连问,谁能顶住
    前言过完这个节,就要进入金银季,准备了18道MySQL索引题,一定用得上。作者:感谢每一个支持:github1.索引是什么索引是一种数据结构,用来帮助提升查询和检索数据速度。可以理解为一本书的目录,帮助定位数据位置。索引是一个文件,它要占用物理空间。2.MySQL索引有哪些......
  • MySQL 数据库的日志管理、备份与恢复
    一.数据库备份1.数据备份的重要性 备份的主要目的是灾难恢复。在生产环境中,数据的安全性至关重要。任何数据的丢失都可能产生严重的后果。造成数据丢失的原因:程序错误人为,操作错误,运算错误,磁盘故障灾难(如火灾、地震)和盗窃.容灾概念:容灾(DisasterRecovery,DR)......
  • docker-运行mysql服务
    环境说明linux系统版本:lsb_release-a  docker版本:docker-v  不同的操作系统以及软件版本,可能会遇到不一样的问题,一定要注意版本问题。 查看docker中mysql的版本,可以去官网,需要kx上网才能打开。https://hub.docker.com/ 最好是确认自己的服务器已经设置......
  • linux下的mysql常见用法
    linux下的mysql常见用法1.连接Mysql1.1连接到本机上的Mysql键入命令mysql-uroot-p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密码前必须没有空格,否则让你重新输入密码.如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中......