「这是我参与 2022 首次更文挑战的第 23 天,活动详情查看:2022 首次更文挑战」
形而上者谓之道;形而下者谓之器。
前言
前文讲述了 mysql 数据库 InnoDB 引擎的关键特性插入缓存的内容,本文继续介绍插入缓存的其它内容,插入缓存中的 change buffer。
插入缓存
change buffer
Change Buffer 可以视为 Insert Buffer 的升级,InnoDB 存储引擎可以对 DML 操作增删改都进行缓冲,其对应关系如下:
insert -> insert buffer
delete -> delete buffer
update -> purge buffer
Change Buffer 的最用对象依然是非唯一的辅助索引,对一条数据进行更新操作分为两个过程:
- 1 将数据记录标记为删除。
- 2 将数据记录真正的删除。
Delete Buffer 对应 update 操作的第一个过程,Purge Buffer 对应的是 update 操作的第二个过程将数据真正的删除。 InnoDB 存储引擎提供了 innodb_change_buffering 来开启各种 buffer 的选项。该参数值得可选范围为:
inserts、deletes、purges、changes、all、none
all 表示启用所有,为默认参数
changes 表示启用 inserts 和 deletes
none 表示不启用任何配置
Change Buffer 的大小可以通过 innodb_change_buffer_max_size 参数来进行控制,默认的大小为 25,表示最多使用 25% 的缓存池空间,该值的最大有效参数为 50%。
在上图中查看引擎状态时有两个展示项
merged operations 和 discarded operations:
merged operations:
insert 431392, delete mark 658890, delete 401253
insert 表示 Insert Buffer 的操作次数
delete mark 表示 Delete Buffer 的操作次数
delete 表示 Purge Buffer 的操作次数
discarded operations:
insert 0, delete mark 0, delete 0
表示当前的 Change Buffer 发生 merge 时,数据已经清除,无需再将记录合并到辅助索引中了。
Insert Buffer 实现原理
Insert Buffer 的使用场景为非唯一辅助索引的插入操作,其内部的数据结构为 B+Tree。InnoDB 引擎维护一个全局的 B+Tree 树,负责对所有的表辅助索引进行插入缓存。该 B+Tree 存放在共享表空间中,也就是默认的 ibdata1 中。因此试图通过独立表空间 ibd 文件恢复表数据时,往往会导致 check table 失败,这是因为表的辅助索引中的数据可能还在 Insert Buffer 中,也就是在表空间中,所以通过 ibd 文件进行恢复后,还需要进行 repair table 操作来重建表上的所有辅助索引。
Insert Buffer 的 B+tree 结构包括叶子结点和非叶子结点,非叶子结点存放的是查询的 search key ,其主要结构如下所示:
# Insert Buffer 非叶子结点中的 search key
space(4个字节) marker(1个字节) offset (4个字节)
# Insert Buffer 叶子结点中结构
space(4个字节) marker(1个字节) offset(4个字节)metadata(4个字节)(second index record)
search key 一共占用 9 个字节,其中 space 表示待插入记录所在的表空间 id,在 InnoDB 存储引擎中,每个表都有一个唯一的 space id , 可以通过 space id 查询得知是哪张数据库表。当一个辅助索引插入到索引页时,如果这个页不在缓冲池中,那么 InnoDB 存储引擎首先创建一个 search key ,接下来查询 Insert Buffer 这个 B+tree ,然后将数据记录插入到叶子结点中。
second index record 内容就是记录实际插入的数据库索引字段了,因此比较原插入记录,Insert Buffer B+ Tree 的叶子节点需要额外的 13 字节的开销。
在启用 insert buffer 后,辅助索引页的记录可能被插入 insert buffer b+ tree 中,为了保证每个 merge 缓存页的成功,还需要一个特殊的页来标记每个索引辅助页的可使用空间,这个页称之为 Insert Buffer Bitmap。
每个 Insert Buffer Bitmap 页用来追踪 16384 个辅助索引页,也就是 256 个区(Extent)。
Merge Insert Buffer
在 Insert Buffer 或者 Merge Buffer 发生合并操作时,可能会出现以下几种情况下:
- 1 辅助索引被读取到缓冲池中。
- 2
Insert Buffer Bitmap页追踪到该辅助索引页已经无可用空间。 - 3
Master Thread开始进行合并操作。
总结
本文介绍了插入缓存的剩余内容,以及 Insert Buffer 的实现原理,在下一节中将介绍 InnoDB 的其它特性-两次写(doublewrite)。