13删除数据但文件大小不变

InnoDB表包含:表结构定义和数据
MySQL8.0前表结构是存在.frm文件,8.0版本允许表结构定义放在系统数据表中

表数据可存放在共享表空间 也可是单独文件。innodb_file_per_table on:单独存放

数据删除

数据页上删除一行或整页会标记为可复用,没有压缩
若两个相邻数据页利用率低,会合并到一个,标记另一个为可复用

因此delete只是将记录标记为可复用,磁盘文件不会变小。这些可复用,却没有被使用的空间看起来像”空洞”。
插入数据页分裂也会出现”空洞”
更新可理解为删除再插入,是一个道理。

解决数据空洞:重建表

重建表

alter table A engine=InnoDB,ALGORITHM=copy;
在server层新建临时表,复制时阻塞读写

alter table A engine=InnoDB,ALGORITHM=inplace;
MySQL5.6版本引入Online DDL,不新建临时表,在innodb上新建临时文件,将原表数据存储到临时文件中,重建表过程中对表的操作会记录在日志里,后续应用到临时文件,临时文件替换原表。

在alter语句启动时要获取MDL写锁,在拷贝数据前退化为读锁,MDL读锁不会阻塞增删改查。
MDL写锁时间很短,对业务来说可认为是Online

即使是Online重建表还是很消耗CPU和IO,对于大表重建要把控时间,推荐使用gh-ost

alter table A engine=InnoDB,ALGORITHM=instant;
修改表元数据,不复制和重建表,速度很快,不阻塞。

analyze table t索引重新统计,加MDL读锁

optimize table t 相当于recreate + analyze

truncate :drop+create

问题

alter table t engine=InnoDB 会让一个表占用的空间反而变大了?
本身表没有空洞,重建表时会预留10%的页空间