为什么数据库表的数据删除了一般空间却没有减少?
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。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通