January 27, 2013

[MySQL学习] Innodb change buffer(2) 相关函数及流程

简单的代码跟踪,顺便弄清了之前一直困惑的bp->watch的用途。。。。 //////////////////////////////// A.相关结构体 在介绍ibuf在Innodb中的使用前,我们先介绍下相关的结构体及全局变量。 我们知道通过Ibuf可以缓冲多种操作类型,每种操作类型,在内部都有一个宏与之对应: IBUF_OP_INSERT IBUF_OP_DELETE_MARK IBUF_OP_DELETE 至于对update操作的缓冲,由于二级索引记录的更新是先delete-mark,再insert,因此其ibuf实际有两条记录IBUF_OP_DELETE_MARK+IBUF_OP_INSERT ibuf是全局对象,用于控制change buffer的控制对象,从ibuf_struct结构体来看,其中存储了ibuf索引树信息和其他一些统计信息。 ibuf_flush_count计数器,计算调用ibuf_should_try的次数 ibuf_use用于内部标示当前使用的change buffer 类型 由于从5.5开始扩展了change buffer缓冲的操作类型,因此在ibuf记录的格式也需要做变化,需要记录在同一个page上的操作计数器并标示操作类型 Ibuf entry的格式在ibuf0ibuf.c文件头部的注释中有详细描述: 4字节 space id 1字节,marker (0) 区分老版本 4字节 page no 类型信息,包括: 5.5特有的counter(2字节) 、操作类型(1字节) 、flags1(1字节, 值为IBUF_REC_COMPACT.   剩下的是实际数据 B.何时决定使用ibuf: 当我们更新一条数据的时候,首先是更新聚集索引记录,然后再更新二级索引,当通过聚集索引记录寻找搜索二级索引Btree时,会做判断是否可以进行ibuf,判断函数为ibuf_should_try row_update_for_mysql->row_upd_step->row_upd->row_upd_sec_step->row_upd_sec_index_entry->row_search_index_entry->btr_pcur_open_func->btr_cur_search_to_nth_level->ibuf_should_try 而对于二级索引Purge操作的缓冲,则调用如下backtrace: row_purge->row_purge_del_mark->row_purge_remove_sec_if_poss->row_purge_remove_sec_if_poss_leaf->row_search_index_entry->btr_pcur_open_func->btr_cur_search_to_nth_level->ibuf_should_try 可以看到最终的backtrace都汇总到row_search_index_entry->btr_pcur_open_func->btr_cur_search_to_nth_level->ibuf_should_try 因此以下我们也不区分对待这两种backtrace类型  ibuf_should_try作为基础判断是否使用ibuf,其判断逻辑为: 1.打开了change buffer(即ibuf_use != IBUF_USE_NONE) 2.不是聚集索引,聚集索引不可以做Ibuf 3.对于唯一索引,不缓存插入操作(BTR_INSERT_OP) 当判断可以缓存时,对ibuf_flush_count++,每四次(ibuf_flush_count % 4 == 0),调用一次buf_LRU_try_free_flushed_blocks,尝试去把buffer pool中LRU链表上干净的block(已经和磁盘同步)转移到free […]