文章目录
InnoDB存储引擎特性——插入缓冲
一.Insert Buffer
- 在探讨插入缓冲特性之前,我们必须先弄懂InnoDB聚集索引和非聚集索引的插入过程,因为插入缓冲就是针对于非聚集索引的插入效率而诞生的
- 如果对于 聚集索引和非聚集索引的概念还不是很清楚的朋友可以看看我的这篇博客:
Mysql技术内幕:聚集索引,非聚集索引的底层实现
1.1 聚集索引和非聚集索引的插入
1.1.1聚集索引的插入
- 在InnoDB存储引擎中,主键是行的唯一标识符,通常应用程序中行记录插入的顺序就是按照主键递增的顺序进行插入的
- 聚集索引有这样的特点:行物理地址与主键的逻辑顺序是相同的
- 这就意味着插入聚集索引的时候不需要进行磁盘的随机读取,直接顺序插入即可。
- 由于索引页中的索引也是顺序存放的,所以只要在页中顺序插入,不需要读取其他页
1.1.2 非聚集索引的插入
- 由于非聚集索引树中的叶子节点的插入不再是顺序的,所以每次插入都需要离散的访问非聚集索引页
- 这种随机读取的存在就导致了插入操作的性能下降,这个特性其实是因为B+树的特性决定的
- 但是需要注意的是,在某些特殊情况下辅助索引的插入依然是顺序的,或者说是比较顺序的,比如用户购买表中的时间字段
1.2 Insert Buffer原理概述
- InnoDB存储引擎开创性地设计的Insert Buffer,对于非聚集索引的插入或更新操作,不是每一次直接插入索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若果在则直接插入,如果不在,那就先放到一个Insert Buffer对象中
- 这就好似欺骗,数据库的非聚集索引已经插入到叶子结点中了,但是实际上并没有 ,只是存起来了,然后一一定的频率和情况进行Insert Buffer和辅助索引页的合并操作
- 这时候通常就可以将多个插入合并到一个操作中(因为在一个索引页中),这就大大的提高了对非聚集索引的插入性能
1.3 Insert Buffer使用条件
- 索引是辅助索引
- 索引不是唯一的
索引是辅助索引:Insert Buffer本身就是针对于非聚合索引的插入出现的,所以必须是非聚合索引的插入才可以使用
索引不是唯一的:因为在插入缓冲的时候,数据库并不去查找索引页来判断插入的记录的唯一性,如果去查找肯定会有离散读取的情况发生,这就使其失去了意义。因为判断是否唯一需要扫描索引页,而扫描索引页可能涉及到随机读写磁盘,这里引入插入缓冲,就是为了避免多次随机读写磁盘引入的。
二. Change Buffer
- InnoDB从1.0.x版本开始引入了Change Buffer,可以将其视为Insert Buffer的升级
- 意思就是InnoDB存储引擎可以对DML操作——INSERT,DELETE,UPDATE都进行缓冲
- 分别是:INSERT Buffer,DELETE Buffer,Purge Buffer
2.1 实现过程
- 对一条记录进行UPDATE操作可能分为两个过程
1)将记录标记为已删除
2)真正将记录删除 - 因此Delete Buffer对应第一个过程,就是将记录标记为删除
- Purge Buffer对应第二个过程,将记录真正删除
三. Insert Buffer的内部实现
- 刚刚有提到,Insert Buffer就是为了插入非聚集索引实现的,并且是非唯一的,每次插入辅助索引都是先将其存到Insert Buffer对象中,那么Insert Buffer对象到底是什么呢?
- 在InnoDB内部,Insert Buffe其实就是一棵B+树,在现在的版本中,全局只有一棵Insert Buffe B+树,负责对所有的表的辅助索引插入进行 Insert Buffer
四. 合并插入缓冲
- 我们已经知道Insert Buffer就是一棵B+树,如果要插入的辅助索引页不在缓冲池中,就将其插到这棵树中,那么什么时候将Insert Buffer中的记录合并到真正的辅助索引页中呢?
- 合并插入缓冲的触发有以下三种情况
1)辅助索引页被读取到缓冲池中
2)Insert Buffer Bitmap页追踪到该辅助索引页已无可用空间时
3)Master Thread - 第一种情况:当用户操作需要读取到某个辅助索引页时,InnoDB会将该页从磁盘读取进缓冲池中没如果发现Insert Buffer中有该页需要插入更新的辅助索引,那么就进行合并操作。然后会根据一定的频率和机制刷新回磁盘
- 第二种情况:Insert Buffer Bitmap页用来追踪每个辅助索引页的可用空间,并至少有1/32的空间。若插入辅助索引记录时检测到插入之后可用空间会少于1/32页,则会强制进行一个合并操作,即强制读取辅助索引页,然后进行合并
- 第三种情况:Master Thread是后台的核心线程,有每一秒和每十秒的操作,会有一定的频率进行合并缓冲操作。
五. 总结
- 总的来说插入缓冲就是为了解决非聚集索引插入的性能问题,B+树的结构导致插入非聚集索引需要离散的访问磁盘,所以这种方法可以将多次插入合并成一个操作,提高性能
- 对于InnoDB体系架构,后台线程(Master Thread等),缓冲池等不太懂的朋友可以看我这篇博客:MySQL技术内幕:MySQL—InnoDB存储引擎体系架构
觉得写得不错的朋友可以点个赞 !!! 谢谢!!!