Change Buffer 概念
Change Buffer 是 MySQL InnoDB 存储引擎中的一种优化机制,用于缓存对 非唯一索引的变更操作(插入、更新和删除)。它的主要目的是减少磁盘 IO操作,从而提高数据库的写入性能。
在MySQL5.5 之前叫 Insert Buffer只缓存插入,从MySQL5.5 开始扩展到插入、更新和删除,更名为 Change Buffer。
Change Buffer执行流程

说明:
0、实则Change Buffer 是 Buffer Pool里的一部分,图中分开是为了能清晰描述逻辑。
1、只有修改非唯一索引且要修改的数据页不在BufferPool里时,才使用ChangeBuffer,也就是 分支1 。
2、修改非唯一索引但要修改的数据页在BufferPool里时,直接修改BufferPool的数据页即可。
3、修改唯一索引时,要做唯一性验证必须操作BufferPool的数据页(若BufferPool里没有就去磁盘加载)。
4、Delete操作,并非直接把BufferPool里数据页上的对应数据删掉,而是修改该数据的删除标记然后由后台Purge线程定期清除。
5、所有的修改都是操作BufferPool,然后有FlushThread和CheckPoint定期异步实现落盘。
Change Buffer合并时机
1、访问该Page;有其他线程访问该Page时,Buffer Pool不是最新数据,把Change Buffer里的修改Merge过去使Buffer Pool里数据最新,查询到最新数据。
2、后台线程定期Merge(io_buffer_thread,空闲时处理)。
3、数据库正常关闭;要正常关闭,不能直接 kill -9 {pid}。
Change Buffer怎么提升效能
修改非唯一索引,如果涉及的数据页不在Buffer Pool里,从磁盘里加载到Buffer Pool里然后在Buffer Pool里修改不可以吗?为什么要引入Change Buffer呢?Change Buffer又是怎么提升效能的?
答案:由于非唯一索引对应的数据可能许多,可能涉及到许多数据页,若要扫描磁盘需要做大量的扫描工作,效能极低,Change Buffer就是为了解决这个问题。
关键参数
innodb_change_buffering
可选值:
- all:默认值。缓冲插入、删除标记操作和清除操作。
- none:不缓冲任何操作。
- inserts:只缓冲插入操作。
- deletes:只缓冲删除标记操作。
- changes:缓冲插入和删除标记操作。
- purges:只缓冲在后台发生的物理删除操作。
说明:
1、上面的inserts、deletes等不是指的SQL语句层面的操作,而是指索引层面的操作。
2、执行一条INSERT语句,在索引层面:插入一条数据(inserts);要想完全缓存可以设置为inserts或all。
2、执行一条DELETE语句,在索引层面:先将数据加删除标记(deletes),然后后台定时物理删除(purges);要想完全缓存需设置为 all。
3、执行一条UPDATE语句,在索引层面:先将旧数据加删除标记(deletes),再插入一条新数据(inserts),然后后台定时物理删除(purges);要想完全缓存需设置为 all。
4、提议保持默认值 all。
innodb_change_buffer_max_size:
控制 Change Buffer 占用 Buffer Pool 的最大比例,默认值为 25%,取值范围为 0 到 50。
Buffer Pool里缓存的数据页对于数据库整体性能超级重大,要保证这块尽量大。对于读多写少的场景可以降低此配置; 对于读少写多的场景可以提高此配置(不能超过50%)。
大家好
大家好,我是旭杰,我整理了MySQL的一些知识点(大体目录如下),愿与大家分享:


更多问题欢迎扫码加群交流,愿与大家共同追求卓越。
