一文带你搞懂MySQL的Change Buffer

一 认识

Change Buffer 是 InnoDB 的一个特殊区域, 是 InnoDB 存储引擎为了优化对非唯一二级索引页的修改操作而设计的一个机制。 它的核心目标是:延迟并合并对非唯一二级索引页的磁盘写入,以减少磁盘 I/O,提高性能。

二 为什么需要 Change Buffer?

在数据库中,当我们执行 `INSERT、UPDATE、DELETE`操作时,除了更新主键(聚簇索引)对应的行数据外,**还必须更新所有相关的二级索引**(普通索引)

但二级索引页可能不在内存中(Buffer Pool) :

  • 如果每次都把对应页从磁盘加载到内存,再进行修改,这样的随机磁盘I/O非常消耗性能

所以,InnoDB的设计思路是:

  • 如果是 非唯一二级索引,我们可以先不加载对应的索引页到内存,而是把这次修改先记录在Change Buffer中等未来合适的时候再一次性应用 (merge) 到磁盘上

三 工作原理详解

1 满足条件:修改的是非唯一索引

2 如果要修改的索引页 当前不在Buffer Pool(内存页)中:

  • InnoDB 不会立刻从磁盘加载该页
  • 而是将这次变更记录到Change Buffer(内部存储结构)中

3 Change Buffer 会在合适的时机应用到真实的索引页中,这个过程成为merge,时机包括:

  • 索引页被访问
    • 用户发起查询,访问某个二级索引页
    • 该页被加载到 Buffer Pool
    • 如果这页有对应的 Change Buffer 修改,则立刻执行合并
  • 后台线程定期合并
    • InnoDB 会在数据库空闲时,通过后台线程将 Change Buffer 中的变更批量应用到索引页
    • 减少主线程负担,提高整体吞吐率
  • 数据库关闭前或缓冲页刷写时
    • 所有未合并的Change Buffer 都必须应用,以确保数据完整性
    • 写前日志(redo log)也记录这些操作,确保崩溃恢复安全
  • Buffer Pool 空间紧张,页被驱逐前
    • 某个页即将被淘汰时,如果其有对应的Change Buffer修改,会在刷盘前执行合并

4 合并过程(Merge Mechanics)

合并过程大致如下:

  1. 判断页是否在 Buffer Pool 中;
  2. 如果不在,从磁盘加载目标索引页;
  3. 读取对应 Change Buffer 的修改记录;
  4. 依次应用:
    • 执行插入、删除或更新操作;
  5. 更新页的状态(dirty),并标记该页为需刷新;
  6. 清除已合并的 Change Buffer 项。

合并后,原 Change Buffer 中对应的记录会被清理。

5 Change Buffer 与事务一致性

即便使用 Change Buffer,InnoDB 仍然保证事务的 ACID 特性

  • 所有 Change Buffer 修改都被写入 redo log;
  • 崩溃恢复时,未 merge 的记录仍然可以被重新加载、合并;
  • 和数据页一样,这些修改受事务隔离级别控制;
  • 多个事务并发操作相同索引时,仍然会通过锁机制(如记录锁、间隙锁)维持一致性。

四 Change Buffer 的底层存储结构

1. Change Buffer 存储在哪?

Change Buffer 不是驻留在内存中的结构,而是:
  • 存储在 InnoDB 系统表空间(system tablespace,**ibdata1**)中的一个特殊结构
  • 这使得即使数据库崩溃或重启,Change Buffer 中的修改记录依然保留
  • 数据恢复阶段会处理这些未合并的变更记录,确保数据一致性

2. Change Buffer 的数据结构类型

在底层实现上,**Change Buffer 是一个 B+ 树结构**,它存储的不是完整的数据页,而是**修改操作的元数据**,包括:
字段含义
page_id被修改的目标索引页
record_id被修改的具体索引项
操作类型INSERT / DELETE / UPDATE
操作数据要插入/删除/更新的内容
时间戳/顺序号合并顺序控制

它有点类似 “补丁列表”,在目标索引页不在内存时,把“要改哪里”和“改什么”记下来,等以后再应用。

五 相关参数(MySQL 8+)

参数含义
innodb_change_buffering控制是否启用 Change Buffer(可选值:none、inserts、deletes、changes、all)
innodb_change_buffer_max_sizeChange Buffer 占用 Buffer Pool 最大比例(默认 25)
innodb_adaptive_hash_index和 Change Buffer 无直接关系,但都是优化访问路径的手段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值