继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

MySQL 数据库的提速器-写缓存(Change Buffer)

平头哥的技术博文
关注TA
已关注
手记 61
粉丝 3663
获赞 834

写缓存(Change Buffer) 是一种特殊的数据结构,用于在对数据变更时,如果数据所在的数据页没有在 buffer pool 中的话,在不影响数据一致性的前提下,InnoDB 引擎会将对数据的操作缓存在 Change Buffer 中,这样就省去了从磁盘中读入这个数据页。

将数据页从磁盘读入内存中涉及随机 IO 访问,这也是数据库里面成本最高的操作之一,而利用写缓存(Change Buffer)可以减少 IO 操作,从而提升数据库性能。

关于 MySQL 写缓存(Change Buffer),我们先来看看 InnoDB 的技术架构图:

InnoDB 架构图

Change Buffer 是 Buffer Pool 中的一部分,虽然 Change Buffer 名字叫 Buffer ,但是它也是可以持久化的,在右边的 System Tablespace 中可以看到持久化 Change Buffer 的空间。触发写缓存(Change Buffer)持久化操作有以下几种情况:

  • 1、数据库空闲时,后台有线程定时持久化
  • 2、数据库缓冲池不够用时
  • 3、数据库正常关闭时
  • 4、redo log 写满时

再单独看看 Change Buffer 的架构图,如下所示:
Change Buffer 的架构图

图中详细的描述了 Change Buffer 的功能,Change Buffer 中的数据最终还是会刷回到数据所在的原始数据页中,Change Buffer 数据应用到原始数据页,得到新的数据页的过程称之为 merge。merge 过程中只会将 Change Buffer 中与原始数据页有关的数据应用到原始数据页,以下三种情况会发生 merge 操作:

  • 1、原始数据页加载到 Buffer Pool 时。
  • 2、系统后台定时触发 merge 操作。
  • 3、MySQL 数据库正常关闭时。

Change Buffer 的相关设置

上面就是写缓存(Change Buffer)的相关知识,写缓存(Change Buffer)我们也是可以使用命令参数来控制,MySQL 数据库提供了两个对写缓存(Change Buffer)的参数。
Change Buffer 参数

1、innodb_change_buffer_max_size

innodb_change_buffer_max_size 表示 Change Buffer 最大大小占 Buffer Pool 的百分比,默认为 25%。最大可以设置为 50%。

2、innodb_change_buffering

innodb_change_buffering 参数用来控制对哪些操作启用 Change Buffer 功能,默认是:all。innodb_change_buffering 参数有以下几种选择:

--all:      默认值。开启buffer inserts、delete-marking operations、purges
--none: 不开启change buffer
--inserts:  只是开启buffer insert操作
--deletes:  只是开delete-marking操作
--changes:  开启buffer insert操作和delete-marking操作
--purges:   对只是在后台执行的物理删除操作开启buffer功能

对上面写缓存(Change Buffer)如果你还是云里雾里的话,那么我们就用一个案例来说明一下 Change Buffer ,首先我们向数据库中插入两条数据:

mysql> insert into t(id,k) values(id1,k1),(id2,k2);

结合下面这张图来分析这两条插入语句。

图片来源极客时间

假设当前是 K索引树的状态,K1 所在的数据页 page1 在 Buffer Pool 中,k2 所在的数据页不在 Buffer Pool 中,来看看这两条语句的执行流程:

1、对于 k1 这条数据,Page 1 在内存中,所以直接更新内存,不会使用到 Change Buffer;

2、k2 对应的数据页 Page 2 没有在内存中,就在内存的 change buffer 区域,记录下“我要往 Page 2 插入一行”这个信息,这个地方及其关键,并没有从磁盘中将 page2 加载到内存。

3、将上述两个动作记入 redo log 中(图中 3 和 4)。

4、后台线程会定时将 page1 和 Change Buffer 中的数据持久化

主要地方在于步骤二,这就是写缓存(Change Buffer)提高性能的地方,虽然 page2 并没有在内存中,但是并没有妨碍我们往数据库 page2 中插入数据,这就是写缓存(Change Buffer)的巧妙之处,也是写缓存(Change Buffer)提高 MySQL
的地方。

Change Buffer 适用场景

Change Buffer 并不是适用于所有场景,以下两种情况不适合开启 Change Buffer :

  • 1、数据库都是唯一索引

如果数据库都是唯一索引,那么在每次操作的时候都需要判断索引是否有冲突,势必要将数据加载到缓存中对比,因此也用不到 Change Buffer。

  • 2、写入一个数据后,会立刻读取它

写入一个数据后,会立刻读取它,那么即使满足了条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价。所以,对于这种业务模式来说,change buffer 反而起到了副作用。

以下几种情况开启 Change Buffer,会使得 MySQL 数据库明显提升

  • 1、数据库大部分是非唯一索引
  • 2、业务是写多读少
  • 3、写入数据之后并不会立即读取它

总体来说 InnoDB 的写缓存(Change Buffer)应用得当,会极大提高 MySQL 数据库的性能,使用不恰当的话,可能会适得其反。

以上就是今天分享的内容,希望对您的学习或者工作有所帮助,如果您觉得文章不错,欢迎点个赞和转发,谢谢。

最后

目前互联网上很多大佬都有 MySQL数据库相关文章,如有雷同,请多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有所错误之处,还望提出,谢谢。

互联网平头哥(id:pingtouge_java)
作者:平头哥

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP