Sunskey

日拱一卒,不期而至

0%

数据表空间回收

数据表空间回收

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