文章目录
  1. 插入缓冲
  2. Change Buffer
  3. Insert Buffer的内部实现
  4. 合并插入缓冲

插入缓冲

InnoDB存储引擎设计插入缓冲用于非聚集索引的插入与更新操作,并非每次直接插入索引页;而是先判断插入的非聚集索引页是否在缓冲池中,若在,则直接插入;否则,先将其放入Insert Buffer对象中,再以一定的频率和情况进行Insert Buffer与辅助索引页子节点的merge(合并)操作,这时可将多个插入合并到一个操作中,从而提高了非聚集索引插入的性能。

Insert Buffer的使用需同时满足以下两个条件

  • 索引是辅助索引;
  • 索引不是唯一的(在插入缓冲时,InnoDB存储引擎并不会去查找索引页来判断插入记录的唯一性);

Change Buffer

InnoDB存储引擎对INSERT、DELETE、UPDATE均进行缓冲,即Insert Buffer、Delete Buffer与Purge Buffer;

Insert Buffer的内部实现

在MySQL的实现中,全局只有一棵Insert Buffer树,负责对所有表的辅助索引进行Insert Buffer。在通过idb文件进行恢复时,还需要进行REPAIR TABLE操作来重建表上所有的辅助索引。

Insert Buffer是一棵B+树,由叶节点与非叶节点组成,非叶节点存放查询的键值,其结构如下图。

 

其中space表示待插入记录所在表的表空间id,占4字节;marker占1字节,用于兼容旧版本的Insert Buffer;offset表示页所在的偏移量,占4字节。当一个辅助索引要插入到页(space, offset)时,若该页不在缓冲池中,则InnoDB存储引擎首先根据上述规则构造一个search key,接下来查询Insert Buffer这颗B+树,再将这条记录插入到树的叶节点。

叶节点需按照如下结构。

 

插入的具体内容从第五列开始。为保证将Insert Buffer中的辅助索引成功合并到磁盘上的辅助索引页,需要用一个特殊的页来标记每个辅助索引页的可用空间,这种页称为Insert Buffer Bitmap。

每个Insert Buffer Bitmap页用来标记$2^{15}$个辅助索引页,每个Insert Buffer Bitmap页都是这$2^{15}$个页的第二个页;每个辅助索引页在Insert Buffer Bitmap页中占用4位,存储的信息如下表。

 

合并插入缓冲

合并插入缓冲操作发生在以下情形。

  • 辅助索引页被读取到缓冲池;
  • Insert Buffer Bitmap页注意到该辅助索引页已无可用空间时:若辅助索引页可用空间少于1/32页,则InnoDB存储引擎会强制进行一个合并操作;
  • Master线程:根据srv_innodb_io_capactiy的百分比来决定需要合并的辅助索引页数,再随机选择Insert Buffer B+树的一个页,读取该页中space,读取space所指定表空间的页,页数为之前确定的页数;

若进行合并操作时,要合并的表已经被删除,则直接将对应的辅助索引丢弃即可!