表数据删掉一半,为什么表文件大小不变
InnoDB表包含两部分: 表结构定义和数据。
参数innodb_file_per_table
1.设置off 表数据存放在系统共享空间,也就是跟数据字典放到一起。
2.设置on,表数据存储在一个以.ibd为后缀的文件中。
drop table 命令可以直接删除这个文件。
如果放到 共享表空间,即使表删除,空间也不会回收。
数据删除流程: 数据 R1 R2 R3 -- 插入顺序,自增
删除一条R2记录,InnoDB引擎只会把该记录标记为删除。如果之后插入在R1和R3之间的数据,可能会复用这个位置。
但是磁盘文件大小并不会缩小。
如果删掉一个数据页上的所有记录,整个页就会被复用。
数据页的复用跟记录的复用是不同的。
数据页被复用不用局限于数据插入的索引范围。
delete 数据只是把数据标记为可复用,不能回收表空间。这些可复用而没有被使用的空间,看起来就是一个空洞。不止删除会造成数据的空洞,插入数据也会造成空洞。
如果数据是按照索引递增的顺序插入,那么索引是紧凑的。
但如果数据是随机插入的,就会造成索引的数据页分裂。
更新索引上的值,可以理解为删除一个旧值,再插入一个新值。也会造成空洞。
也就是说,经过大量增删改的表,都可能是存在空洞的。所以把这些空洞去掉就达到了收缩表的目的。
表重建:
msql 5.5之后
alter table A engine=InnoDB命令,mysql 会自动创建表,完成转存数据,交换表名,删除旧表的操作。
如果有新数据写入表,会造成数据丢失。因此,整个DDL过程中,表不能更新。也就是说整个DDL不是Online的。
mysql 5.6之后引入 Online DDL,对整个操作流程做了优化。
1.建立一个临时文件,扫描表主键所有数据页。
2.用数据页中表记录生成B+树,存储到临时文件。
3.生成临时文件的过程中,将对表操作记录在一个日志文件(row log)中
4.临时文件生成后,将日志文件中操作应用到临时文件中,得到逻辑上于表相同的数据文件
5.用临时文件替换表中文件。
用于记录,学习。