一文带你了解MySQL之Change Buffer

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 上一篇文章一文带你了解MySQL数据库InnoDB_Buffer_Pool(点击跳转)我们学习了InnoDB Buffer Pool的工作原理,其作用是减少MySQL读取数据时直接与磁盘打交道的次数。那么写入数据时MySQL是否做了减少IO的优化呢?答案是肯定的,就要我们深入的学习Change Buffer。

前言


上一篇文章一文带你了解MySQL数据库InnoDB_Buffer_Pool(点击跳转)我们学习了InnoDB Buffer Pool的工作原理,其作用是减少MySQL读取数据时直接与磁盘打交道的次数。那么写入数据时MySQL是否做了减少IO的优化呢?答案是肯定的,就要我们深入的学习Change Buffer。先放一张官档中Change Buffer的架构图:

微信图片_20230525230613.png

官档地址:https://dev.mysql.com/doc/refman/8.0/en/innodb-change-buffer.html

点击此处跳转


官档中对Change Buffer的概念是:更改缓冲区是一种特殊的数据结构,当二级索引页不在缓冲池中时,它将更改缓存到二级索引页。缓冲的更改可能来自INSERT、UPDATE或DELETE操作(DML),稍后当其他读操作将页面加载到缓冲池中时,这些更改将被合并。


一、如何减少因数据写入导致的IO?

对于读请求,缓冲池能够减少与磁盘打交道的次数,提升性能。但是,如果写数据请求也能减少和磁盘打交道的次数,那样性能不是更好吗?


这时也分为两种情况:


情况一:


假如要修改的页4正好在缓冲池内

微信图片_20230525230639.png


处理过程为图中1、2:


直接修改缓冲池中的页,一次内存操作;

写入redo log,一次磁盘顺序写操作;

这样的效率是最高的(像写日志这种顺序写,每秒几万次没问题)


是否会出现一致性问题呢?


并不会。

1、读取,会命中缓冲池的页;

2、缓冲池LRU数据淘汰,会将“脏页”刷回磁盘;

3、数据库异常奔溃,能够从redo log中恢复数据;


什么时候缓冲池中的页,会刷到磁盘上呢?


定期刷磁盘,而不是每次刷磁盘,能够降低磁盘IO,提升MySQL的性能。


情况二:


假如要修改的这个页40正好不在缓冲池内。

微信图片_20230525230655.png


此时麻烦一点,处理过程为1、2、3:


先把需要为40的索引页,从磁盘加载到缓冲池,一次磁盘随机读操作;

修改缓冲池中的页,一次内存操作;

写入redo log,一次磁盘顺序写操作;

没有命中缓冲池的时候,至少产生一次磁盘IO,对于写多读少的业务场景,是否还有优化的空间呢?


这即是InnoDB考虑的问题,写缓冲(change buffer)应用而生(从名字容易看出,写缓冲是降低磁盘IO,提升数据库写性能的一种机制)。


二、Change Buffer工作原理

2.1 Change Buffer概念

在MySQL5.5之前,叫插入缓冲(Insert Buffer),只针对INSERT做了优化;现在对DELETE和UPDATE也有效,叫做写缓冲(Change Buffer)。


它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中,对页进行了写操作,并不会立刻将磁盘页加载到缓冲池,而仅仅记录缓冲变更(Buffer Changes),等未来数据被读取时,再将数据合并(Merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。


为什么写缓冲优化,仅适用于非唯一普通索引页呢?

InnoDB里,聚集索引(Clustered Index))和普通索引(Secondary Index)存在异同。如果索引设置了唯一(Unique)属性,在进行修改操作时,InnoDB必须进行唯一性检查。也就是说,索引页即使不在缓冲池,磁盘上的页读取无法避免(否则怎么校验是否唯一),此时就应该直接把相应的页放入缓冲池再进行修改


2.2 Change Buffer工作原理

假如要修改页号为40的索引页,而这个页正好不在缓冲池内

微信图片_20230525230721.png


加入写缓冲优化后,流程优化为:


在写缓冲中记录这个操作,一次内存操作;

写入redo log,一次磁盘顺序写操作;

其性能与这个索引页在缓冲池中,相近(可以看到,40这一页,并没有加载到缓冲池中)。


是否会出现一致性问题呢?


也不会。

数据库异常奔溃,能够从redo log中恢复数据

写缓冲不只是一个内存结构,它也会被定期刷盘到写缓冲系统表空间;

数据读取时,有另外的流程,将数据合并到缓冲池;


稍后的一个时间,有请求查询索引页40的数据

微信图片_20230525230808.png


此时的流程如序号1-3:


载入索引页,缓冲池未命中,这次磁盘IO不可避免;

从写缓冲读取相关信息;

恢复索引页,放到缓冲池LRU里;(可以看到,40这一页,在真正被读取时,才会被加载到缓冲池中)


三、Change Buffer触发时机

除了数据页被访问,还有这么几种情况,会刷写缓冲中的数据:


有一个后台线程,会认为数据库空闲时;

数据库缓冲池不够用时; 数据库正常关闭时;

redo log写满时;(几乎不会出现redo log写满,此时整个数据库处于无法写入的不可用状态)


四、Change Buffer适用场景

4.1 适合开启InnoDB的写缓冲机制

数据库大部分是非唯一索引;

业务是写多读少,或者不是写后立刻读取;

可以使用写缓冲,将原本每次写入都需要进行磁盘IO的SQL,优化定期批量写磁盘。例如,账单流水业务


4.2 不适合开启InnoDB的写缓冲机制

数据库都是唯一索引;

或者,写入一个数据后,会立刻读取它;

这两类场景,在写操作进行时(进行后),本来就要进行进行页读取,本来相应页面就要入缓冲池,此时写缓存反倒成了负担,增加了复杂度。


五、Change Buffer的重要的参数

mysql> show variables like '%innodb_change_buffer%';

+-------------------------------+-------+

| Variable_name                 | Value |

+-------------------------------+-------+

| innodb_change_buffer_max_size | 25    |

| innodb_change_buffering       | all   |

+-------------------------------+-------+

2 rows in set (0.01 sec)

5.1 innodb_change_buffer_max_size

配置写缓冲的大小,占整个缓冲池的比例,默认25表示change buffer最大可以占用innodb buffer的25%,最大可设置的值为50%


set persist innodb_change_buffer_max_size = 20


5.2 innodb_change_buffering

默认all表示所有的非唯一普通索引页写入都使用change buffer


all:所有的非唯一普通索引页写入

none:关闭change buffer

inserts:缓冲插入操作

deletes:缓冲删除操作

changes:缓冲插入和删除操作

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

set persist innodb_change_buffering=all;


六、Change Buffer相关监控信息

使用show engine innodb status \G命令查询


mysql> show engine innodb status \G;

**省略部分信息**

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 1, free list len 0, seg size 2, 0 merges

解读:

size 1:正在使用page

free list len:空闲的page

seg size:当前change buffer大小2*16K

merges:插入的条目


merged operations:

insert 0, delete mark 0, delete 0

解读:

insert:通过change buffer插入的数目

delete mark:通过change buffer删除的数目

delete:通过change buffer purge的数目


discarded operations:

insert 0, delete mark 0, delete 0

**省略部分信息**


change buffer的效果=merges/(insert+delete mark+delete)结果越小说明change buffer对性能提升越有利,也可以使用以下 select NAME,COUNT,MAX_COUNT,MIN_COUNT,AVG_COUNT,COMMENT from information_schema.innodb_metrics where name like '%ibuf%'语句进行监控


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
关系型数据库 MySQL 数据库
MySQL 的 change buffer 是什么?
MySQL 的 change buffer 是什么?
|
5月前
|
存储 关系型数据库 MySQL
MySQL Change Buffer 深入解析:概念、原理及使用
MySQL Change Buffer 深入解析:概念、原理及使用
MySQL Change Buffer 深入解析:概念、原理及使用
|
5月前
|
缓存 关系型数据库 MySQL
MySQL Buffer Pool 解析:原理、组成及作用
MySQL Buffer Pool 解析:原理、组成及作用
|
5月前
|
缓存 关系型数据库 MySQL
MySQL数据库——InnoDB引擎-架构-内存结构(Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer)
MySQL数据库——InnoDB引擎-架构-内存结构(Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer)
98 3
|
5月前
|
存储 关系型数据库 MySQL
MySQL Doublewrite Buffer(双写缓冲区)深入解析:原理及作用
MySQL Doublewrite Buffer(双写缓冲区)深入解析:原理及作用
|
6月前
|
关系型数据库 MySQL 数据库
MySQL 的 change buffer 是什么?
MySQL 的 change buffer 是什么?
|
6月前
|
SQL 缓存 关系型数据库
MySQL(三)SQL优化、Buffer pool、Change buffer
MySQL(三)SQL优化、Buffer pool、Change buffer
97 0
|
6月前
|
存储 算法 关系型数据库
MySQL之深入InnoDB存储引擎——Buffer Pool
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。在数据库系统中,由于CPU速度与磁盘速度之间的鸿沟,基于磁盘的数据库系统通常使用缓冲池技术来提高数据库的整体性能。在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中,在下一次读取相同的页时,首先判断该页是否存在缓冲池中,如果存在则被命中,直接读取,否则读取磁盘上的页。
|
11天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
26 1
|
13天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
29 4
下一篇
无影云桌面