【学习计划】《MySQL实战45讲》13 | 为什么表数据删掉一半,表文件大小不变?


一、新名词

1. “Online DDL”

重建表的过程中,允许对表做增删改操作

Online DDL,重建表的流程:

  1. 建立一个临时文件,扫描表A主键的所有数据页;
  2. 用数据页中表A的记录生成B+树,存储到临时文件中;
  3. 生成临时文件的过程中,将所有对A的操作记录在一个日志文件(row log)中,对应的是图中state2的状态;
  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表A相同的数据文件,对应的就是图中state3的状态;
  5. 用临时文件替换表A的数据文件。
    Online DDL
    特别注意:重建方法都会扫描原表数据和构建临时文件。对于很大的表来说,这个操作是很消耗IO和CPU资源的。因此,如果是线上服务,你要很小心地控制操作时间。如果想要比较安全的操作的话,推荐使用GitHub开源的gh-ost来做。

2. “inplace”

表A重建出来的数据是放在“tmp_file”里的,这个临时文件是InnoDB在内部创建出来的。整个DDL过程都在InnoDB内部完成。对于server层来说,没有把数据挪动到临时表,是一个“原地”操作。


二、新指令

alter table

重建表

alter table A engine=InnoDB;

特别注意:MySQL 5.5及之前的版本,这个命令是会阻塞DML


三、新参数

1. innodb_file_per_table

表数据的存储方式

  • 这个参数设置为OFF表示的是,表的数据放在系统共享表空间,也就是跟数据字典放在一起;
  • 这个参数设置为ON表示的是,每个InnoDB表数据存储在一个以 .ibd为后缀的文件中。

四、新知识点

1. drop table 和 delete

  • drop table 命令回收表空间。
  • delete 命令不能回收表空间。delete 命令其实只是把记录的位置,或者数据页标记为了“可复用”,但磁盘文件的大小是不会变的。

2. 数据页的复用

数据页的复用:可以复用到任何位置。

3. 删除数据造成的空洞

当有ID(300,400,500)的数据时,删除ID(400),插入ID(800)时,ID(400)的位置不会被复用。

4. 插入数据造成的空洞

page A满了,ID(300,400,500)。这时插入ID(450),会申请一个新的页面page B来保存数据了。页分裂完成后,page A的末尾就留下了空洞。此时page A,ID(300,400);page B,ID(450,500)。

5. Online 和 inplace 的关系

  • DDL过程如果是Online的,就一定是inplace的;
  • 反过来未必,也就是说inplace的DDL,有可能不是Online的。截止到MySQL 8.0,添加全文索引(FULLTEXT index)和空间索引(SPATIAL index)就属于这种情况。

6. optimize table、analyze table和alter table这三种方式重建表的区别。

  • 从MySQL 5.6版本开始,alter table t engine = InnoDB(也就是recreate)默认的就是上面图的流程了;
  • analyze table t 其实不是重建表,只是对表的索引信息做重新统计,没有修改数据,这个过程中加了MDL读锁;
  • optimize table t 等于recreate+analyze。

五、小结

数据库中收缩表空间的方法

  • 如果要收缩一个表,只是delete掉表里面不用的数据的话,表文件的大小是不会变的,还要通过alter table命令重建表,才能达到表文件变小的目的。
  • 重建表的两种实现方式,Online DDL的方式是可以考虑在业务低峰期使用的,而MySQL 5.5及之前的版本,这个命令是会阻塞DML的,这个需要特别小心。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值