mysql 特性之 change buffer

目录

前言

Change Buffer 

用途

合并(merge )

持久化


前言

InnoDB 的索引数据结构使用的是 B+ 树,根据 B+ 树叶子节点存放的不同内容,InnoDB 索引分为 主键索引(聚集索引)和  非主键索引(二级索引)。

一般建表都会建议采用自增主键,保证主键是按顺序插入的,这样插入过程就不会发生磁盘的随机读取。但是因不同业务需求建立的二级索引,一般是很难保证他们都是按序插入的,这时就需要对磁盘进行随机读取,影响插入性能。因此,针对二级索引,InnoDB 设计了 Change  Buffer 来提升插入/变更性能。

Change Buffer 

Change Buffer 只是一个统称,实际上它包含三个类型: Insert Buffer、Delete Buffer 和 Purge Buffer,分别对应 INSERT、DELETE 和 UPDATE 三种 DML 操作。

Change Buffer 和数据页一样,也是物理页的一个组成部分,即它也会被写到磁盘;并且它的数据结构也是 B+ 树,存放在共享表空间中(ibdata1)。

此外,Change Buffer 使用的是 buffer pool 里的内存,因此不能无限增大。从 InnoDB 1.2.X 开始,可以通过参数 innodb_change_buffer_max_size 来设置 Change Buffer 最大的使用内存(数值表示占用百分比)。

用途

我们知道,Innodb 是基于磁盘存储,同时按  的方式来管理记录,为了提升数据库性能,引入了 内存缓存。有了内存缓存,在对数据进行查询时,先查缓存,如果数据存在直接返回,如果不存在则去磁盘读取并将读取到的页放到缓存池中,然后再返回数据;对数据的修改则是先判断数据页是否在缓存中,如果在,则直接修改缓存池的页;如果不在,需要先从磁盘读取该数据页放到缓存中,然后再修改缓存,最终都会异步同步到磁盘。

那有了 Change Buffer,在修改时会有一点变化,以一个插入操作为例:

对于二级索引的插入操作,如果数据页在内存中,则直接插入;如果不在,则 先缓存到 Insert Buffer 中,这样就不用去磁盘读取数据页了,减少了从磁盘读取数据页到内存的过程。

我们这里强调的是二级索引的插入,因为 Insert Buffer 并不适用于唯一索引。原因是对于唯一索引的插入,需要判断插入值是否违背了唯一性,这就必须先将数据页读到内存中,从而导致 Insert Buffer 失去了意义(Change Buffer 设计的目的就是为了避免从磁盘读取数据页到内存中来)。

从这一点来看,在索引的选择上,对于需要保证唯一性的需求,如果业务已经保证了字段的唯一性,我们应该尽量选择普通索引而非唯一索引。普通索引和 change buffer 的配合使用,对于数据量大的表的更新优化还是很明显的。

合并(merge )

缓存在 Change Buffer 中的数据什么时候合并到真正的数据页去呢?

1、查询数据时,会将数据页读到内存,此时必须对 Change Buffer 中关于该数据页的改动做合并操作,保证查询数据的准确性;

2、数据页空间不够用时,强制合并,避免以后合并失败;

3、后台的主线程每秒以及每10秒的任务中会进行一次合并操作(根据 srv_innodb_io_capactiy 的百分比来决定要合并多少个页);

4、数据库正常关闭时,也会执行合并。

根据合并时机的第一点,我们应该注意到 Change Buffer 并不适用于所有场景:

对于数据查询很频繁的场景,Change Buffer 其实反而变得多余。因为每次查询数据时,都要先将数据页读到内存中,然后与 Change Buffer 做合并才能返回数据。这样既没有减少与磁盘的交互,反而多出一次合并过程。因此,如果所有的更新后面,都马上伴随着对这个记录的查询,此时我们应该关闭 change buffer。

而对于写多读少的场景就很适合了,因为每次写不用和磁盘交互,等到真正做数据页合并的时候,Change Buffer 可能已经记录了多个变更操作了,相当于本来应该和数据页发生 N 次交互的操作这里一次合并就可以完成了。

持久化

在二级索引使用了 Change Buffer 的情况下,对于二级索引的插入/更新都是只写入到了 Change Buffer 中,思考一个问题,如果在合并之前,数据库发生了宕机,那这些变更会不会全部丢失呢?

答案是不会丢失。因为在事务提交的时候,会把 Change Buffer 的操作也记录到 redo log,所以在重启恢复的时候,Change Buffer 和其他数据页的变更一样,都能从 redo log 中恢复回来。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值