mysql的 undo log、redo log、bin log、buffer pool

文章目录

  • Buffer Pool
    • 为什么需要Buffer Pool
    • Buffer Pool 缓存了什么
  • Redo log
    • 为什么需要 redo log?
    • redo log 什么时候刷盘?
    • redo log 文件写满了怎么办?
  • undo log

本文章内容都来自小林coding博主,基于他的文章内容,加一些自己的理解

Buffer Pool

为什么需要Buffer Pool

MySQL 的数据都是存在磁盘中的,那么我们要更新一条记录的时候,得先要从磁盘读取该记录,然后在内存中修改这条记录。那修改完这条记录是选择直接写回到磁盘,还是选择缓存起来呢?

当然是缓存起来好,这样下次有查询语句命中了这条记录,直接读取缓存中的记录,就不需要从磁盘获取数据了。

为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。

Buffer Pool 缓存了什么

在 MySQL 启动的时候,InnoDB 会为 Buffer Pool 申请一片连续的内存空间,然后按照默认的16KB的大小划分出一个个的页, Buffer Pool 中的页就叫做缓存页。此时这些缓存页都是空闲的,之后随着程序的运行,才会有磁盘上的页被缓存到 Buffer Pool 中。

Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 Undo 页,插入缓存、自适应哈希索引、锁信息等等。

Undo页记录了什么?

开启事务后,InnoDB 层更新记录前,首先要记录相应的 undo log,如果是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面。

Redo log

为什么需要 redo log?

Buffer Pool 是提高了读写效率没错,但是问题来了,Buffer Pool 是基于内存的,而内存总是不可靠,万一断电重启,还没来得及落盘的脏页数据就会丢失。

为了防止断电导致数据丢失的问题,当有一条记录需要更新的时候,InnoDB 引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以 redo log 的形式记录下来,这个时候更新就算完成了加粗样式

后续,InnoDB 引擎会在适当的时候,由后台线程将缓存在 Buffer Pool 的脏页刷新到磁盘里,这就是 WAL (Write-Ahead Logging)技术。

WAL 技术指的是, MySQL 的写操作并不是立刻写到磁盘上,而是先写日志,然后在合适的时间再写到磁盘上。

过程如下图:
在这里插入图片描述

什么是 redo log?

redo log 是物理日志,记录了某个数据页做了什么修改,比如对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新,每当执行一个事务就会产生这样的一条或者多条物理日志。

在事务提交时,只要先将 redo log 持久化到磁盘即可(redo log 有三种持久化到磁盘的策略),可以不需要等到将缓存在 Buffer Pool 里的脏页数据持久化到磁盘。

当系统崩溃时,虽然脏页数据没有持久化,但是 redo log 已经持久化,接着 MySQL 重启后,可以根据 redo log 的内容,将所有数据恢复到最新的状态。

被修改 Undo 页面,需要记录对应 redo log 吗?

需要的。

开启事务后,InnoDB 层更新记录前,首先要记录相应的 undo log,如果是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面。

不过,在内存修改该 Undo 页面后,需要记录对应的 redo log。(这里记录对应的redo log,不是说记录更新后的数据,而是记录undo页面修改后的内容,即记录了undo log的数据

redo log 和 undo log 区别在哪?

这两种日志是属于 InnoDB 存储引擎的日志,它们的区别在于:

  • redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
  • undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值;

事务提交之前发生了崩溃,重启后会通过 undo log 回滚事务,事务提交之后发生了崩溃,重启后会通过 redo log 恢复事务,如下图:
在这里插入图片描述
所以有了 redo log,再通过 WAL 技术,InnoDB 就可以保证即使数据库发生异常重启,之前已提交的记录都不会丢失,这个能力称为 crash-safe(崩溃恢复)。可以看出来, redo log 保证了事务四大特性中的持久性。

redo log 要写到磁盘,数据也要写磁盘,为什么要多此一举?

除了需要保证事务的持久性,让mysql有crash-safe的能力,此外还将写的操作从【随机写】变成了【顺序写】,提升了MYSQL写入磁盘的性能

产生的 redo log 是直接写入磁盘的吗?

不是的,执行一个事务产生的redo log是先放入到 redo log buffer里面

redo log buffer 默认大小 16 MB,可以通过 innodb_log_Buffer_size 参数动态的调整大小,增大它的大小可以让 MySQL 处理「大事务」是不必写入磁盘,进而提升写 IO 性能。

redo log 什么时候刷盘?

缓存在 redo log buffer 里的 redo log 还是在内存中,它什么时候刷新到磁盘?

主要有下面几个时机:

  • MySQL 正常关闭时;
  • 当 redo log buffer 中记录的写入量大于 redo log buffer 内存空间的一半时,会触发落盘;
  • InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘。
    每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘(这个策略可由 innodb_flush_log_at_trx_commit 参数控制,有三种策略,)。

由参数 innodb_flush_log_at_trx_commit 参数控制,可取的值有:0、1、2,默认值为 1,这三个值分别代表的策略如下:

  • 当设置该参数为 0 时,表示每次事务提交时 ,还是将 redo log 留在 redo log buffer 中 ,该模式下在事务提交时不会主动触发写入磁盘的操作。
  • 当设置该参数为 1 时,表示每次事务提交时,都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘,这样可以保证 MySQL 异常重启之后数据不会丢失。
  • 当设置该参数为 2 时,表示每次事务提交时,都只是缓存在 redo log buffer 里的 redo log 写到 redo log 文件,注意写入到「 redo log 文件」并不意味着写入到了磁盘,因为操作系统的文件系统中有个 Page Cache(如果你想了解 Page Cache,可以看这篇 (opens new window)),Page Cache 是专门用来缓存文件数据的,所以写入「 redo log文件」意味着写入到了操作系统的文件缓存。

innodb_flush_log_at_trx_commit 为 0 和 2 的时候,什么时候才将 redo log 写入磁盘?

InnoDB 的后台线程每隔 1 秒:

  • 针对参数 0 :会把缓存在 redo log buffer 中的 redo log ,通过调用 write() 写到操作系统的 Page Cache,然后调用 fsync() 持久化到磁盘。所以参数为 0 的策略,MySQL 进程的崩溃会导致上一秒钟所有事务数据的丢失;
  • 针对参数 2 :调用 fsync,将缓存在操作系统中 Page Cache 里的 redo log 持久化到磁盘。所以参数为 2 的策略,较取值为 0 情况下更安全,因为 MySQL 进程的崩溃并不会丢失数据,只有在操作系统崩溃或者系统断电的情况下,上一秒钟所有事务数据才可能丢失

加入了后台现线程后,innodb_flush_log_at_trx_commit 的刷盘时机如下图:
在这里插入图片描述

redo log 文件写满了怎么办?

两个文件循环写
redo log 是循环写的方式,相当于一个环形,InnoDB 用 write pos 表示 redo log 当前记录写到的位置,用 checkpoint 表示当前要擦除的位置

undo log

  • 实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执 行了 ROLLBACK 语句,MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态。
  • 实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过 ReadView + undo log 实现的。undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的记录。

TIP
很多人疑问 undo log 是如何刷盘(持久化到磁盘)的?
undo log 和数据页的刷盘策略是一样的,都需要通过 redo log 保证持久化。
buffer pool 中有 undo 页,对 undo 页的修改也都会记录到 redo log。redo log 会每秒刷盘,提交事务时也会刷盘,数据页和 undo 页都是靠这个机制保证持久化的。

undo log 是一种用于撤销回退的日志。在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。如下图:

在这里插入图片描述

思考: 在上图中undo log日志用于事务需要回滚,恢复原先数据,但是undo log日志也是缓存在Buffer Pool中的Undo页中,并且刷盘逻辑跟《数据页》一样的。那么在事务提交前,undo log是否已经刷盘,如果在内存中,这时断电了,undo log存在内存中,数据丢失,如何回滚,为什么能说undo log是保证了事务的原子性?

  • 第一种情况,在一条update语句中(事务时间极短),默认开启隐式事务,在事务提交前,发生断电,Buffer Pool中的undo页和数据页,以及redo log都未来得及刷盘,但是update修改的数据也未持久化。因此,数据的一致性得以保证,但事务的原子性在这种极端情况下未能通过 Undo Log 来维护,因为这些日志未被持久化。
  • 第二种情况,在一个显式事务中(事务整体时间长),一开始就执行了update的操作,后续执行业务代码,那么修改后的值(数据页,undo页)可能被 后台线程通过 每秒刷盘的策略从 Buffer Pool中或redo log中刷进了磁盘,那么修改后的数据进入了磁盘(undo log也进入了磁盘),那么这时即使mysql崩溃或者事务需要回滚,都可以通过加载undo log 和redo log进行比对然后回滚

所以在上述的第二种情况下,undo log是对事务的acid的原子性进行了保证,但不是绝对的

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

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

相关文章

PXE的使用

配置前提 1、挂载镜像源,可正常下载软件 [rootredhat-7 ~]# mkdir -p /rhel7 ----创建挂载点目录 [rootredhat-7 ~]# mount /dev/sr0 /rhel7/ ----挂载镜像源至挂载点(临时挂载,重启失效)[rootredhat-7 ~]# vim /etc/yum.repos.…

C++ | Leetcode C++题解之第319题灯泡开关

题目: 题解: class Solution { public:int bulbSwitch(int n) {return sqrt(n 0.5);} };

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-02 MAC层程序设计

软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台:https://milianke.tmall.com/ 登录“米联客”FPGA社区 ht…

用Python实现炫酷的代码雨效果(完整代码)

导语 在这个数字时代,编程不仅是一项技能,更是一种艺术。想象一下,在你的屏幕上,一行行代码如同雨滴般落下,闪烁着技术的光芒,是不是既酷炫又充满科技感?今天,我们就将使用 Python …

哪个品牌的超声波清洗机最好?好用的超声波清洗机排名

随着人们对生活质量的提升,对健康也是越来越关注了,很多眼镜佩戴者也逐渐对眼部健康逐渐重视起来了,因为眼镜镜片的缝隙很容易有大量的灰尘和细菌,而超声波清洗机的出现,恰恰是可以针对于这些缝隙污垢清洁的&#xff0…

Android:Uniapp平台中接入即构RTC+相芯美颜

0 前言 前阵子使用Uniapp平台开发了一个跨平台app,并且接入了即构RTC后,今天想进一步丰富app的直播功能。之前有相芯美颜的开发经验,打算将相芯美颜接入即构RTC. **在DCloud插件市场找到了在即构RTC接入相芯美颜插件,https://ex…

CasaOS系统小主机Docker部署memos结合内网穿透打造私有云笔记

文章目录 前言1. 使用Docker部署memos2. 注册账号与简单操作演示3. 安装cpolar内网穿透4. 创建公网地址5. 创建固定公网地址 前言 本文主要介绍如何在CasaOS轻NAS系统设备中使用Docker本地部署开源云笔记服务memos,并结合cpolar内网穿透工具配置公网地址&#xff0…

50etf期权怎么可以买跌做空吗?

50ETF期权可以做买方也可以做卖方,并且50ETF期权还能够买涨买跌双向交易,50ETF期权可以看涨期权和看跌期权,所以50ETF期权是可以买跌做空的,并且50ETF期权是很适合进行做空操作的,下文为大家介绍50etf期权怎么可以买跌…

SQL进阶技巧:Hive如何巧解和差计算的递归问题?【应用案例2】

目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 累计值分析模型是一种用于分析和预测累计值数据的统计模型。它主要用于处理随时间积累的数据,例如销售额、用户数量、网站访问量等。累计值分析模型的目的是通过对历史数据的分析,揭示数据的趋势和模式,以便进…

日撸Java三百行(day13:链表)

目录 一、链表的基础知识 二、链表的代码实现 1.链表创建 2.链表遍历 3.链表定位查找 4.链表插入 5.链表删除 6.数据测试 7.完整的程序代码 总结 一、链表的基础知识 在之前顺序表的学习中,我们其实提到过链表。链表它是线性表在不同的物理存储方式下派生…

谷歌账号被停用后,申诉没有反馈或者被拒绝后怎么办?附:谷歌账号申诉信要点和模板

有一些朋友在登录谷歌账号的时候,或者在是用谷歌账号的过程中突然被强制退出来,然后再次登录的时候就遇到了下面的提醒:您的账号已停用,而且原因通常是两大类:1)谷歌账号与其他多个账号一起创建或使用的&am…

将网络变压器(Ethernet Transformer)从千兆单口设计改为百兆双口设计涉及几个关键步骤和注意事项

变压器选型: 确保选用的变压器支持1000BASE-T到100BASE-TX的转换。通常,这种变压器会有额外的电气特性,如抑制和隔离等,以确保数据传输的可靠性和稳定性。 端口连接: 对于千兆单口设计,通常会有一对输入和输…

【python报错已解决】`AttributeError: ‘DataFrame‘ object has no attribute ‘ix‘`

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引言: 在使用Pandas库进行数据分析时,你是否遇到过AttributeError: DataFrame object has no attribut…

本地安装Llama3.1与LobeChat可视化UI界面并实现远程访问大模型实战

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

企业定制AI智能名片微信小程序在私域流量运营中的应用与策略

摘要:随着2022年私域运营市场步入冷静期,企业逐渐从盲目模仿向精准化、个性化的运营模式转变。在这一背景下,企业定制AI智能名片微信小程序凭借其独特的智能化、便捷化特性,成为企业构建私域流量池、深化用户关系、实现高效转化的…

【完美解决】正点原子Linux开发板无法联网ping通百度但可以ping通主机和虚拟机,联通了局域网但无法联通互联网,DNS配置问题

问题记录 主机通过共享网络给以太网口想让正点原子的阿尔法Linux开发板连上网,网络配置过程如下: 开发板连接的是eth1口,通过在终端输入以下命令进入网络配置文件。 vi /etc/network/interfaces 将其配置为了以下地址 但是出现了一些问题&…

RAG 入门指南:从零开始构建一个 RAG 系统

本文正文字数约 3300 字,阅读时间 10 分钟。 从零开始构建一个应用可以让我们快速理解应用的各个部分。 这个方法其实非常适用于 RAG。 我在以前的文章中有介绍过 RAG 的概念、原理以及应用等,但其实,亲自动手来构建一个 RAG 系统或许能够…

C语言指针详解(三)目录版

C语言指针详解(三)目录版 1、字符指针变量1.1、字符指针变量的一般应用1.2、常量字符串1.3、常量字符串与普通字符串的区别1.3.1 常量字符串的不可修改性1.3.2 常量字符串的存储 2、数组指针变量2.1、数组指针变量定义2.2、数组指针变量的初始化 3、二维…

图的DFS

LeetCode2368 受限条件下可到达节点的数目 class Solution { public:int dfs(vector<vector<int>>& g,int x,int fa){int sum1;for(int y:g[x]){if(y!fa) sumdfs(g,y,x);}return sum;}int reachableNodes(int n, vector<vector<int>>& edges, …

C语言指针(3)

目录 一、字符指针变量 二、数组指针变量 三、⼆维数组传参的本质 四、函数指针变量 五、typedef 关键字 六、函数指针数组 一、字符指针变量 字符指针char* &符号名 符号名&#xff0c;这都是获取的是首元素地址。 int main() {char a[] "abcdef";cha…