MySQL中Buffer pool、Log Buffer和redo、undo日志介绍

MySQL中Buffer pool、Log Buffer和redo、undo日志介绍

  • Buffer Pool 原理
  • MySQL中的内存结构
    • Buffer Pool
    • Change Buffer
    • Log Buffer
  • redo和undo日志
    • redo日志
      • 为什么需要REDO日志
      • redo log 基本概念
      • redo的组成
      • redo的整体流程
      • redo log的刷盘策略
  • undo 日志
    • undo log 基本概念
    • undo log的作用
  • 面试题一、 undo log、redo log、 bin log的作用是什么?
  • 面试题二、redo log与bin log的区别?

Buffer Pool 原理

缓冲池是InnoDB存储引擎中一块连续的内存区域,用于缓存磁盘上的数据页和索引页。由于内存访问速度远快于磁盘访问,因此将经常访问的数据和索引加载到缓冲池中,可以显著提高数据库的读写性能。缓冲池的工作原理主要基于“时间局部性”和“空间局部性”原则,即最近访问过的数据在未来很可能再次被访问,且一个数据项被访问时,与其相邻的数据项也很可能被访问。

MySQL中的内存结构

MySQL中内存结构由多个缓冲区构成主要由Buffer Pool、Change Buffer和Log Buffer,如下图所示
在这里插入图片描述

Buffer Pool

Buffer Pool:缓冲池是主内存中的一个区域(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。

Buffer Pool默认大小是128M, 以Page页为单位,Page页默认大小16K,如上图中的每个小方格代表Page页。底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:

  • free page : 空闲page,未被使用
  • clean page:被使用page,数据没有被修改过
  • dirty page:脏页,被使用page,数据被修改过,Page页中数据和磁盘的数据产生了不一致

Change Buffer

Change Buffer :更改缓存区(针对非唯一二级索引),在执行DML(insert、update)语句时,如果这些数据的Page没有在Buffer Pool中,不会直接操作磁盘,而会将数据变更操作存在缓冲区Change Buffer中,在未来数据被读取到Buffer Pool中,再将数据合并到Buffer Pool中,最后将合并后的数据刷新到磁盘中。

change buffer更新流程
在这里插入图片描述
Change Buffer的意义是什么?

与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引,(聚集索引通常是有序插入)。这样随机顺序的插入会导致删除和更新操作可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了Change Buffer之后,我们可以在缓冲池Buffer Pool中进行合并处理,减少磁盘IO。

在进行修改时,如果索引设置唯一性,InnoDB必须要做唯一性校验,因此必须查询磁盘,做一次IO操作。会直接将记录查询到BufferPool中,然后在缓冲池修改,不会在ChangeBuffer操作。

Log Buffer

Log Buffer :日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log、undo log)默认大小16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除多行的事务,增加日志缓冲区的大小可以节省磁盘IO。
其中两个重要的参数

  • innodb_log_buffer_size:缓冲区大小
  • Innodb_flush_log_at_trx_commit:日志刷新到磁盘的时机

redo和undo日志

事务有4种特性:原子性、一致性、隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢?

  • 事务的隔离性由 锁机制 实现。
  • 而事务的原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。

REDO LOG 称为 重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持
久性。

UNDO LOG 称为 回滚日志 ,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。
有的DBA或许会认为 UNDO 是 REDO 的逆过程,其实不然。

redo日志

InnoDB存储是以页为单位来管理存储空间的,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页会以一定的频率被刷入磁盘中(checkpoint机制),通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能。

为什么需要REDO日志

  1. 一方面,缓冲池可以帮助我们消除CPU和磁盘之间的鸿沟,checkpoint机制可以保证数据的最终落盘,然而由于checkpoint 并不是每次变更的时候就触发 的,而是master线程隔一段时间去处理的。所以最坏的情况就是事务提交后,刚写完缓冲池,数据库宕机了,那么这段数据就是丢失的,无法恢复。
  2. 另一方面,事务包含 持久性 的特性,就是说对于一个已经提交的事务,在事务提交后即使系统发生了崩溃,这个事务对数据库中所做的更改也不能丢失。

那么如何保证这个持久性呢?

一个简单的做法 :在事务提交完成之前把该事务所修改的所有页面都刷新到磁盘,但是这个简单粗暴的做法有些问题另一个解决的思路 :我们只是想让已经提交了的事务对数据库中数据所做的修改永久生效,即使后来系统崩溃,在重启后也能把这种修改恢复出来。所以我们其实没有必要在每次事务提交时就把该事务在内存中修改过的全部页面刷新到磁盘,只需要把 修改 了哪些东西 记录一下 就好。

比如,某个事务将系统表空间中 第10号 页面中偏移量为 100 处的那个字节的值 1 改成 2,我们只需要记录一下:将第0号表空间的10号页面的偏移量为100处的值更新为 2 。

redo log 基本概念

  • InnoDB引擎对数据的更新,是先将更新记录写入redo log日志,然后会在系统空闲的时候或者是按照设定的更新策略再将日志中的内容更新到磁盘之中。
    这就是所谓的Write-Ahead Log(预先日志持久化):在持久化一个数据页之前,先将内存中相应的日志页持久化。
  • redo log:被称作重做日志, 包括两部分:一个是内存中的日志缓冲: redo log buffer,另一个是磁盘上的日志文件: redo log file

redo的组成

Redo log可以简单分为以下两个部分:redo log buffer、redo log file

  1. 重做日志的缓冲 (redo log buffer),保存在内存中,是易失的。
    参数设置:innodb_log_buffer_size:
    redo log buffer 大小,默认 16M,最大值是4096M,最小值为1M。
mysql> show variables like '%innodb_log_buffer_size%';
+------------------------+----------+
| Variable_name     | Value  |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
  1. 重做日志文件 (redo log file),保存在硬盘中,是持久的。

redo的整体流程

以一个更新事务为例,redo log 流转过程,如下图所示:

在这里插入图片描述

1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝
第2步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
第3步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加写的方式
第4步:定期将内存中修改的数据刷新到磁盘中

redo log的刷盘策略

redo log的写入并不是直接写入磁盘的,InnoDB引擎会在写redo log的时候先写redo log buffer,之后以 一定的频率 刷入到真正的redo log file 中。这里的一定频率怎么看待呢?这就是我们要说的刷盘策略。
在这里插入图片描述
注意,redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是刷入到 文件系统缓存(OS Buffer)中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定

innodb_flush_log_at_trx_commit 参数设置

针对这种情况,InnoDB给出 innodb_flush_log_at_trx_commit 参数,该参数控制 commit提交事务
时,如何将 redo log buffer 中的日志刷新到 redo log file 中。

缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统缓冲区( OS Buffer )。因此, redo log buffer 写入 redo logfile 实际上是先写入 OS Buffer,然后再通过系统调用 fsync() 将其刷到 redo log file.

Redo Buffer 持久化到 redo log 的策略,可通过 Innodb_flush_log_at_trx_commit 设置:

参数值含义
0 (延迟写)事务提交时不会将 redo log buffer中日志写入到 os buffer, 而是每秒写入 os buffer并调用 fsync()写入到 redo log file中。 也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。
1 (实时写,实时刷)事务每次提交都会将 redo log buffer中的日志写入 os buffer并 调用 fsync()刷到 redo log file中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。
2 (实时写, 延时刷)每次提交都仅写入到 os buffer,然后是每秒调用 fsync()os buffer中的日志写入到 redo log file

在这里插入图片描述
一般建议选择取值2,因为 MySQL 挂了数据没有损失,整个服务器挂了才会损失1秒的事务提交数据

undo 日志

undo log 基本概念

  • undo log是一种用于撤销回退的日志,在数据库事务开始之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。

  • Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收处理。

注意: undo log也会产生redo log,因为undo log也要实现持久性保护。

undo log的作用

  1. 提供回滚操作【undo log实现事务的原子性】

    在数据修改的时候,不仅记录了redo log,还记录了相对应的undo log,如果因为某些原因导致事务执行失败了,可以借助undo log进行回滚。

    undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

  2. 提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)
    MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。

总体记录undo日志和redo日志流程如下图:

先找是否有加载对应的BufferPool有就使用没有就加载读取 ----> 写入UndoLog —>操作执行数据 —> 写入RedoLogBuffer内存 ----> 写入RedoLog到磁盘文件
在这里插入图片描述

面试题一、 undo log、redo log、 bin log的作用是什么?

undo log 基本概念

  • undo log是一种用于撤销回退的日志,在数据库事务开始之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
  • Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收处理。

注意: undo log也会产生redo log,因为undo log也要实现持久性保护。

undo log的作用

  1. 提供回滚操作【undo log实现事务的原子性】
    在数据修改的时候,不仅记录了redo log,还记录了相对应的undo log,如果因为某些原因导致事务执行失败了,可以借助undo log进行回滚。
    undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
  2. 提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)
    MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。

redo log 基本概念

  • InnoDB引擎对数据的更新,是先将更新记录写入redo log日志,然后会在系统空闲的时候或者是按照设定的更新策略再将日志中的内容更新到磁盘之中。这就是所谓的预写式技术(Write Ahead logging)。这种技术可以大大减少IO操作的频率,提升数据刷新的效率。
  • redo log:被称作重做日志, 包括两部分:一个是内存中的日志缓冲: redo log buffer,另一个是磁盘上的日志文件: redo log file

redo log的作用

  • mysql 每执行一条 DML 语句,先将记录写入 redo log buffer 。后续某个时间点再一次性将多个操作记录写到 redo log file 。当故障发生致使内存数据丢失后,InnoDB会在重启时,经过重放 redo,将Page恢复到崩溃之前的状态 通过Redo log可以实现事务的持久性 。

bin log基本概念

  • binlog是一个二进制格式的文件,用于记录用户对数据库更新的SQL语句信息,例如更改数据库表和更改内容的SQL语句都会记录到binlog里,但是不会记录SELECT和SHOW这类操作。
  • binlog在MySQL的Server层实现(引擎共用)
  • binlog为逻辑日志,记录的是一条SQL语句的原始逻辑
    • binlog不限制大小,追加写入,不会覆盖以前的日志.
    • 默认情况下,binlog日志是二进制格式的,不能使用查看文本工具的命令(比如,cat,vi等)查看,而使用mysqlbinlog解析查看。

bin log的作用

  1. 主从复制:在主库中开启Binlog功能,这样主库就可以把Binlog传递给从库,从库拿到Binlog后实现数据恢复达到主从数据一致性。
  2. 数据恢复:通过mysqlbinlog工具来恢复数据。

面试题二、redo log与bin log的区别?

1)redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。

2)redo log是物理日志,记录的是“在XXX数据页上做了XXX修改”;binlog是逻辑日志,记录的是原始逻辑,其记录是对应的SQL语句。

  • 物理日志: 记录的是每一个page页中具体存储的值是多少,在这个数据页上做了什么修改. 比如: 某个事物将系统表空间中的第100个页面中偏移量为1000处的那个字节的值1改为2.
  • 逻辑日志: 记录的是每一个page页面中具体数据是怎么变动的,它会记录一个变动的过程或SQL语句的逻辑, 比如: 把一个page页中的一个数据从1改为2,再从2改为3,逻辑日志就会记录1->2,2->3这个数据变化的过程.

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

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

相关文章

Linux:网络相关概念的认识

文章目录 基本认知数据跨网络传输初识ip地址 端口号端口号的理解进程与端口号总结 本篇是基于前面对于网络的基本框架搭建,进而进行相关概念的进一步理解,为后续准备 基本认知 那么首先总结一下一些基本的相关结论性的信息 对于任何协议来说&#xff…

156.乐理基础-和弦固定标记法(五)挂留(sus)和弦省略音(omit)和弦

如果到这五线谱还没记住还不认识的话去看102.五线谱-高音谱号与103.五线谱-低音谱号这两个里,这里面有五线谱对应的音名,对比着看 如果一章没落下,看到这里,但是看不懂什么意思,那就强行下看,看着看着指不…

热点!浅谈低代码到底是什么?

低代码平台的历史相对较短,大约始于 2000 年初,源于快速应用程序开发工具。随着低代码平台和工具的日益普及和优势,它不断发展以满足各种领域和角色的需求。 本文将研究各种低代码和无代码应用程序开发方法、业务用例、挑战和未来预测等。 …

定制红酒:品质保障,从源头做起

云仓酒庄的洒派定制红酒,以其卓着的品质和与众不同的口感,赢得了众多消费者的喜爱。而这种品质的保障,正是从源头上开始的。 在葡萄种植方面,种植者对土壤、气候等自然条件进行严格的筛选和评估,确保葡萄能够在理想的环…

递增四元组

解法: 首先都可以想到dp[i]:第i个元素结尾的递增四元组有dp[i]个 然后发现有一组数据:2,3,6,1,5,8。会出现6结尾和5结尾的递增三元组,也就是未来的决策受过去影响,专业的说就是有后效性。需要强化约束条件&#xff0…

普发Pfeiffer分子泵TMH-U1001PC-1601PC安装使用维护说明

普发Pfeiffer分子泵TMH-U1001PC-1601PC安装使用维护说明

【Linux中vim系列】如何在vim中检索字符串

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

最简明的大模型agent教程

大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径及一点个人思考大模型应用开发实用开源项目汇总大模型问答项目…

关闭Elasticsearch built-in security features are not enabled

禁用Kibana安全提示(Elasticsearch built-in security features are not enabled) Kibana提示#! Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.e…

基于SSM+Jsp+Mysql的KTV点歌系统

基于SSMJspMysql的KTV点歌系统 基于SSMJspMysql的KTV点歌系统的设计与实现 开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工…

Redisson分布式锁(WatchDog分析,浅浅看下源码)

带大家简单了解下Redisson的看门狗机制,这个面试中也比较常见。 目录 WatchDog(看门狗)机制开启WatchDog(看门狗)浅看下源码 WatchDog(看门狗)机制 Redisson看门狗机制是用于解决在业务运行时间…

弱网测试利器 - Charles工具实战分享!

一:弱网测试要点 二:利用抓包工具charles进行弱网设置,适用PC端和移动端(IOS/Android) 1、以charles 4.5.6版本为例,打开Proxy->Throttle Settings 2、打开Throttle Settings,界面…

蓝桥杯练习06给网页化个妆

给页面化个妆 介绍 各个网站都拥有登录页面,设计一个界面美观的登录页面,会给用户带来视觉上的享受。本题中我们要完成一个登录页面的布局。 准备 开始答题前,需要先打开本题的项目代码文件夹,目录结构如下: 其中&…

A7680C 4G模块连接MQTT服务器

AT\r\n检查模块正常工作 返回 OK ATCPIN?\r\n检查SIM是否正常 返回: [20:01:31.561]接收←ATCPIN? CPIN: READY OK ATCGREG? //检查网络注册注册状态 返回 [20:02:21.042]接收←ATCGREG?…

28 OpenCV 轮廓周围绘制图形

文章目录 approxPolyDP 轮廓周围绘制矩形boundingRectminAreaRect绘制圆和椭圆示例 approxPolyDP 轮廓周围绘制矩形 approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)curve:输入点集,二维点向量的集合appro…

干货!Python正则表达式之匹配分组和其他功能函数

1.匹配分组 ():表示一个整体,表示分组,然后捕获 2.匹配分组实例 # 导入re模块 import re ​ tel "0755-98776754" ​ # 定义正则表达式 pattern "(\\d{4})-(\\d{8})" result re.search(pattern, tel) print(result…

offer选择:创业公司 VS 大厂外包

面试拿到两个offer,一个是规模只有几十人的初创小公司,另一个是大厂外包岗位。都是功能测试,两者薪水待遇也差不多,该如何选择?更有利于之后的职业发展...... 这是一个比较典型的问题,对于要转行的同学或者是刚入行没…

Leetcode 200. 岛屿数量

心路历程: 在没有看图论这一章之前看这道题没什么直接的思路,在看完图论之后,学着使用DFS和BFS去套用解决。第一次自己做的时候还是遇到了很多小问题。整体思路很流畅,但是需要处理的细节第一次没怎么处理好,花了很多…

VC++ error C1001: 内部编译器错误 c\error.h”,第 1291 行) 原因和解决

原因是使用模板时实现方法没写分号 #include <iostream>template <class T> class A { public:A() {};~A() {};void GetName() {return}; };int main(int argc, char* argv[]) {return 0; }

Linux:执行命令的命令eval与Bash解析命令的方式

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 eval命令用于接收参数&#xff0c;并将这些参数作为一行命令执行&#xff0c;这也许会使人困惑&#xff0c;为什么我不能直接执行命令而需要使用eval命令间接执行呢&…