背景:
–每个索引有两个segment,用于管理叶子节点和非叶子节点
–每个segment包含多个extend,extend是一次文件扩展单元(64个page)
–每个page默认非压缩表为16k
相关tips:
space header :表空间的第一个page中,用于管理所有下述结构,
file segment inode用于描述segment信息
每个extend都对应一个extend descriptor,描述信息单独记录在一个page中,占用40个字节,一个page可以存放256个描述符,因此每隔(256*64)个page会有一个单独的extend descriptor page
segment inode 用于管理其对应的segment信息,其中记录了该segment拥有的extend的相关信息(以及该segment内的碎片page信息) ,一个page内可以存储的segment inode个数为fsp_seg_inodes_per_page(zip_size)。segment inode的位置信息可以由btree的根节点中的segment header得到。
问题:
每个segment通过一个宏fseg_fillfactor来决定什么时候进行段扩展,默认为8,也就是说,当一个segment中保留的page数少于1/8时,就要对其进行扩展一个extend,也就是64个page。这个值是硬编码的,facebook将其修改成可动态调整的值,根据其测试,可以减少不少空闲page(达到10%)
上述逻辑的判断是在函数fseg_alloc_free_page_low中实现,当然比描述的更加复杂(一堆if else :-(..)
把patch backport到了5.5.18,并跑了下test case,两个相同结构的表,load相同的数据。
innodb_segment_reserve_factor = 8 ibd文件大小为20971520
innodb_segment_reserve_factor = 500, ibd文件大小为23068672
大约减小了9%
更主要的是从学习该patch的过程中,顺便了解了一下fsp相关知识。