【MySQL】change buffer,buffer pool,redo log,bin log,undo log的作用

文章目录

  • Change Buffer
  • Buffer Pool
  • Redo Log
  • Bin Log
  • Undo Log
  • 这几个日志的协作流程

Change Buffer

当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。
在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。
需要说明的是,虽然名字叫作 change buffer,实际上它是可以持久化的数据。也就是说,change buffer 在内存中有拷贝,也会被写入到磁盘上。
将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。
除了访问这个数据页会触发 merge 外,系统有后台线程会定期 merge。在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。
显然,如果能够将更新操作先记录在 change buffer,减少读磁盘,语句的执行速度会得到明显的提升。
而且,数据读入内存是需要占用 buffer pool 的,所以这种方式还能够避免占用内存,提高内存利用率。

那么,什么条件下可以使用 change buffer 呢?
对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。
比如,要插入unique_key = 4这个记录,就要先判断现在表中是否已经存在 unique_key=4 的记录,而这必须要将数据页读入内存才能判断。如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。
因此,唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。

因此,对于数据本身就存在于内存中的情况,那么普通和唯一索引的性能差距不大。
但是如果数据不存在内存中,那么唯一索引由于需要把数据从磁盘读取到内存中,无法使用change buffer,因此性能差了很多。

通过上面的分析,我们已经清楚了使用 change buffer 对更新过程的加速作用,也清楚了 change buffer 只限于用在普通索引的场景下,而不适用于唯一索引。

那么,现在有一个问题就是:
普通索引的所有场景,使用 change buffer 都可以起到加速作用吗?
因为 merge 的时候是真正进行数据更新的时刻,而 change buffer 的主要目的就是将记录的变更动作缓存下来,所以在一个数据页做 merge 之前,change buffer 记录的变更越多(也就是这个页面上要更新的次数越多),收益就越大。
因此,对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。 这种业务模型常见的就是账单类、日志类的系统。反过来,假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价。所以,对于这种业务模式来说,change buffer 反而起到了副作用。

Buffer Pool

MySQL 中的 Buffer Pool 是为了优化磁盘 I/O 而引入的机制。MySQL 内部的页大小与操作系统的页大小可以不一致,MySQL 中的页大小通常是固定的,默认为16KB。

Buffer Pool 是一个内存区域,用于缓存从磁盘读取和维护的数据页。它的作用是减少磁盘 I/O 操作,提高数据库的性能和响应速度。当查询或修改数据时,MySQL 首先检查缓冲池中是否存在所需的数据页,如果存在,则可以直接从内存中读取或写入数据,从而避免了频繁的磁盘读写操作。

缓冲池的大小可以通过配置参数 innodb_buffer_pool_size 来设置。合理设置缓冲池的大小非常重要,过小的缓冲池可能导致频繁的磁盘 I/O,而过大的缓冲池可能浪费宝贵的内存资源。

为了更好地使用缓冲池,可以考虑以下几个方面:

根据系统的内存大小和数据库的访问模式设置合适的缓冲池大小。这需要综合考虑系统中其他进程和服务的内存需求。
监控缓冲池的使用情况,例如使用 show global status like ‘Innodb_buffer_pool%’ 命令来查看缓冲池的命中率、使用率等指标。可以根据监控结果来调整缓冲池大小。
确保表的索引足够优化,以最大程度地减少对磁盘的访问。
对于 Buffer Pool 中的数据如何保证与磁盘的数据一致性,InnoDB 引擎采用了写前日志(Write-Ahead Logging)的机制。在修改数据之前,InnoDB 会先将修改的数据写入日志文件(Redo Log),然后再将数据页更新到 Buffer Pool。这样即使系统崩溃或重启,可以通过日志的恢复操作来保证数据的一致性。

(WAL)写前日志是一种常见的数据库事务处理策略,旨在保证数据的持久性和一致性。在MySQL中,当进行数据修改操作时,InnoDB存储引擎首先会将修改操作写入日志文件(称为重做日志或者写前日志),然后再将相应的数据页更新到Buffer Pool中。这样做的好处是,即使在更新到磁盘之前发生了系统崩溃或断电等故障,数据库可以根据重做日志来恢复数据,保证数据的完整性和一致性。

换句话说,写前日志机制确保了数据的持久性,而Buffer Pool则用于提高查询性能,缓存经常访问的数据页,减少对磁盘的I/O操作。两者是协同工作的,保证了数据的安全性和数据库的高性能运行。

在正常情况下,MySQL 会根据一定的策略将 Buffer Pool 中的数据刷新到磁盘,以确保数据的持久性。
正常情况下,MySQL会定期将Buffer Pool中的脏页(已被修改但尚未写入磁盘的数据页)刷新到磁盘,以保证数据的持久性。刷新策略可以通过配置参数进行调整,如innodb_max_dirty_pages_pct和innodb_io_capacity等。

Redo Log

一言以蔽之:减少磁盘随机写,使用内存高速顺序写。提供奔溃数据恢复机制。

Redo Log日志为mysql提供了crash-safe的能力,也就是奔溃恢复能力。
我们知道,我们使用mysql的时候,其性能瓶颈在于随机的磁盘IO操作,因此如果能减少对磁盘IO的操作,那么能极大的提高性能。
我们再使用增删改操作的时候,其实就是一种随机IO操作,如果我们每次都把对应的操作数据从磁盘中读取出来然后修改再写入,那么性能可想而知的低。
所以,能不能有一种办法,我们能先把数据写到缓存(内存)中,然后再合适的时机再把这些数据写入到磁盘呢?
是有的,也就是我们所谓的Redo Log日志了。
当我们需要写入数据的时候,我们并不是把这些数据直接写入到磁盘,而是先写到redo log这种更快速的内存文件中,那么对性能的影响就会小很多了。
redo log中记录的是对mysql中数据块的操作。
当我们的mysql出现奔溃的时候,我们再次重启进行数据恢复的时候,就可以从redo log中把这些还没有写道磁盘中的数据给他进行写入,从而保证了数据一致性。

Bin Log

一言以蔽之:提供数据恢复,数据回滚,主从同步等功能。

Binlog(二进制日志)是MySQL中的一种日志文件,用于记录数据库的所有修改操作,例如插入、更新和删除。Binlog具有以下几个重要的作用和意义:

数据恢复与备份:Binlog可以用于数据的恢复与备份。通过将Binlog文件应用到MySQL实例中,可以将数据库还原到特定的时间点或特定的事务状态。这在数据丢失或数据库崩溃时非常有用。

主从复制:Binlog是MySQL主从复制的基础。在主从复制中,主数据库上的所有修改操作都会被记录到Binlog文件中,并通过网络传送给从数据库。从数据库根据Binlog文件的内容来执行相同的修改操作,从而保持与主数据库的数据一致性。

数据库同步与高可用性:Binlog可以用于实时地将变更操作传播到其他MySQL实例,从而实现数据库的同步和高可用性。通过将Binlog文件传输给其他MySQL实例,这些实例可以将变更操作应用到自己的数据库中,从而保持数据的一致性。

数据分析与查询回放:Binlog记录了数据库的所有修改操作,因此可以用于数据分析和查询回放。通过分析Binlog文件,可以了解到数据库的历史修改操作,进行性能分析、数据统计等工作。对于需要重放历史查询的场景,可以将Binlog文件应用到测试环境中,模拟执行查询操作。

在MySQL中,Bin Log是用于记录数据库的更改操作的二进制日志。以下是会写入Bin Log日志的操作:

DML语句(Data Manipulation Language):包括INSERT、UPDATE和DELETE语句,用于对表中的数据进行增、删、改操作。

DDL语句(Data Definition Language):包括CREATE、ALTER和DROP语句,用于创建、修改和删除数据库对象,如表、索引等。

DCL语句(Data Control Language):包括GRANT和REVOKE语句,用于授权和撤销权限。

数据更改函数和存储过程:如果函数或存储过程中包含了会修改数据的操作,那么执行这些函数或存储过程也会写入Bin Log日志。

写入Bin Log日志的目的是为了实现数据库的持久性和数据恢复。通过将更改操作记录到Bin Log中,可以在发生故障或数据丢失的情况下进行数据恢复和同步。此外,Bin Log日志还可以用于数据库复制、数据备份、数据迁移等场景。

Undo Log

一言以蔽之:MVCC多版本并发控制的视图所能看到的数据依赖于此。

Undo log(回滚日志)是MySQL InnoDB存储引擎中的一部分,用于实现事务的原子性和一致性。它的作用是记录事务操作的反向操作,以便在事务回滚或系统崩溃时,可以恢复到事务开始前的状态。

当一个事务开始时,InnoDB会为该事务创建一个undo log。在事务执行期间,如果发生了数据修改(例如插入、更新、删除),则会在undo log中记录相应的反向操作,以便在回滚时可以撤销这些修改。

具体而言,对于插入操作,undo log记录了插入的数据和哪个位置需要删除该数据;对于更新和删除操作,undo log记录了被修改或删除的数据和如何还原到原有状态的操作。

当一个事务需要回滚时,InnoDB会根据对应的undo log中的反向操作,将之前的数据修改撤销,恢复到事务开始前的状态。这种能力是事务的基本特性之一,保证了事务的原子性和一致性。

对于MySQL的性能影响来说,undo log会占用一定的存储空间。每个事务的undo log都需要先写入磁盘,这可能引起一定的IO开销。同时,在事务并发执行时,undo log的管理和读写也会引起一些额外的开销,因此在高并发场景下,需要合理设置undo log的大小和管理策略,以保证系统性能的平衡。

Undo log在MySQL InnoDB存储引擎中与多版本并发控制(MVCC)密切相关,并且在MVCC中起到重要作用。MVCC是一种并发控制机制,用于实现高并发环境下的事务隔离性。

MVCC通过为每个事务分配唯一的事务ID(Transaction ID)和版本号来管理事务的并发访问。当一个事务开始时,会记录当前数据库中的快照版本。随着事务的进行,其他事务可以继续对数据库进行读操作,读取快照版本的数据,而不会受到当前事务所做的修改的影响。

这就引入了undo log的作用。在MVCC中,当一个事务正在对数据进行修改时,为了保证其他事务能够读取到一致的数据,InnoDB会将修改前的数据拷贝一份到undo log中,并在undo log中记录该操作的版本号。

当其他事务读取数据时,如果该数据被正在进行修改的事务修改了,InnoDB会根据事务的版本号和undo log中的信息,通过回滚操作将该数据还原到修改前的状态,然后读取这个被还原的数据,保证了读取的一致性。

因此,undo log在MVCC中的作用是提供了用于还原数据的历史版本,以确保事务读取的数据是一致的。它用于实现数据的回滚和回滚段的管理,为MVCC提供了必要的支持。

需要注意的是,MVCC不仅仅依赖于undo log,还与其他机制(如读视图、回滚段等)紧密结合,以实现事务的隔离性和并发控制。undo log作为其中的一部分,发挥了关键的作用。

这几个日志的协作流程

当根据修改请求对应的数据是否在内存中,分别对这些日志进行操作的执行流程如下:

Change Buffer:首先,修改操作会在内存的Change Buffer中进行记录。Change Buffer是MySQL的一种机制,用于延迟对磁盘上对应页的实际修改,以提高性能。修改操作在Change Buffer中被记录下来,而不是立即写入磁盘上的对应页。

Buffer Pool:数据在内存中的主要存储位置是Buffer Pool(也称为页缓存)。当修改操作需要读取数据页时,MySQL会先检查Buffer Pool中是否存在要修改的页。如果存在,就直接在Buffer Pool中进行修改操作。如果要修改的页不在Buffer Pool中,那么下次查询出来这条数据的时候,我们就会把他加载到Buffer Pool并且使用Change Buffer里面的修改操作来对他进行操作。

Undo Log:在修改操作执行过程中,MySQL会将对原始数据的修改操作记录到Undo Log中。Undo Log用于回滚事务或者恢复数据到之前的版本。通过记录修改前的数据,MySQL可以在需要时撤销或回滚修改操作。

Redo Log:同时,修改操作的日志也会写入到Redo Log中。Redo Log是用于崩溃恢复的重要日志。它记录了所有的修改操作,以保证即使在异常情况下数据的持久性。

Bin Log:最后,修改操作还会记录到Bin Log(二进制日志)中。Bin Log是用于复制和恢复的日志。通过记录修改操作,可以在主从服务器之间同步数据,并且可以用于在灾难恢复时恢复数据。
注意,最后写Bin Log日志以及Redo Log日志的过程涉及到两阶段提交。

也就是不论是否使用到Change Buffer,只要我们做了修改操作,我们就会写入数据到redo log中

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

请问如何用oracle触发器实现不允许新增/删除表/增加/减少/修改字段类型

请问如何用oracle触发器实现不允许新增/删除表/增加/减少/修改字段类型 给本帖投票 56211打赏收藏 分享 转发到动态举报 写回复 性能测试中发现oracle11g数据库每天22点,oralce进程CPU占用率突增>> 11 条回复 切换为时间正序 请发表友善的回复… 发表回复 microsof…

最新版本的OpenLens,有两个隐藏技能

最新版本的OpenLens v6.4.15,有两个隐藏技能 1、需要添加扩展插件alebcay/openlens-node-pod-menu,查看pod时才会出现进入命令行的按钮 2、测试环境查看pod、node时可能会出现监控数据未显示,点击集群的Setting,在Metrics里选…

软件测试用例的八大步骤你都知道吗?

目录 第一步、UI体验测试 第二步、功能完整性测试 第三步、业务流程测试 第四步、容错机制测试 第五步、常规性测试 第六步、性能测试 第七步、交互体验测试 第八步、兼容性测试 总结: 第一步、UI体验测试 1.风格、样式、颜色是否协调 2. 界面布局是否整齐、…

Linux和Shell笔记-2基本的bash shell命令

Linux文件系统及相关操作 与windows前面标明盘符不同,Linux采用了将文件存储在单个目录结构中,这个目录被称为虚拟目录。 Linux使用正斜线( / )而不是反斜线( \ ) 在文件路径中划分目录。Linux中反斜线用来标识转义字符,因此不能用在文件路…

【C++】开源:cpp-tbox百宝箱组件库

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍cpp-tbox百宝箱组件库。 无专精则不能成,无涉猎则不能通。。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,…

【大数据之Hive】二十五、HQL语法优化之小文件合并

1 优化说明 小文件优化可以从两个方面解决,在Map端输入的小文件合并,在Reduce端输出的小文件合并。 1.1 Map端输入文件合并 合并Map端输入的小文件是指将多个小文件分到同一个切片中,由一个Map Task处理,防止单个小文件启动一个M…

Jenkins (一)

Jenkins (一) Docker Jenkins 部署 一. 安装 jenkins $ mkdir -p /home/tester/data/docker/jenkins $ vim jenkins:lts-jdk11.sh./jenkins:lts-jdk11.sh 内容 #! /bin/bash mkdir -p /home/tester/data/docker/jenkins/jenkins_homesudo chown -R 1000:1000 /home/tester/da…

后端查询出的数据库数字自动补零和不补零

select CAST(YTD_CHANGE*100 as decimal(18,1)), round(YTD_CHANGE*100,1) from RP where data_date 20211231补零 round(PYTD_CHANGE_PER*100,1)不补零 CAST(PYTD_CHANGE_PER*100 as decimal(18,1))

PageHelper分页失效,只能查出第一页

PageHelper分页失效&#xff0c;只能查出第一页 1. 现象2. 原因3. PageHelper工作原理 1. 现象 分页代码如下&#xff1a; int pageId Constants.ONE;boolean isHasNextPage;do {PageHelper.startPage(pageId, Constants.DEFAULT_PAGE_SIZE);List<String> projectIdLi…

【SCI一区】【电动车】基于ADMM双层凸优化的燃料电池混合动力汽车研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 1.2 电动车动力学方程 1.3 电池模型 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、数据、文章讲解 &#x1f4a5;1 概述 文献来源&#xff1a; 随着车辆互联性的出现&#xff0c;互联汽车 (CVs) 在增强道路安全、改…

数学建模-图论 最短路径

作图 %% 注意&#xff1a;以下代码需要较新版本的matlab才能运行&#xff08;最好是2016版本及以上哦&#xff09; % 如果运行出错请下载新版的matlab代码再运行%% Matlab作无向图 % &#xff08;1&#xff09;无权重&#xff08;每条边的权重默认为1&#xff09; % 函数graph(…

ES(2)基本使用

文章目录 创建索引查询索引查询 shopping索引查询所有索引 删除索引数据操作添加查询查询指定id数据 查询所有数据修改完全覆盖局部修改 删除 复杂查询操作条件查询根据字段名和值查询对应数据全量查询分页查询显示指定字段排序查询 多条件查询must&#xff08;and&#xff09;…

spring复习:(29)MutablePropertyValues

该类通过成员变量 propertyValueList 来保存多个PropertyValue对象。 public class MutablePropertyValues implements PropertyValues, Serializable {private final List<PropertyValue> propertyValueList;Nullableprivate Set<String> processedProperties;pr…

SQL进阶(2)——SQL语句类型 增删改查CRUD 事务初步 表关联关系 视图 +索引

目录 引出SQL语句类型1.DML数据操纵语言&#xff08;重点&#xff09;2.DQL数据查询语言&#xff08;重点&#xff09;3.DDL(Data Definition Language了解)4.DCL(Data Control Language了解)5.TCL 事务控制语言 运算符和其他函数1.运算符2.其它函数增删改查CRUD 视图索引事务1…

基于Python的用户和项目协同过滤算法实现与解析——以余弦相似度和最近邻居为基础的推荐系统构建

基于Python的用户和项目协同过滤算法实现与解析——以余弦相似度和最近邻居为基础的推荐系统构建 摘要 本篇文章主要讲解如何使用Python来编写基于用户的协同过滤算法和基于项目的协同过滤算法。我们首先了解这两种协同过滤算法的概念和原理,接着通过Python代码实现这两种算…

如何克服Leetcode做题的困境

文章目录 如何克服Leetcode做题的困境问题背景克服困境的建议实践与理论结合切忌死记硬背分析解题思路不要过早看答案迭代式学习寻求帮助坚持与耐心查漏补缺 结论 如何克服Leetcode做题的困境 问题背景 明明自觉学会了不少知识&#xff0c;可真正开始做Leetcode题目时&#x…

内存参数问题导致内存溢出

问题&#xff1a;内存参数问题导致内存溢出 1、文件过大&#xff0c;进行分块 2、 运行参数&#xff0c;使用最大内存配置2时&#xff0c;导致空指针异常。 3、获取详细报错信息-内存溢出 多线程捕获Throwable异常 修改代码&#xff0c;捕获Throwable&#xff0c;获取异常 异…

vue中预览pdf

情况一 如果后端返回的pdf地址&#xff0c;粘贴到浏览器的url框中&#xff0c;可以在浏览器中直接进行预览的&#xff0c;那么我们就用window.open&#xff0c;或 a标签&#xff0c;或iframe标签通过设置src进行预览即可 法1&#xff1a;可以直接使用window.open&#xff08;…

leetcode100.相同的树

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;相同的树 1️⃣ 代码&#xff1a; bool isSameTree(struct TreeNode* p, struct TreeNode* q){// 判断两棵树当前结点是否为空if (p NULL && q NULL) {// 说明是相同的return true;}// 来到这里有几种情况// …

【裸辞转行】是告别,也是新的开始

一年多了没有更新&#xff0c;是因为去年身体加心理因素辞职了&#xff0c;并且大概率不会再做程序员了&#xff0c;嗯。本来觉得可能再也不会打开 CSDN 了&#xff0c;想了想&#xff0c;还是来做个告别吧&#xff0c;任何事情都该有始有终才对。 回忆碎碎念 是在去年的 11 …