January 13, 2013

[MySQL学习] Innodb change buffer(1)之初识篇

从MySQL5.5版本开始,Insert buffer更名为change buffer,除了缓冲对二级索引的insert操作,还包括update/delete/后台purge操作,由参数innodb_change_buffering来控制。因此这里统一称为change buffer。 ////////////////////////////////////////////////////////// 当更新/插入的非聚集索引的数据所对应的页不在内存中时(对非聚集索引的更新操作通常会带来随机IO),会将其放到一个insert buffer中,当随后页面被读到内存中时,会将这些变化的记录merge到页中。当服务器比较空闲时,后台线程也会做merge操作 但change buffer会占用buffer pool,并且在非聚集索引很少时,并不总是必要的,反而会降低buffer pool做data cache的能力。 change buffer只作用于二级索引的叶子节点,并且无法处理可能导致索引分裂或合并的操作。 另外和5.1有所不同的是,由于5.5引入了更多buffer的操作,因此需要在ibuf中保证对一个page的操作是有序的。 当文件页在buffer pool中时,就直接操作文件页,而不会去考虑ibuf;当文件页从磁盘读入内存时,总会去尝试做Merge。 在表空间中,有ibuf bitmap来跟踪记录每个Page空闲空间的范围,以避免Page溢出或被清空。 在FSP_HDR页随后是ibuf_bitmap页,其中FSP_HDR在表空间的第一个Page上。每个FSP_HDR只能管理256 个extent的信息(也就是16384个Page),因此每隔16384个page,会有一个类似FSP_HDR的Page来描述随后的extend信息,相应的每个ibuf_bitmap也可以管理16384个page,每个page的空闲空间用一个字节来表示。 从Jeremy Cole大神博客上扣的图: 另外,change buffer的数据实际上是在系统表空间ibdata中,对应的内部系统表名为SYS_IBUF_TABLE。因此change buffer也会存储到磁盘。 其中,ibdata的第4个page(FSP_IBUF_HEADER_PAGE_NO)存储了ibuf数的SEGEMENT信息。 第5个page(FSP_IBUF_TREE_ROOT_PAGE_NO)是ibuf树的根节点。 在Percona版本的5.5中,有几个参数来控制change buffer的行为: innodb_change_buffering 取值包括all/none/inserts/deletes/changes/purges 其中deletes包括了delete和update操作(二级索引的update是 标记删除旧记录,再插入新记录). innodb_ibuf_accel_rate 默认值为100,用于控制做change buffer merge的page数量 一般作为ibuf_contract_for_n_pages函数的第二个参数 是宏PCT_IBUF_IO,定义如下: #define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity                  * srv_ibuf_accel_rate * […]