MySQL 学习(七)undo log、redo log、bin log 的作用以及持久化机制

news2025/7/15 18:47:09

目录

    • 一、前言
    • 二、三大日志的概念、作用、存储位置
      • 2.1 bin log 二进制执行日志
      • 2.2 undo log 事务回滚日志
      • 2.3 redo log 快速恢复日志
    • 三、补充说明
      • 3.1 补充:为什么使用 buffer pool 而不直接修改磁盘中的数据?
      • 3.2 补充:同为操作数据变更的日志,有了 bin log 为什么还要 redo log?
      • 3.3 补充:redo log 一定能保证事务的持久性吗?
    • 四、redo log 与 undo log 的持久化机制
      • 3.1 redo log 持久化
      • 3.2 undo log 持久化

一、前言

你有没有想过,MySQL是怎么保证数据安全的?比如突然断电时,为什么你的订单数据不会丢失?其实这全靠三个"小帮手":undo logredo logbin log

  • undo log 就像游戏的"存档点",让你能 回滚 错误操作;
  • redo log 是应急的"记事本",断电时能 快速恢复 数据;
  • bin log 则是完整的"操作日记",用于 数据备份同步

这篇文章我们就来聊聊这三个日志的工作原理,看看它们是如何默契配合,守护你的数据安全的。


二、三大日志的概念、作用、存储位置

2.1 bin log 二进制执行日志

bin log 的基本概念:

binlog 是一个二进制格式的文件,记录了对 MySQL 数据库执行更改的所有 写操作,例如更改数据库表和更改内容的 SQL 语句都会记录到 binlog 里,但是不会记录 SELECTSHOW 这类操作。

  • binlog 在 MySQL 的 Server 层实现(引擎共用)
  • binlog 为逻辑日志,记录的是一条 SQL 语句的原始逻辑。
    • binlog 不限制大小,追加写入,不会覆盖以前的日志。
    • 默认情况下,binlog 日志是二进制的,不能使用查看文本工具的命令(比如:cat、vi 等)查看,而是用 mysqlbinlog 解析查看。

bin log 的作用:

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

bin log 文件存储位置:

首先,需要确保binlog开启:

SHOW VARIABLES LIKE 'log_bin';
  • MySQL 5.7需手动开启binlog;
  • MySQL 8.0默认已开启binlog,只需确认配置。

binlog文件默认在 datadir 目录下:

-- 查看数据目录位置
show variables like 'datadir';

在这里插入图片描述

如果手动指定了位置,则需要到 my.cnf 或 my.ini 中进行查看:

# 指定了目录和前缀
log_bin = D:/java/mysql-5.7.33-winx64/binlog/mysql-bin

在这里插入图片描述

undo log 文件存储位置

2.2 undo log 事务回滚日志

undo log 基本概念:

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

undo log 的产生和销毁:

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

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

undo log 的作用:

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

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

  2. 提供多版本控制(MVCC)【undo log 实现多版本并发控制(MVCC)】

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

undo log 的存储位置:

可以使用如下命令查看存储位置:

SHOW VARIABLES LIKE 'innodb_undo%';

从下面执行结果可以看到,这里的相对位置是以数据存储位置 datadir 为准。

在这里插入图片描述

我们执行如下命令查看 datadir 数据位置:

-- 查看数据目录位置
show variables like 'datadir';

在这里插入图片描述

undo log 的日志文件如下:

(补充:ib是InnoDB的简写)

在这里插入图片描述


2.3 redo log 快速恢复日志

redo log 基本概念:

redo log 被称作重做日志,包括两部分:

  • 一个是内存中的日志缓存 redo log buffer
  • 另一个是磁盘上的日志文件 redo log file

补充: 在内存层面的日志缓存会按照固定大小进行存储,默认 16M,通过 innodb_log_buffer_size 参数可以修改。

MySQL 每执行一条 DML 语句,先将记录写入 redo log buffer,后续某个时间点再一次性将多个操作记录写到 redo file log。

MySQL 中 InnoDB 修改数据的操作流程:

在这里插入图片描述

  1. 先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝,产生脏数据
  2. 生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
  3. 默认在事务提交后将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式
  4. 定期将内存中修改的数据刷新到磁盘中(这里说的是那些还没及时被后台线程刷盘的脏数据)

通常所说的 Write Ahead Log(预写式技术)指的是 在持久化一个数据页之前,先将内存中相应的日志页持久化。这种技术可以大大减少 IO 操作的频率,提升数据刷新的效率。

redo log 的作用:

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

redo log 的存储位置:

redo log 默认存储在 datadir 数据目录下的 ib_logfile0ib_logfile1 文件中,如下所示:

(补充:ib是InnoDB的简写)

在这里插入图片描述


三、补充说明

相信大家看了上面的概念一定云里雾里,脑袋里有很多疑问,下面就为大家答疑一下。

3.1 补充:为什么使用 buffer pool 而不直接修改磁盘中的数据?

因为直接修改磁盘数据的话,它是 随机IO,修改的数据分布在磁盘中的不同位置,需要来回的查找,所以命中率低,消耗打,而一个小小的修改就不得不将整个页刷新到磁盘,利用率低。

与之相对的是 顺序IO,磁盘的数据分布在磁盘的一块,所以省去了查找的过程,节省在磁盘上的寻道事件。

使用后台线程以一定的频率去刷新磁盘可以降低随机IO的频率,增加吞吐量,这是使用 buffer pool 的根本原因。

3.2 补充:同为操作数据变更的日志,有了 bin log 为什么还要 redo log?

最核心的一点就是 两者记录的数据变更粒度是不一样 的。

以修改数据为例:

  • binlog 是以 为记录主体,在 ROW 模式下,binlog 保存的表中每行的变更记录。
  • 由于 MySQL 是以页为单位进行刷盘的,每一页的数据单位为 16K,所以在刷盘的过程中需要把数据刷新到磁盘的多个扇区中去。而把 16K 数据刷到磁盘的每个扇区里这个过程是 无法保证原子性的,如果数据库宕机,那么就可能会造成一部分数据成功过,而一部分数据失败的情况。而通过 binlog 这种级别的日志是无法恢复的,因为一个 update 可能更改了多个磁盘区域的数据,所以这个时候得需要通过 redo log 这种 记录到磁盘数据级别 的日志进行数据恢复。

redo log 和 binlog 的具体区别如下:

redo logbinlog
文件大小redo log 的大小是固定的。binlog 可通过配置参数 max_binlog_size 设置每个 binlog 文件的大小。
实现方式redo logInnoDB 引擎实现的,并不是所有引擎都有。binlogServer 层实现的,所有引擎都可以使用 binlog 日志。
记录方式redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。binlog 通过朱家的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上。
使用场合redo log 用于崩溃恢复(crash-safe)。binlog 用于主从复制中数据恢复、时间点恢复。

由以上两者的对比可知:binlog 日志只用于归档,只依靠 binlog 是没有 crash-safe 能力的。

同样只有 redo log 也不行,因为 redo log 是 InnoDB 特有的,且日志上的记录落盘后会被覆盖掉。因此需要 binlog 和 redo log 二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。(redo log 自动恢复,binlog 手动触发)

3.3 补充:redo log 一定能保证事务的持久性吗?

不一定,这样根据 redo log 的刷盘策略决定,因为 redo log buffer 同样是在内存中,如果提交事务之后,redo log buffer 还没来得及将数据刷新到 redo log file 中进行持久化,此时发生宕机照样会丢失数据。

那该如何解决呢?可以配置写入策略为实时写、实时刷。

-- 确保每次事务提交都刷盘 (默认值)
SET GLOBAL innodb_flush_log_at_trx_commit = 1;

-- 使用 O_DIRECT 方式绕过OS缓存 (Linux)
SET GLOBAL innodb_flush_method = O_DIRECT;

四、redo log 与 undo log 的持久化机制

3.1 redo log 持久化

在计算机操作系统中,用户空间(user space) 下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统的 **内核控件(kernel space) ** 中的 缓冲区(OS Buffer)

因此,redo log buffer 写入 redo log file 实际上是先写入 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 秒的事务提交数据。

3.2 undo log 持久化

MySQL 中的 Undo Log 严格的讲不是Log,而是数据,因此它的管理和罗盘跟数据是一样的。

  • Undo 的磁盘结构并不是顺序的,而是像数据一样按 Page 管理。
  • Undo 写入时,也想数据一样产生对应的 Redo Log(因为 undo 也是对页面的修改,记录 undo 这个操作本身也会有对应的 redo)。
  • Undo 的 Page 也像数据一样缓存在 Buffer Pool 中,跟数据 Page 一起做 LRU 换入换出,以及刷脏。Undo Page 的刷脏也像数据一样要等到对应的 Redo Log 落盘之后。

当事务提交的时候,innodb 不会立即删除 undo log,因为后续还可能会用到 undo log,如隔离级别为 repeatable read 时,事务读取的都是开启时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即 undo log 不能删除。

但是在事务提交的时候,会将该事务对应的 undo log 放入到删除列表中,未来通过 purge 来删除。并且提交事务时,还会判断 undo log 分配的页是否可以宠用,如果可以重用,则会分配给后面来的事务,避免为每个独立的事务分配独立的 undo log 页而浪费存储空间和性能。

整理完毕,完结撒花~🌻





参考地址:

1.MySQL面试 | undo log、redo log、 bin log的作用是什么?https://www.bilibili.com/video/BV1Q4AkeKEai

2.硬核干货!一文掌握MySQL核心日志:binlog、redo log、undo log,https://baijiahao.baidu.com/s?id=1821334254098820619&wfr=spider&for=pc

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

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

相关文章

时间序列预测建模的完整流程以及数据分析【学习记录】

文章目录 1.时间序列建模的完整流程2. 模型选取的和数据集2.1.ARIMA模型2.2.数据集介绍 3.时间序列建模3.1.数据获取3.2.处理数据中的异常值3.2.1.Nan值3.2.2.异常值的检测和处理(Z-Score方法) 3.3.离散度3.4.Z-Score3.4.1.概述3.4.2.公式3.4.3.Z-Score与…

FFmpeg3.4 libavcodec协议框架增加新的decode协议

查看ffmepg下面的configure文件发现,config.h文件;解码协议的配置是通过libavcodec/allcodecs.c文件,通过查找DEC关键字生成的。 1、在libavcodec/allcodecs.c 新增REGISTER_ENCODER(MYCODE, mycode); REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); …

无人机数据处理与特征提取技术分析!

一、运行逻辑 1. 数据采集与预处理 多传感器融合:集成摄像头、LiDAR、IMU、GPS等传感器,通过硬件时间戳或PPS信号实现数据同步,确保时空一致性。 边缘预处理:在无人机端进行数据压缩(如JPEG、H.265)…

前端面试宝典---js垃圾回收机制

什么是垃圾回收 垃圾回收是指一种自动内存管理机制,当声明一个变量时,会在内存中开辟一块内存空间用于存放这个变量。当这个变量被使用过后,可能再也不需要它了,此时垃圾回收器会自动检测并回收这些不再使用的内存空间。垃圾回收…

IDEA 新建 SpringBoot 项目时,没有高版本 SpringBoot 可选

环境描述 IDEA 2025.1.1JDK17Maven 3.9.9 问题描述 IDEA 新建 SpringBoot 项目时,没有高版本 SpringBoot 可选,可以看到此时的最高版本为 3.0.2: 问题分析 返回上一步,可以发现 Spring Initializr 的服务地址为阿里云&#…

2025年PMP 学习十三 第9章 项目资源管理(9.1,9.2)

2025年PMP 学习十三 第9章 项目资源管理(9.1,9.2) 序号过程过程组9.1规划资源管理规划9.2估算活动资源规划9.3获取资源执行9.4建设团队执行9.5管理团队执行9.6控制资源监控 文章目录 2025年PMP 学习十三 第9章 项目资源管理(9.1,9.2&#xf…

动态规划问题 -- 多状态模型(删除并获得点数)

目录 动态规划分析问题五步曲题目概述预处理阶段 代码编写 动态规划分析问题五步曲 不清楚动态规划分析问题是哪关键的五步的少年们可以移步到 链接: 动态规划算法基础 这篇文章非常详细的介绍了动态规划算法是如何分析和解决问题的 题目概述 链接: 删除并获得点数 预处理阶段…

Jenkins里构建一个简单流水线

前情提要:传送门,我在虚拟机里装了一个Ubuntu,然后在docker里装了一个Jenkins及GitLab! 点击这里下载或fork一个简单的Java项目用于学习Jenkins! 目标:修改代码后,上传到git,在在Jenkins流水线里…

Java Queue 接口实现

Date: 2025.05.14 20:46:38 author: lijianzhan Java中的Queue接口是位于java.util包中,它是一个用于表示队列的接口。队列是一种先进先出(First-In-First-Out, 简称为FIFO)的数据结构,其中元素被添加到队列的尾部,并从…

OpenEvidence AI临床决策支持工具平台研究报告

平台概述 OpenEvidence是一个专为医疗专业人士设计的临床决策支持工具,旨在通过整合各类临床计算器和先进的人工智能技术,提高医生的诊疗决策效率和准确性。作为一款综合性医疗平台,OpenEvidence将复杂的医学计算流程简化,同时提供个性化的临床建议,使医生能够更快、更准…

如何远程执行脚本不留痕迹

通常我们在做远程维护的时候,会有这么一个需求,就是我想在远程主机执行一个脚本,但是这个脚本我又不想保留在远程主机上,那么有人就说了,那就复制过去再登录远程执行不就行了吗?嗯嗯,但是这还不…

Ota++框架学习

一:框架结构 这是一幅展现 Web 应用程序架构的示意图,以下是对图中各部分的详细解释: 外部交互部分 Request(请求):位于架构图的左上角,用黄色虚线框表示 。代表来自客户端(如浏览器…

Chrome安装最新vue-devtool插件

本vue-devtool版本是官方的 v7.6.8版本,兼容性好、功能齐全且稳定。 操作步骤: 方法一: 打开谷歌浏览器 --> 右上角三个点 --> 扩展程序 --> 管理扩展程序 --> 加载已解压的扩展程序, 然后选择解压后的文件夹即可。…

bfs-最小步数问题

最小步长模型 特征: 主要是解决权值为1且状态为字符串类型的最短路问题,实质上是有向图的最短路问题,可以简化为bfs求最短路问题。 代表题目: acwing 845 八数码问题: 八数码题中由于每次交换的状态是由x进行上下左右…

java----------->代理模式

目录 什么是代理模式? 为什么会有代理模式? 怎么写代理模式? 实现代理模式总共需要三步: 什么是代理模式? 代理模式:给目标对象提供一个代理对象,并且由代理对象控制目标对象的引用 代理就是…

Untiy基础学习(十四)核心系统—物理系统之碰撞检测代码篇 刚体,碰撞体,材质

目录 一、碰撞器(Collider)与触发器(Trigger) 二、碰撞检测条件 三、碰撞事件与触发器事件,可以理解为特殊的生命周期函数。 四、讲讲如何选择 ​编辑 五、总结 一、碰撞/触发事件函数对照表 二、Collider 与 …

SAP学习笔记 - 开发08 - Eclipse连接到 BTP Cockpit实例

有关BTP,之前学了一点儿,今天继续学习。 SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)_sap btp开发-CSDN博客 如何在Eclipse中连接BTP Cockpit开发环境实例。 1&#xf…

Git的安装和配置(idea中配置Git)

一、Git的下载和安装 前提条件:IntelliJ IDEA 版本是2023.3 ,那么配置 Git 时推荐使用 Git 2.40.x 或更高版本 下载地址:CNPM Binaries Mirror 操作:打开链接 → 滚动到页面底部 → 选择2.40.x或更高版本的 .exe 文件&#xf…

【2025版】Spring Boot面试题

文章目录 1. Spring, Spring MVC, SpringBoot是什么关系?2. 谈一谈对Spring IoC的理解3. Component 和 Bean 的区别?4. Autowired 和 Resource 的区别?5. 注入Bean的方法有哪些?6. 为什么Spring 官方推荐构造函数注入?…

火山引擎实时音视频 高代码跑通日志

实时音视频 SDK 概览--实时音视频-火山引擎 什么是实时音视频 火山引擎实时音视频(Volcengine Real Time Communication,veRTC)提供全球范围内高可靠、高并发、低延时的实时音视频通信能力,实现多种类型的实时交流和互动。 通…