MySQL 数据库的提速器-写缓存(Change Buffer)
写缓存(Change Buffer) 是一种特殊的数据结构,用于在对数据变更时,如果数据所在的数据页没有在 buffer pool 中的话,在不影响数据一致性的前提下,InnoDB 引擎会将对数据的操作缓存在 Change Buffer 中,这样就省去了从磁盘中读入这个数据页。
将数据页从磁盘读入内存中涉及随机 IO 访问,这也是数据库里面成本最高的操作之一,而利用写缓存(Change Buffer)可以减少 IO 操作,从而提升数据库性能。
关于 MySQL 写缓存(Change Buffer),我们先来看看 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 数据应用到原始数据页,得到新的数据页的过程称之为 merge。merge 过程中只会将 Change Buffer 中与原始数据页有关的数据应用到原始数据页,以下三种情况会发生 merge 操作:
- 1、原始数据页加载到 Buffer Pool 时。
 - 2、系统后台定时触发 merge 操作。
 - 3、MySQL 数据库正常关闭时。
 
Change Buffer 的相关设置
上面就是写缓存(Change Buffer)的相关知识,写缓存(Change Buffer)我们也是可以使用命令参数来控制,MySQL 数据库提供了两个对写缓存(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 相关文章,如有雷同,请多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有所错误之处,还望提出,谢谢。
欢迎扫码关注微信公众号:「互联网平头哥」,和平头哥一起学习,一起进步。
MySQL 数据库的提速器-写缓存(Change Buffer)的更多相关文章
- MySql 缓冲池(buffer pool) 和 写缓存(change buffer)  转
		
应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. M ...
 - MySQL 数据库性能优化之缓存参数优化
		
在平时被问及最多的问题就是关于 MySQL 数据库性能优化方面的问题,所以最近打算写一个MySQL数据库性能优化方面的系列文章,希望对初中级 MySQL DBA 以及其他对 MySQL 性能优化感兴趣 ...
 - Canal 实战 | 第一篇:SpringBoot 整合 Canal + RabbitMQ 实现监听 MySQL 数据库同步更新 Redis 缓存
		
一. Canal 简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同 ...
 - 全网最清楚的:MySQL的insert buffer和change buffer 串讲
		
目录 一.前言 二.问题引入 2.1.聚簇索引 2.2.普通索引 三.change buffer存在的意义 四.再看change buffer 五.change buffer 的限制 六.change ...
 - mysql数据库性能优化(包括SQL,表结构,索引,缓存)
		
优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...
 - MySQL -- Innodb中的change buffer
		
change buffer是一种特殊的数据结构,当要修改的辅助索引页不在buffer pool中时,用来cache对辅助索引页的修改.对辅助索引页的操作可能是insert.update和delete操 ...
 - 【MySQL 5.7 Reference Manual】15.4.2 Change Buffer(变更缓冲)
		
15.4.2 Change Buffer(变更缓冲) The change buffer is a special data structure that caches changes to se ...
 - MySQL 5.7 Reference Manual】15.4.2 Change Buffer(变更缓冲)
		
15.4.2 Change Buffer(变更缓冲) The change buffer is a special data structure that caches changes to se ...
 - 浅谈MySQL 数据库性能优化
		
MySQL数据库是 IO 密集型的程序,和其他数据库一样,主要功能就是数据的持久化以及数据的管理工作.本文侧重通过优化MySQL 数据库缓存参数如查询缓存,表缓存,日志缓存,索引缓存,innodb缓存 ...
 
随机推荐
- [bzoj4011] [洛谷P3244] [HNOI2015] 落忆枫音
			
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂--我们也 ...
 - 玩转Django2.0---Django笔记建站基础六(模型与数据库)
			
第六章 模型与数据库 Django对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite和Oracle,而且为这些数据库提供了统一的调用API,这些API统称为ORM框架. ...
 - svn subvesion Branch Merge
 - Collections.synchronizedList 、CopyOnWriteArrayList、Vector介绍、源码浅析与性能对比
			
## ArrayList线程安全问题 众所周知,`ArrayList`不是线程安全的,在并发场景使用`ArrayList`可能会导致add内容为null,迭代时并发修改list内容抛`Concurre ...
 - zerotier 远程办公方案
			
武汉新肺炎疫情下,搞得人心惶惶.很多公司都要求前期远程办公 我厂日常有在家远程应急支持的情况,所以公司很早就有VPN服务.只需要申请VPN服务,开通之后就可以连上公司各种公共资源. 然而对于一些非公共 ...
 - 痞子衡嵌入式:知名半导体MCU大厂软件开发C代码规范
			
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是飞思卡尔软件开发C语言编码规范. 2020鼠年春节是个漫长的假期,痞子衡在家百无聊赖,翻出了2016年10月1日(这个时间是痞子衡正式开始 ...
 - 尼姆博弈+SG函数
			
博弈这个东西真的很费脑诶.. 尼姆博奕(Nim Game):游戏者轮流从一堆棋子(或者任何道具)中取走一个或者多个,最后不能再取的就是输家.当指定相应数量时,一堆这样的棋子称作一个尼姆堆 当n堆棋子的 ...
 - 如何更改cmd 编码为UTF-8
			
如何将cmd编码改为UTF—8 如图输入chcp 65001即可更改 改完之后是这样的 更改回GBK 输入 CHCP 936即可
 - Prometheus学习笔记之教程推荐
			
最近学习K8S和基于容器的监控,发现了如下的教程质量不错,记录下来以备参考 K8S最佳实战(包括了K8S的Prometheus监控和EFK日志搜集) https://jimmysong.io/kube ...
 - Linux驱动管理
			
一.驱动更新 本示例为更新网卡驱动,把新的驱动文件放到/root/目录下,然后执行下面的命令 备份已有的文件,将新的文件复制的相应位置 mv /lib/modules/`uname -r`/kerne ...