InooDB的文件格式,ibd利用主键索引到具体数据,数据都在叶节点上,frm就是一些数据库的元信息了。
重点看看ibd文件,这个文件由多个段组成,每个段和一个索引相关。
文件的结构是不会随着数据行的删除而变化的,但段则会跟着构成它的更小一级单位——区的变化而变化。页则是区的下一级构成单位,默认体积为16KB。
每个页(逻辑上讲即叶子节点)是包含了2-N行数据,根据主键排列。
InnoDB不是按行的来操作的,它可操作的最小粒度是页,页加载进内存后才会通过扫描页来获取行/记录。
页合并
当你删了一行记录时,实际上记录并没有被物理删除,记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。
当页中删除的记录达到MERGE_THRESHOLD
(默认页体积的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
页合并发生在删除或更新操作中,关联到当前页的相邻页。如果页合并成功,在INFOMATION_SCHEMA.INNODB_METRICS
中的index_page_merge_successful
将会增加
页分裂
如果一个数据应该被插入第10页,但是10页满了,11页也满了,那怎么办?
直接把第10页分裂成两个,页分裂会发生在插入或更新,并且造成页的错位(dislocation,落入不同的区)
InnoDB用INFORMATION_SCHEMA.INNODB_METRICS
表来跟踪页的分裂数。可以查看其中的index_page_splits
和index_page_reorg_attempts/successful
统计。
一旦创建分裂的页,唯一将原先顺序恢复的办法就是新分裂出来的页因为低于合并阈值(merge threshold)被删掉。这时候InnoDB用页合并将数据合并回来。
另一种方式就是用OPTIMIZE重新整理表。这可能是个很重量级和耗时的过程,但可能是唯一将大量分布在不同区的页理顺的方法。
要注意的是在合并和分裂的过程中会加锁