MySQL 的 Change Buffer 是什么?它有什么作用?

MySQL 的 Change Buffer 是什么?它有什么作用?

MySQL 是目前广泛使用的开源数据库管理系统,其中的 InnoDB 存储引擎凭借其高性能、高可靠性以及强大的事务支持,成为了默认的存储引擎。在 InnoDB 的众多优化机制中,Change Buffer 是一个相对较少被关注,但却在提升数据库性能方面发挥着重要作用的功能。


一.什么是 Change Buffer?

Change Buffer 是 MySQL InnoDB 存储引擎中的一个缓存机制,它用于缓存对 非主键索引(Secondary Indexes) 页的更改。这个缓存区的主要目的是延迟对这些索引页的写操作,以减少磁盘 I/O,从而提升数据库的写性能。

img

**简单来说,当我们对数据库中的二级索引执行插入、删除或更新操作时,这些操作并不会立即写入磁盘。**而是将它们先存放在 Change Buffer 中,直到相关的索引数据页被读取时,才会将这些更改刷写到磁盘。

为什么 Change Buffer 只对非唯一普通索引页有效?

Change Buffer 只对非唯一普通索引页有效,原因在于主键索引和唯一索引具有严格的数据一致性和唯一性要求,修改这些索引时通常涉及到数据行的完整更新或物理位置变化,这使得不能通过延迟写入来保证一致性。相反,非唯一普通索引的修改操作相对简单,且不直接影响行数据,因此适合通过 Change Buffer 缓存变更,减少磁盘 I/O 提高性能。主键索引通常更频繁地被查询和更新,直接写入磁盘可以确保数据的最新性,避免延迟写入引发的不一致问题。同时,限制 Change Buffer 仅应用于非唯一索引页,有助于更高效地利用内存资源,减少与主键索引频繁访问的内存竞争。因此,Change Buffer 的设计是基于数据一致性、性能优化和内存管理的综合考虑。

二.Change Buffer 的工作原理

InnoDB 存储引擎中的索引分为主键索引(Primary Index)和二级索引(Secondary Index)。Change Buffer 只作用于 二级索引,并不涉及主键索引。这是因为主键索引是聚簇索引,数据行按照主键排序存储,直接操作数据行,因此不适合使用延迟写入策略。

1. 对二级索引的操作: 更改暂存

在 InnoDB 中,二级索引是指那些非主键字段建立的索引。对于二级索引的 插入、删除和更新操作,InnoDB 会将这些修改记录到 Change Buffer 中,直到这些索引页被访问时,才会将更改刷写到磁盘。只有当磁盘中的二级索引数据页被访问(例如查询操作),或当系统触发数据页刷写操作时,这些更改才会真正写入磁盘。

2. 如何实现延迟写入:合并更改

Change Buffer 工作时的延迟写入机制主要依赖于 脏页(Dirty Pages) 的概念。在内存中,Change Buffer 会维护一份待刷写的脏页列表,这些脏页记录了尚未写入磁盘的索引更改。当某个二级索引页被访问时,InnoDB 会首先检查该页是否有尚未刷写的更改,如果有,就将更改合并到磁盘数据页中。

3. **与 Redo Log 的配合:**刷新到磁盘

Change Buffer 与 InnoDB 的 Redo Log 协同工作。在数据库崩溃恢复时,Redo Log 会确保所有已提交的事务操作能够恢复。对于那些还没有写入磁盘的数据变更,Change Buffer 会通过 Log Buffer 在系统恢复时被重做,以确保数据的一致性。

4.对旧数据的处理:定期清理

随着时间的推移,Change Buffer中的数据可能会老化或不再需要。为了保持Change Buffer的使用效率,InnoDB会定期执行清理过程,移除那些已经过时或不再需要的更改操作信息。

当我们要更新一条普通索引记录的时候:

  1. 如果这条记录在内存中,那么直接更新内存
  2. 如果该记录没有在内存中,那么就需要更新change buffer
  3. 更新完 change buffer 之后,MySQL会在redo log中记录下change buffer 的修改
  4. 事务就算完成了,后续binlog落盘,redo log commit
  5. 当需要读取不在内存中的记录时,会将该数据页从磁盘加载到内存,然后应用change buffer中的修改,也就是merge操作

三.如何触发Change Buffer

Change Buffer的触发时机主要是在非主键索引的更新或删除操作时。当对一个非主键索引的记录进行更改时,这些更改操作首先会被暂存到Change Buffer中。以下是Change Buffer触发的具体时机:

  1. 非主键索引的更新操作: 当一个非主键索引的记录被更新时,Change Buffer会触发并将更改操作暂存到内存中。

  2. 非主键索引的删除操作: 当一个非主键索引的记录被删除时,Change Buffer同样会触发并将该删除操作暂存到内存中。

  3. 数据页读取操作: 当从非主键索引页读取数据时,Change Buffer会检查该页是否在Change Buffer中有相关的更改。如果有,它会将这些更改应用到该页上,确保读取的数据是最新的。

需要注意的是,Change Buffer触发的时机并不是在每次数据更改时都立即触发。而是将这些更改暂存到内存中的Change Buffer区域,并在合适的时机(如数据页读取操作时)再将这些更改应用到相应的数据页上。这样可以减少频繁的磁盘I/O操作,提高数据库的性能。

此外,Change Buffer的使用时机也受到一些参数和配置的影响。例如,可以通过调整InnoDB存储引擎的相关参数来控制Change Buffer的行为和触发条件。在实际应用中,需要根据具体的业务场景和性能需求进行合理的配置和优化。

四.数据库崩溃时 Change Buffer 的行为

当 MySQL 数据库发生崩溃或停止运行时,InnoDB 会通过 Crash Recovery 机制来恢复数据库。Change Buffer 中的变更不会丢失,InnoDB 会在恢复过程中利用 Redo Log 重新应用这些未写入磁盘的更改。

具体而言:

  • Change Buffer 中存储的变更(如插入、删除等)会在数据库崩溃恢复时被合并到相关的二级索引数据页。
  • 恢复时,InnoDB 会检查并重新应用所有记录在 Change Buffer 中的更改,确保它们正确地反映在数据库的磁盘存储中。

五.Change Buffer 的优缺点

优点:
  1. 减少磁盘 I/O: Change Buffer 可以有效减少每个数据页的磁盘 I/O 操作,提升数据库性能。
  2. 提高写入吞吐量: 延迟写入机制提高了系统的写操作吞吐量,尤其在高并发场景下表现尤为突出。
  3. 减少写放大效应: 多个修改操作可以批量处理,从而减少磁盘的写放大效应。
缺点:
  1. 内存占用: Change Buffer 会占用一定的内存资源,若系统内存不足,可能会影响性能。
  2. 延迟性: 虽然 Change Buffer 可以提升写入性能,但它也引入了延迟,特别是在需要实时反映数据更改的应用中,可能不是最佳选择。

六.如何管理 Change Buffer?

InnoDB 提供了几个参数来管理 Change Buffer 的大小和行为,常用的包括:

  • innodb_change_buffer_max_size:这个参数设置 Change Buffer 的最大大小,默认值是 25%,即最多占用 InnoDB 缓存池的 25%。
  • innodb_change_buffering:此参数控制哪些操作可以使用 Change Buffer。可以设置为 none(禁用 Change Buffer)、insert(仅插入操作使用 Change Buffer)或 all(所有修改操作都使用 Change Buffer)。
  • innodb_change_buffer_free_percent: 这个参数定义了Change Buffer中保留给将来更改的空间百分比。当Change Buffer的使用率达到这个百分比时,InnoDB会开始将一些更改写入到磁盘上的重做日志中。

总结

MySQL 的 Change Buffer 是 InnoDB 存储引擎中的一个优化机制,它通过将对二级索引的修改操作延迟到数据页被访问时才写入磁盘,显著减少了磁盘 I/O,提升了数据库的写入性能和并发能力。对于高并发、高写入负载的数据库应用,Change Buffer 能有效降低磁盘访问压力,提高系统吞吐量。

数据页被访问时才写入磁盘,显著减少了磁盘 I/O,提升了数据库的写入性能和并发能力。对于高并发、高写入负载的数据库应用,Change Buffer 能有效降低磁盘访问压力,提高系统吞吐量。

然而,Change Buffer 并非没有缺点。它增加了内存占用,并且由于延迟写入,可能会导致某些实时应用对数据一致性的要求受到影响。因此,理解 Change Buffer 的作用和管理策略,可以帮助开发者在实际应用中合理配置和优化数据库性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920852.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spark 之 Aggregate

Aggregate 参考链接: https://github.com/PZXWHU/SparkSQL-Kernel-Profiling 完整的聚合查询的关键字包括 group by、 cube、 grouping sets 和 rollup 4 种 。 分组语句 group by 后面可以是一个或多个分组表达式( groupingExpressions )…

C#高级:Winform中的自定义窗体输入

目录 一、多样式输入(无封装) 1.代码 2.效果 二、单输入框封装 1.使用 2.封装 3.效果 三、组合框批量输入封装 1.使用 2.封装 3.效果 一、多样式输入(无封装) 1.代码 private async void button1_Click(object send…

使用GDB或Delve对已经运行起来的Go程序进行远程调试

同步发布在我的博客,欢迎来点赞。 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 背景 Java 程序可以很方便地通过 jdwp 参数指定一个对外端口进行远程调试,如 java \ -agentlib…

简单实现QT对象的[json]序列化与反序列化

简单实现QT对象的[json]序列化与反序列化 简介应用场景qt元对象系统思路实现使用方式题外话 简介 众所周知json作为一种轻量级的数据交换格式,在开发中被广泛应用。因此如何方便的将对象数据转为json格式和从json格式中加载数据到对象中就变得尤为重要。 在python类…

Java开发经验——开发常用工具类

摘要 本文介绍了Java开发中常用的工具类,包括Apache Commons Collections的SetUtils、Google Guava的Sets、Apache Commons Lang的ArrayUtils等,以及它们在集合操作、数组操作、字符串处理、JSON处理等方面的应用。文章还涉及了Optional类、Money工具类…

esp32c3开发板通过micropython的mqtt库连MQTT物联网消息服务器

MQTT介绍 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议,旨在设备之间进行通信,尤其是在网络条件较差的情况下。MQTT v3.1.1 和 MQTT v5 是该协议的两个主要版本。 MQTT v3.1.1: 优点&#xff…

【IDE】使用指南

定期更新实用技能,建议关注收藏点赞。 友情链接: 点击跳转常见代码编辑器的报错解决方案 目录 常用快捷键pycharm右下角边栏脚本头安装IDE的插件git配置TODO 代码编辑器里有许多小技巧,便于办公。本篇主要以pycharm,vscode等主流常用IDE为…

OpenGL入门009——漫反射在片段着色器中的应用

本节将在片段着色器中应用漫反射 文章目录 一些概念漫反射 实战简介dependenciesshadervsshader.fs utilsCube.cpp main.cppCMakeLists.txt最终效果 一些概念 漫反射 概述: 描述的是粗糙表面对光的反射,反射的光线相关各个方向均匀分布,与视…

删库跑路,启动!

起因:这是一个悲伤的故事,在抓logcat时 device待机自动回根目录了,而题主对当前路径的印象还停留在文件夹下,不小心在根目录执行了rm -rf * … 所以,这是个悲伤的故事,东西全没了…device也黑屏了&#xff…

Ubuntu下的Eigen库的安装及基本使用教程

一、Eigen库介绍 简介 Eigen [1]目前最新的版本是3.4,除了C标准库以外,不需要任何其他的依赖包。Eigen使用的CMake建立配置文件和单元测试,并自动安装。如果使用Eigen库,只需包特定模块的的头文件即可。 基本功能 Eigen适用范…

OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)

本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。 原文链接:分享|16个含源码和数据集的计算机视觉实战项目 本文将分享16个含源码和数据集的计算机视觉实战项目。具体包括: 1. 人…

MySQL win安装 和 pymysql使用示例

目录 一、MySQL安装 下载压缩包: 编写配置文件: 配置环境变量: 初始化服务和账户 关闭mysql开机自启(可选) 建议找一个数据库可视化软件 二、使用pymysql操作数据库 安装pymysql 示例代码 报错处理 一、My…

springboot基于微信小程序的停车场管理系统

摘 要 停车场管理系统是一种基于移动端的应用程序,旨在方便车主停车的事务办理。该小程序提供了便捷的停车和功能,使车主能够快速完成各项必要的手续和信息填写。旨在提供一种便捷、高效的预约停车方式,减少停车手续的时间和精力成本。通过该…

js:数组转换为字符串

1、使用join 通过join,将数组拼接,使用,进行分割 let array [a, b, c] let str array.join(,); console.log(str) 2、使用toString() const array [a, b, c] const string array.toString() console.log(string) 3、使用扩展运算符和…

npm上传自己封装的插件(vue+vite)

一、npm账号及发包删包等命令 若没有账号,可在npm官网:https://www.npmjs.com/login 进行注册。 在当前项目根目录下打开终端命令窗口,常见命令如下: 1、登录命令:npm login(不用每次都重新登录&#xff0…

路由缓存后跳转到新路由时,上一路由中的tip信息框不销毁问题解决

上一路由tip信息框不销毁问题解决 路由缓存篇问题描述及截图解决思路关键代码 路由缓存篇 传送门 问题描述及截图 路由缓存后跳转新路由时,上一个路由的tip信息框没销毁。 解决思路 在全局路由守卫中获取DOM元素,通过css去控制 关键代码 修改文…

uni-app 界面TabBar中间大图标设置的两种方法

一、前言 最近写基于uni-app 写app项目的时候,底部导航栏 中间有一个固定的大图标,并且没有激活状态。这里记录下实现方案。效果如下(党组织这个图标): 方法一:midButton的使用 官方文档:ta…

Apple Vision Pro开发003-PolySpatial2.0新建项目

unity6.0下载链接:Unity 实时开发平台 | 3D、2D、VR 和 AR 引擎 一、新建项目 二、导入开发包 com.unity.polyspatial.visionos 输入版本号 2.0.4 com.unity.polyspatial(单独导入),或者直接安装 三、对应设置 其他的操作与之前的版本相同…

xiaolin coding 图解网络笔记——基础篇

基础篇 Linux 系统是如何收发网络包的? 网络模型 为了使多种设备能通过网络相互通信,和为了解决不同设备在网络互连中的兼容性问题,国际标准化组织制定了开放式系统互连通信参考模型(Open System Interconnection Reference Mo…

【vba源码】导入excel批注信息

Hi,大家好呀! 又到了一周一分享的时间,上周繁忙的我都没有给大家直播,视频也没更新,那这周大家放心,都会给大家更新,今天我们来讲点啥呢?每周找优质的内容给大家更新是我最最痛苦的…