MySQL十七:Change Buffer

转载~

在之前的文章介绍的InnoDB的存储结构的组成中,我们知道Change Buffer也是用InnoDB内存结构的组成部分。

MySQL十七:Change Buffer

Change Buffer主要是为了在写入是减少磁盘IO而存在的,

一、什么是什么是Change Buffer

「在 中介绍了buffer pool会缓存热的数据页和索引页,减少磁盘读操作,而对于磁盘的写操作,innoDB同样也有类似的策略,即通过change buffer缓解磁盘写操作产生的磁盘IO」

  • 「Change Buffer是在【非唯一普通索引页】不在buffer pool中时,当对页进行了写操作时,在不影响数据一致性的前提下。InnoDB会将数据先写入Change Buffer中,等未来数据被读取时,再将 change buffer 中的操作merge到原数据页中」
  • 在MySQL5.5之前,只针对insert做了优化,叫插入缓冲(insert buffer),后面进行了优化,对delete和update也有效,叫做写缓冲(change buffer)。

二、Change buffer 执行过程

「我们知道当执行写操作时,数据页存在于Buffer Pool中时,会直接修改数据页。那如果数据页不存在于Buffer Pool中时,过程会有一些不一样,这种情况会将写操作缓存到Change Buffer中,等未来在特定条件下其合并到Buffer Pool中」。因此当需要执行一个写入操作时,一般分为走Change buffer和不走Change buffer两种情况。

2.1 写入的数据页在内存中

这种情况在在《Buffer Pool》的第4.3.2节 Flush链表写入过程中已经提过了,感兴趣的可以去看看,不看也没关系,这里在写一遍,凑一下字数~~

当我们在写入数据的时候,写入的数据页在内存中,MySQL不会直接更新直接更新磁盘,而是经过以下两个步骤:

  • 第一步:更新Buffer Pool中的数据页,一次内存操作;
  • 第二步:将更新操作顺序写Redo log,一次磁盘顺序写操作;

这样的效率是最高的。顺序写Redo log,每秒几万次,问题不大。

MySQL十七:Change Buffer

「这种情况是被更新的数据已经别加载到Buffer Pool的前提下」

  • 「是否会产生数据一致性问题」 「因此写入的数据页在内存中这中情况不会产生数据一致性问题」
    *
  • 读取数据,会命中缓冲池的页(已经被修改)。
  • 缓冲池LRU数据淘汰,则会将【脏页】刷回磁盘。
  • 数据库奔溃,redo log可以恢复数据。

2.2 写入的数据页不在内存中

当我们修改的数据所在的数据页之前没有别读取过,或者干脆就是一条插入语句,则会经过以下两个步骤:

  • 第一步:在Change buffer中记录这个写入操作,一次内存操作。
  • 第二步:将写入操作顺序写Redo log,一次磁盘顺序写操作;

可以看到,这种方式跟上面的方式 「仅仅只是第一步写入的位置不一样而已,而且都是内存操作」
如果没有Change buffer,那更新可能会变成

  • 第一步:先从磁盘读取所在数据页加载到缓冲池,一次磁盘随机读操作;
  • 第二步:更新Buffer Pool中的数据页,一次内存操作;
  • 第三步:将更新操作顺序写Redo log,一次磁盘顺序写操作;

也就是会多一次磁盘IO,磁盘IO相比较内存操作时很慢的,并发下性能就会急剧下降。

MySQL十七:Change Buffer

这种方式的效率跟第一次差不多,写缓冲是降低磁盘IO,提升数据库写性能的一种机制。

「是否会产生数据一致性问题」

  • 读取数据,会将Change Buffer中的数据合并到Buffer Pool中。
  • 如果没有读取,Change也会被被定期刷盘到写缓冲系统表空间。
  • 数据库奔溃,redo log可以恢复数据。

「因此写入的数据页不在内存中这中情况也不会产生数据一致性问题」

三、Change Buffer大小配置

「从下图中可以看出,Change Buffer被包含在了Buffer Pool中的,change buffer用的是buffer pool里的内存,由于Buffer Pool的内存大小是有限制的,所以change buffer大小也是有限制的,可通过参数innodb_change_buffer_max_size设置」

MySQL十七:Change Buffer
show variables like '%innodb_change_buffer_max_size%';

MySQL十七:Change Buffer
  • innodb_change_buffer_max_size表示允许change_buffer占Buffer Pool总大小的百分比,默认值为25%,最大可设置为50%。
    *
  • 当在系统中有大量插入,更新和删除操作时,可以增大innodb_change_buffer_max_size,以提高系统的写入性能。
  • 当在系统中有大量查询操作时,可以减小innodb_change_buffer_max_size,以减少Buffer Pool中数据页的淘汰的概率,提高系统的读取性能。
  • innodb_change_buffer_max_size 设置是动态的,它允许修改设置而无需重新启动服务器。

四、配置Change Buffer的类型

「前面说到Change Buffer在MySQL5.5之后可以支持新增、删除、修改的写入,对于受I/O限制的操作(大量DML、如批量插入)有很大的性能提升价值。但是对于一些特定的场景,可以通过修改innodb_change_buffering来变更Change Buffer支持的类型,分别为插入,删除,清除启用或禁用缓冲,更新操作是插入和删除的组合」

show variables like '%innodb_change_buffering%';

MySQL十七:Change Buffer
  • all :默认值,缓冲区插入,删除和清除。
  • none:不缓存任何操作
  • inserts:缓冲区插入操作。
  • deletes:缓冲区删除标记操作。
  • changes:缓冲区插入和删除标记操作。
  • purges:缓冲区在后台发生的物理删除操作。

五、Change buffer被merge的时机

既然Change buffer是单独内存中,写入之后会被合并到Buffer Pool中,那么是时候时候会被merge呢?

「Change buffer会被merge触发时机」

  • 读取Change buffer中记录的数据页时,会将Change buffer合并到buffer Pool 中,然后被刷新到磁盘。
  • 当系统空闲或者slow shutdown时,后台master线程发起merge。
  • change buffer的内存空间用完了,后台master线程会发起merge。
  • redo log写满了,但是一般不会发生。

六、Change buffer为什么只对非唯一普通索引页有效

「不知道大家有没有印象,在本文第一节就重点说了一个词【非唯一普通索引页】,Change buffer只有在非唯一普通索引页时才生效,这是为什么呢?」

相信大家在日常工作中会经常遇到一个问题: 「主键冲突」

  • 「主键索引,唯一索引」 实际上对于【唯一索引】的更新,插入操作都会 「先判断当前操作是否违反唯一性约束」,而这个操作就必须要将索引页读取到内存中,此时既然已经读取到内存了,那直接更新即可,没有需要在用Change buffer了。
  • 「非唯一普通索引」 「不需要判断当前操作是否违反唯一性约束」,也就不需要将数据页读取到内存,因此可以直接使用 change buffer 更新。

「基于此,Change buffer只有对普通索引可以使用,对唯一索引的更新无法生效」

Original: https://www.cnblogs.com/yunlongn/p/16630261.html
Author: 云扬四海
Title: MySQL十七:Change Buffer

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/588782/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【转】【OpenGL】【OpenGLSE】opengl shader 内置变量和函数

    1、uint CreateShader(enum type) : 创建空的shader object; type: VERTEX_SHADER, 2、void ShaderSour…

    Java 2023年5月29日
    080
  • java生成机器码

    java根据系统参数生成每个计算机的唯一标识。 获取CPU序列号 /** * 获取CPU序列号 * @return * @throws IOException */ public …

    Java 2023年6月16日
    079
  • 【spring-boot】mybatis 使用入门

    新建项目 设置项目名称 设置为Web项目 工程初始化 目录结构 相关配置文件修改 配置pom.xml文件 1.修改pom.xml文件,添加mybatis配置 mysql mysql…

    Java 2023年5月29日
    0104
  • Java 字符串常量池 及 intern 方法的使用

    参考这篇文章:深入解析String#intern – 美团技术团队 (meituan.com) jdk7 版本对 intern 操作和常量池都做了一定的修改,主要包括2…

    Java 2023年5月29日
    090
  • numpy中矩阵的逆,求解,特征值,特征向量

    逆:numpy.linalg.inv() 求矩阵的逆import numpy as npa=np.mat(‘1 0;0 1’)#生成一个矩阵print(ty…

    Java 2023年6月8日
    082
  • 2021 — 冰与火之歌

    大半夜的睡不着,越发的想给 2021 年作个总结,一想更睡不着了,来唠叨下吧。 一拖再拖的婚礼。本来定在今年正月的婚礼,因为疫情,不敢办,村里也不让办;然后选在国庆吧,卧槽,封城了…

    Java 2023年6月7日
    068
  • java static learning

    /static learning / class one { public int a = 5; static { // 类加载时就运行代码码 System.out.println…

    Java 2023年5月29日
    074
  • maven

    聚合 作用:聚合用于快速构建maven工程,一次性构建多个项目/模块。 制作方式: 创建一个空模块,打包类型定义为pom 定义当前模块进行构建操作时关联的其他模块名称 &#…

    Java 2023年6月7日
    075
  • 没那么简单的单例模式

    作者:小牛呼噜噜 | https://xiaoniuhululu.com计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 什么是单例 单例的应用场景 单…

    Java 2023年6月15日
    066
  • CentOS7-ElasticSearch的使用

    1.下载 ElasticSearch官方下载地址​www.elastic.co/cn/downloads/past-releases#elasticsearch 最好选择版本7.x…

    Java 2023年6月7日
    074
  • 【校招VIP】[Java][二本][5分]开发岗简历项目最好有两个

    关注 【校招VIP】公众号,回复【简历】,添加校招顾问微信,即可获取简历指导! 本份简历是一位21届二本前端同学的简历,简历评分7分。 一、学员简历 二、指导意见 简历模板没有问题…

    Java 2023年6月5日
    078
  • 【转载】SpringCloud-Eurek 心跳阈值说明

    在使用eureka过程中,查看监控界面,出现: Renews threshold:server期望在每分钟中收到的心跳次数Renews (last min):上一分钟内收到的心跳次…

    Java 2023年5月29日
    069
  • 微服务SpringCloud之服务网关zuul二

    Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是”PRE”、”ROUTING&#822…

    Java 2023年5月30日
    079
  • Java 根据XPATH批量替换XML节点中的值

    根据XPATH批量替换XML节点中的值 by: 授客 QQ:1033553122 测试环境 JDK 1.8.0_25 代码实操 _message.xml_文件 xxxxxxxxxx…

    Java 2023年6月16日
    0105
  • LeetCode——任务调度器

    这道题一上手会犯直接找模拟方法,然后根据模拟方法来得出结果。也不是说直接找模拟方法不对,只是说一开始没有更深入的思考的话,模拟方法很可能是错的,导致浪费时间,像这种题,要注意其中的…

    Java 2023年6月10日
    062
  • springBoot 获取注解参数的原理

    判断每个参数带有注解是哪个,是否存在相应的解析器 寻找合适的处理适配器 DispatcherServlet中的 doDispatch方法 // Determine handler …

    Java 2023年6月16日
    071
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球