为什么数据库表的数据删除了一般空间却没有减少?

1.mysql innodb引擎的一张表的数据分为两种:表结构、表数据

  表结构数据一般以.frm形式存储,版本8以后允许存储在系统数据表中了,因为占用空间比较小,所以对本文的问题没有过多的影响。

  表数据可以以.ibd的文件单独存储也可以存储在系统共享的表空间,用innodb_file_per_table 这个参数进行控制;

  OFF的时候表示存储在系统共享的表空间,ON的时候单独存储,建议设置为ON,drop table的时候删除表,无法缩小系统共享表空间,但是可以直接删除.ibd的文件。

 

2.为什么会造成数据页上的空洞

  在删除、增加、不长访问的两个数据页合并的时候都会导致出现空的行或者数据页,这些空的行或者数据页会被标识为可复用;

  行的复用需要满足范围条件,数据页的复用则不需要;

  这些空的行和数据页也是占用空间的,称为空洞;

 

3.如何解决这些空洞

  在5.6版本以前

  • 生成一张临时表,把表a中的数据copy过来;
  • 把临时表的名字更改成A表的名字
  • 删除旧表,新表替换成A表
  • 整个过程是在server层完成的,创建的临时表存在server的空间里
  • 整个过程不是online  不允许DDL,存在DML的写锁  

 

 5.6版本以后

  过程如下

  • 创建一张临时表表,DML的写锁退化成读锁
  • 把A表中的数据逐一写到临时表中
  • 在往临时表中写数据的过程中,把对表A的DDL操作记录到日志中
  • 更改临时表的名字为A 并把日志中的DDL记录完整
  • 删除旧表 更替新表
  • 整个过程是online的
  • 在innodb引擎中进行 是inplace的(并不是所有innodb的inplace的操作都是online的,但是online的一定是inplace;截止到 MySQL 8.0,添加全文索引(FULLTEXT index)和空间索引 (SPATIAL index) 就属于这种情况)  

  

 

  •  从 MySQL 5.6 版本开始,alter table t engine = InnoDB(也就是 recreate)默认的就是上面图 4 的流程了;
  • analyze table t 其实不是重建表,只是对表的索引信息做重新统计,没有修改数据,这个过程中加了 MDL 读锁;
  • optimize table t 等于 recreate+analyze。
posted @ 2022-06-14 10:57  超超小仙女  阅读(525)  评论(0编辑  收藏  举报