InnoDB涉及的几个关键特性有:

  • Insert buffer
  • double write
  • adaptive hash index
  • async IO
  • flush neighbor Page

插入缓冲 insert buffer

InnoDB中主键是唯一标识符,通常行记录的插入顺序是按主键递增顺序插入的(一般以NULL的auto increment),内存中的存储也按续存储。
并不是所有主键插入都是顺序的,如果主键类是UUID这样的类,插入和辅助索引一样时随机的。即使主键是自增类型,插入的是指定值而不是NULL值,同样可能导致插入并非连续的情况。

对于非聚集索引的插入或者更新操作,不是每一次直接插入到索引页,是先判断插入的非聚集索引页是否在缓冲池中,是就直接插入,否则先放到一个Insert Buffer对象中,再以一定的频率进行Insert Buffer和索引页的merge操作(和TCP/IP的Nagle算法有点类似)。
使用Insert Buffer需要满足一下两个条件:

  • 索引是辅助索引
  • 索引不是唯一的

Insert Buffer可以通过SHOW ENGINE INNODB STATUS来查看插入缓冲的信息。

Insert Buffer有个问题,就是在写密集的情况下插入缓冲会占用过多的缓冲池内存,默认情况是最多可占用1/2的内存。可以通过参数IBUF_POOL_SIZE_PER_MAX_SIZE来控制,比如设置成3,则上限是1/3

change buffer

1.0.x版本引入的,可看做insert buffer的升级版,可以同时对INSERT,DELETE,UPDATE操作进行缓冲,搞了3个buffer:Insert Buffer,Delete Buffer,Purge Buffer.

##Insert Buffer内部实现

是B+树,全局只有一个B+树,负责多所有表的辅助索引进行Insert Buffer。非叶节点存放的是查询的search key(键值)

innodb_buffer_pool_instances 设什么 innodb insert buffer_辅助索引

search key 9字节:

  • space:表示待插入记录所在表的表空间ID,占用4字节
  • marker:兼容老版本的insert buffer,1字节
  • offset:页所在的偏移量,4字节

当一个辅助索引要插入到页时,如果页不再缓冲池,需要先插入到insert buffer,InnoDB首先会构造一个对应的search key,再把这个记录插入到insert buffer B+树的叶子节点中。

插入到叶子节点中的数据结构如图:

innodb_buffer_pool_instances 设什么 innodb insert buffer_辅助索引_02


新增的metadata,4字节:

innodb_buffer_pool_instances 设什么 innodb insert buffer_主键_03

Merge Insert Buffer

关于缓冲池中insert buffer的数据何时合并到磁盘的辅助索引页。一下几种场景会进行合并操作:

  • 辅助索引页被读取到缓冲池
  • Insert Buffer bitmap页追踪到该辅助索引页已经没有可用空间时
  • Master Thread