MySQL 之 InnoDB引擎 Change Buffer

Change Buffer

Change Buffer是一种特殊的数据结构,缓存对二级索引页面的更改并且这些页面不在Buffer Pool中。缓存的changes可能由 Insert 、Delete 和 Update的结果导致。稍后在页面被其他读取操作加载到Buffer Pool的时候合并。

Buffer Pool的研究在我的这篇里有:https://blog.csdn.net/qq_36652619/article/details/88953065

简而言之:Change buffer的主要目的是将对二级索引的数据操作缓存下来,以此减少二级索引的随机IO,并达到操作合并的效果。

与聚簇索引(ps:默认是InnoDB里的主键,主键是聚集存储的)不同,二级索引通常不是唯一的,并且插入二级索引的顺序相对随机。删除和更新可能会影响不在索引树中相邻的二级索引页。当受影响的页面被其他操作读入缓冲池时,合并缓存的更改,避免了从磁盘读取二级索引页到缓冲池所需的大量随机访问I / O。

在MySQL5.5之前的版本中,由于只支持缓存insert操作,所以最初叫做insert buffer,只是后来的版本中支持了更多的操作类型缓存,才改叫change buffer,所以本文是基于MySQL5.5之后的版本。

(Secondary Index(二级索引)

  • 也可以称为 非聚集索引

  • 叶子节点存储的是 索引 和 主键 信息

  • 在找到索引后,得到对应的主键,再 回到聚集索引 中找主键对应的记录(row data))

放出二级索引的解释可能还是懵,什么时候算作二级索引,所有主键以外的索引都是二级索引(innodb默认),官方文档说的:

在这里插入图片描述

ps:所以说根据主键访问数据(永远是效果最好的方式),原因看上方括号内二级索引介绍

在这里插入图片描述

为何需要Change Buffer

上面的结构图可能有些迷,看下面的图解:

在这里插入图片描述

表的索引存于该表的ibd文件中,数据也存于此文件。表数据更新的同时也会更新对应的表的索引数据,所以:例如对表进行insert时,很可能会产生大量的物理读(物理读索引数据页),insert一个表,对应的表上面的索引会变动,索引不常使用,产生物理读,索引顺序和表不一致耗时。

(物理读(Physical Reads):从磁盘读取数据块到内存的操作叫物理读,当缓存不存在这些数据块的时候就会产生物理读,物理读过大表现为磁盘 I/O 较高)

所以将对索引的更新记录存入Change Buffer中,而不是直接调入索引页进行更新;选择时机进行merge insert buffer的操作,将insert buffer中的记录合并(merge)到真正的辅助索引中。

在这里插入图片描述

系统大部分空闲时或在慢速关闭期间运行的清除(purge)操作会定期将更新的索引页写入磁盘。与每个值立即写入磁盘相比,purge操作可以更有效地为一系列索引值写入磁盘块。

当有许多受影响的行和许多要更新的二级索引时,Change Buffer合并可能需要几个小时。在此期间,磁盘I / O会增加,这会导致磁盘绑定查询显着减慢。在提交事务之后,甚至在服务器关闭并重新启动之后,更改缓冲区合并也可能继续发生

在内存中,Change Buffer占用Buffer Pool的一部分。在磁盘上,Change Buffer是系统表空间的一部分,其中的索引会在关闭数据库服务器时更改。

配置Change Buffer

对表执行 INSERT,UPDATE和 DELETE操作时, 索引列的值(尤其是secondary keys的值)通常按未排序顺序排列,需要大量I / O才能使二级索引更新。Change Buffer会缓存这个更新当相关页面不在Buffer Pool中,从而磁盘上的相关页面不会立即被读避免了昂贵的I / O操作。当页面加载到缓冲池中时,将合并缓冲的更改,稍后将更新的页面刷新到磁盘。该InnoDB主线程在服务器几乎空闲时以及在慢速关闭期间合并缓冲的更改 。

为方便理解:来了一个关于二级索引页面的DML操作,并且这个页面没有在Buffer Pool内,那么把这个操作存入Change Buffer(MySQL5.5之前的版本叫Insert Buffer),ok,那么下一次需要加载这个页面的时候,也就是这个页面有需求的时候,会将Change Buffer内的更改合并到Buffer Pool,随后当服务器在空闲的时候,这个更改会刷到disk(磁盘)上。所以一开始那张很难读的图的流程就清晰了:(黄色箭头这样的走势)

在这里插入图片描述

因为它可以减少磁盘读取和写入,所以更改缓冲区功能对于I / O绑定的工作负载最有价值,例如具有大量DML操作的应用程序(如批量插入)。

但是,Change Buffer占用Buffer Pool的一部分,从而减少了可用于缓存数据页的内存。如果工作集几乎适合Buffer Pool,或者您的表具有相对较少的二级索引,则禁用Change Buffer可能很有用。

毕竟Change Buffer只适用于Buffer Pool外的页面嘛。

可以使用innodb_change_buffering 配置参数

允许的innodb_change_buffering 值包括:

  • all

    默认值:所有操作

  • none

    不要缓冲任何操作。

  • inserts

    缓冲插入操作。

  • deletes

    缓冲区删除标记操作。

  • changes

    缓冲插入和删除标记操作。

  • purges

    缓冲在后台发生的物理删除操作。

Change Pool内部结构

下面是一张来自云栖社区的图:

图中的ibuf代表Insert Buffer,可以直接将其看成Change Buffer,为MySQL 5.5 之前Change Buffer就叫Insert Buffer

在这里插入图片描述

ibuf btree最大默认为buffer pool size的25%,当超过25%时,可能触发用户线程同步缩减ibuf btree。为何要将ibuf btree的大小和buffer pool大小相关联呢 ? 一个比较重要的原因是防止ibuf本身占用过多的buffer pool资源。

配置Change Pool最大大小

该innodb_change_buffer_max_size 变量允许将Change Buffer的最大大小配置为缓冲池总大小的百分比。默认情况下, innodb_change_buffer_max_size设置为25.最大设置为50。

使用测试不同的设置的业务性能以确定最佳配置。该 innodb_change_buffer_max_size 设置是动态的,允许在不重新启动服务器的情况下修改设置。类似innodb_buffer_pool_size也可以在线更改那种。

以上是对InnoDB引擎Change Buffer的一些粗浅认识

原文链接:

https://blog.csdn.net/qq_36652619/article/details/89460786

相关博客

Change Buffer空间换时间 https://www.bilibili.com/read/cv6472709
MySQL · 引擎特性 · Innodb change buffer介绍 http://mysql.taobao.org/monthly/2015/07/01/

MySQL 数据库的提速器-写缓存(Change Buffer) https://segmentfault.com/a/1190000021853169

数据库原理: Change Buffer 是干什么的? https://zhuanlan.zhihu.com/p/158879979

视频资料

https://www.bilibili.com/video/BV1xX4y1V7ug?p=26

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值