1. 变更缓冲区Change Buffer
从官方给出的架构图中可以看出,变更缓冲区占用buffer pool的一部分空间。
1.1 变更缓冲区的作用
变更缓冲区用来缓存对二级索引数据的修改,是一个特殊的数据结构,当使用INSERT、UPDATE 或 DELETE 语句修改二级索引对应的数据时,如果对应的数据页在缓冲池中则直接更新,如果不在缓冲池中,那么就把修改操作缓存到变更缓冲区,这样就不用立即从磁盘读取对应的数据页了,当之后的读操作将对应的数据页从磁盘加载到缓冲池中时,变更缓冲区中缓存的修改操作再批量合并到缓冲池,从而达到减少磁盘I/O的目的。执行流程如图所示:
为什么是针对二级索引的修改暂时缓存到change buffer:
- 由于聚集索引具有唯一性,我们分析一下聚集索引为什么不能被放入变更缓存,假设表中有一个主键(ID),现在有两条 INSER 语句,都在插入数据时ID的值相同(id=1),那么在变更缓冲区中就存在两个修改操作,如果以后要合并到缓冲池中,这时就会出现重复的主键值,所以聚集索引的修改不能被加入到变更缓冲区;
- 与聚集索引不同,二级索引通常是不唯一的,并且向二级索引中插入数据时由于数据列不同,所以位置相对随机,同样对于删除和更新操作可能会影响不相邻的二级索引页,如果每次都从磁盘读取数据就会发生大量的随机I/O,以变更缓冲区的方式先将修改缓存起来,当真正的读取数据时再把修改合并到缓冲池中可以提升效率。
1.2 变更缓冲区的修改Merge到Buffer Pool的触发时机
- 读取对应的数据页时;
- 当系统空闲或者 Slow Shutdown 时,主线程发起 merge;
- Change buffer 的内存空间即将耗尽时,
- Redo Log 写满时。
2. 自适应哈希索引
2.1 自适应哈希索引的作用
自适应哈希索引可以使InnoDB存储引擎在不牺牲事务特性和可靠性以及缓冲池空间足够的前提下提升效率,使用起来更像是一个内存数据库,哈希索引根据经常访问的索引页自动构建;根据InnoDB内部的监控机制,如果监控到某些查询通过建立哈希索引可以提高性能,则自动对这个页创建哈希索引,这个过程称为自适应,所以叫自适应哈希索引;
哈希索引可以跳过B+树的层级查找,直接定位数据,减少了树的遍历次数和磁盘I/O操作,提升查询效率。
2.2 为什么要创建自适应哈希索引
- InnoDB存储引擎的数据存储于B+树中,B+树通常只有3到5层,但从根节点到叶节点的寻路涉及到多层页面内记录的比较,即使所有路径上的页面都在内存中,也非常消耗CPU的资源
- InnoDB对寻路的开销进行了优化,比如寻路结束后将cursor缓存起来方便下次查询复用;尽可能的避免单词寻路开销,Adaptive hash index(AHI)便是为此而设计,可以理解为B+树的索引
- 本质上是通过缩短寻路路径(Search Path)从而提升MySQL查询性能的一种方式
2.3 自适应哈希索引保存在哪里
自适应哈希索引会占用缓冲池一部分内存区域,在缓冲池初始化后被初始化,为了避免AHI的锁竞争压力,AHI支持分区,可以使用 innodb_adaptive_hash_index_parts 参数配置分区个数,默认为 8。
注意:⾃适应哈希索引是InnoDB内部的优化⽅式,外部不能⼲预
3. 日志缓冲区
3.1 日志缓冲区的作用
日志缓冲区是服务器启动时向操作系统申请的一片连续的内存区域,存储即将要写入磁盘日志文件的数据。在对数据库进行DML操作时,InnoDB会记录对应操作的日志,比如为保证数据完整性实现数据库崩溃恢复的Redo Log,这些日志会首先写入Log Buffer中,从而解决同步写磁盘导致的性能问题然后根据不同落盘策略最终写入磁盘
3.2 为什么设置日志缓冲区
如果日志不通过Log Buffer直接写入磁盘,那么每次进行DML操作都会进行一次磁盘I/O,这样会严重影响效率,所以把日志统一写入内存中的Log Buffer,根据刷盘策略统一进行落盘操作,可以实现一次磁盘I/O写入多条日志,从而提升效率