数据表空间回收
MySQL8.0版本前,表的结构是存在以.frm为后缀的文件里。而8.0后,允许把表结构定义放在系统数据表中。因为结构定义占用的空间很小。
表数据既可以存在共享表空间里面,也可以是单独的文件。这个行为是由参数innodb_file_per_table控制。从Mysql5.6.6以后,默认为on。
off:表的数据放在系统共享表空间,也就是跟数据字典放在一起;
on:每个InnoDB表数据存储在一个以.idb为后缀的文件中。
删除数据
删除一个数据页上的所有记录,整个数据页的复用跟记录的复用是不同的。
使用delete 命令只是把记录或者数据页标记为“可复用”,不能回收表的空间,而没有使用的空间,看起来就像空洞,不止删除数据回暖造成空洞,插入数据也会。
重建表
新建一个与原表结构相同的新表,然后按照主键ID递增的顺序,把数据一行一行地从原表读到表B,然后用B替换A,从而起到收缩表A空间的作用,解决空洞的问题。
在MySQL5.5之后,可以之前使用alter table A engine = InnoDB来重建表。
在这个过程中,如果有新数据要写入表A的话,就回造成数据丢失。
为了保证整个重建表的正常,原表不能进行更新,5.6版本后引入了Online DDL,优化了该过程。
Online DDL
1.建立一个临时文件,扫描表A主键的所有数据页。
2.用数据页中表A的记录生成B+树,存储到临时文件中。
3.生成的临时文件的过程中,将所有对A的操作记录再一个日志文件(row log)中。
4.临时文件生成后,将日志文件的操作应用到临时文件中,得到与表A相同的数据文件。
5.用临时文件替换表A的数据文件。
整个过程中,MDL的写锁会转化为MDL的读锁,从而提高效率。
整个过程很消耗CPU和IO,如果想安全操作,推荐使用gh-os来做。
Online和inplace 的区别
对于server层没有把数据移动到临时表,是一个“原地”操作,这就过程称为inplace。
1.DDL过程如果是Online的,就一定是inplace的
2.inplace的DDL,有可能不是Online的。8.0后添加全文索引(FULLTEXT index)和空间索引(SPATIAL index)就属于这种情况。
optimize table、analyze table和alter table三种重建表的区别
1.从MySQL 5.6版本开始,alter table t engine = InnoDB默认就是Online DDL。
2.analyze table t,只是对索引信息进行重新统计,没有修改数据,加入MDL读锁。
3.optimize table = analyze + alter