MySQL 学习(七)undo log、redo log、bin log 的作用以及持久化机制
目录
- 一、前言
- 二、三大日志的概念、作用、存储位置
- 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 log
、redo log
和 bin log
。
undo log
就像游戏的"存档点",让你能 回滚 错误操作;redo log
是应急的"记事本",断电时能 快速恢复 数据;bin log
则是完整的"操作日记",用于 数据备份 和 同步。
这篇文章我们就来聊聊这三个日志的工作原理,看看它们是如何默契配合,守护你的数据安全的。
二、三大日志的概念、作用、存储位置
2.1 bin log 二进制执行日志
bin log 的基本概念:
binlog
是一个二进制格式的文件,记录了对 MySQL 数据库执行更改的所有 写操作,例如更改数据库表和更改内容的 SQL 语句都会记录到 binlog 里,但是不会记录 SELECT
和 SHOW
这类操作。
- binlog 在 MySQL 的 Server 层实现(引擎共用)
- binlog 为逻辑日志,记录的是一条 SQL 语句的原始逻辑。
- binlog 不限制大小,追加写入,不会覆盖以前的日志。
- 默认情况下,binlog 日志是二进制的,不能使用查看文本工具的命令(比如:cat、vi 等)查看,而是用
mysqlbinlog
解析查看。
bin log 的作用:
- 主从复制: 从主库开启 Binlog 功能,这样主库就可以把 Binlog 传递给从库,从库拿到 Binlog 后实现数据恢复达到主从数据一致性。
- 数据恢复: 通过 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 的作用:
-
提供回滚操作【undo log 实现事务的原子性】
在数据修改的时候,不仅记录了 redo log,还记录相对应的 undo log,如果因为某些原因导致事务执行失败了,可以借助 undo log 进行回滚。
-
提供多版本控制(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 修改数据的操作流程:
- 先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝,产生脏数据
- 生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
- 默认在事务提交后将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式
- 定期将内存中修改的数据刷新到磁盘中(这里说的是那些还没及时被后台线程刷盘的脏数据)
通常所说的 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_logfile0
和 ib_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 log | binlog | |
---|---|---|
文件大小 | redo log 的大小是固定的。 | binlog 可通过配置参数 max_binlog_size 设置每个 binlog 文件的大小。 |
实现方式 | redo log 是 InnoDB 引擎实现的,并不是所有引擎都有。 | binlog 是 Server 层实现的,所有引擎都可以使用 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
相关文章:

MySQL 学习(七)undo log、redo log、bin log 的作用以及持久化机制
目录 一、前言二、三大日志的概念、作用、存储位置2.1 bin log 二进制执行日志2.2 undo log 事务回滚日志2.3 redo log 快速恢复日志 三、补充说明3.1 补充:为什么使用 buffer pool 而不直接修改磁盘中的数据?3.2 补充:同为操作数据变更的日志…...
vue中,created和mounted两个钩子之间调用时差值受什么影响
在 Vue 中,created 和 mounted 是两个生命周期钩子,它们之间的调用时差主要受以下几个因素影响: 🟢 1. 模板复杂度与渲染耗时(最主要因素) mounted 的触发时间是在组件的 DOM 被挂载之后(也就是…...
16S18S_OTU分析(3)
OTU的定义 OTU:操作分类单元是在系统发生学研究或群体遗传学研究中,为了便于进行分析,人为给某一个分类单元(如品系、种、属、分组等)设置的同一标志。目的:OTU用于将相似的序列归为一类,以便于…...
电机的导程和脉冲之间的关系
文章目录 导程计算关系相互影响关系 在电机相关领域中,导程通常是针对直线电机或带有丝杠等传动机构的电机系统而言的。 导程 导程是指丝杠或类似传动部件旋转一周时,与其相连的运动部件在轴向方向上移动的距离。例如,在一个由电机驱动丝杠来…...

时间序列预测建模的完整流程以及数据分析【学习记录】
文章目录 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与…...
Flink和Spark的选型
在Flink和Spark的选型中,需要综合考虑多个技术维度和业务需求,以下是在项目中会重点评估的因素及实际案例说明: 一、核心选型因素 处理模式与延迟要求 Flink:基于事件驱动的流处理优先架构,支持毫秒级低延迟、高吞吐的…...

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…...

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

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)的数据结构,其中元素被添加到队列的尾部,并从…...
华为0507机试
题目二 建设基站 有一棵二叉树,每个节点上都住了一户居民。现在要给这棵树上的居民建设基站,每个基站只能覆盖她所在与相邻的节点,请问信号覆盖这棵树最少需要建设多少个基站 #include <bits/stdc.h> using namespace std;const int …...

OpenEvidence AI临床决策支持工具平台研究报告
平台概述 OpenEvidence是一个专为医疗专业人士设计的临床决策支持工具,旨在通过整合各类临床计算器和先进的人工智能技术,提高医生的诊疗决策效率和准确性。作为一款综合性医疗平台,OpenEvidence将复杂的医学计算流程简化,同时提供个性化的临床建议,使医生能够更快、更准…...
`RotationTransition` 是 Flutter 中的一个动画组件,用于实现旋转动画效果
RotationTransition 是 Flutter 中的一个动画组件,用于实现旋转动画效果。它允许你对子组件进行动态的旋转变换,从而实现平滑的动画效果。RotationTransition 通常与 AnimationController 和 Tween 一起使用,以控制动画的开始、结束和过渡效果…...
Android多媒体——媒体start流程分析(十三)
当多媒体的数据源准备好,并且完成调用准备结束流程后,接下来就开始是调用 start() 方法开始播放媒体了。这里我们就来分析一下媒体开始播放的整个流程。 一、媒体播放流程 对于媒体播放流程的 Java 层和 JNI 层与前面的示例基本相同,这里不再重复展示了,我们直接从 mediap…...

如何远程执行脚本不留痕迹
通常我们在做远程维护的时候,会有这么一个需求,就是我想在远程主机执行一个脚本,但是这个脚本我又不想保留在远程主机上,那么有人就说了,那就复制过去再登录远程执行不就行了吗?嗯嗯,但是这还不…...
jQuery知识框架
一、jQuery 基础 核心概念 $ 或 jQuery:全局函数,用于选择元素或创建DOM对象。 链式调用:多数方法返回jQuery对象,支持连续操作。 文档就绪事件: $(document).ready(function() { /* 代码 */ }); // 简写 $(function…...
java加强 -File
File类的对象可以代表文件/文件夹,并可以调用其提供的方法对象文件进行操作。 File对象既可以代表文件,也可以代表文件夹。 创建File对象,获取某个文件的信息 语法: File 对象名 new File("需要访问文件的绝对路径&…...
c# 倒序方法
在C#中,有几种方法可以对List进行倒序排列: 1. 使用List的Reverse()方法(原地反转) List<int> numbers new List<int> { 1, 2, 3, 4, 5 };numbers.Reverse(); // 直接修改原列表// 结果:5, 4, 3, 2, 1 …...
每日c/c++题 备战蓝桥杯(P2241 统计方形(数据加强版))
洛谷P2241 统计方形(数据加强版)题解 题目描述 给定一个 n m n \times m nm 的方格棋盘,要求统计其中包含的正方形数量和长方形数量(不包含正方形)。输入为两个正整数 n n n 和 m m m,输出两个整数分…...

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

Chrome安装最新vue-devtool插件
本vue-devtool版本是官方的 v7.6.8版本,兼容性好、功能齐全且稳定。 操作步骤: 方法一: 打开谷歌浏览器 --> 右上角三个点 --> 扩展程序 --> 管理扩展程序 --> 加载已解压的扩展程序, 然后选择解压后的文件夹即可。…...
Android锁
引言 🔒 在 Android 应用的开发过程中,随着业务需求的复杂度不断提升,多线程并发场景层出不穷。为了保证数据一致性与线程安全,锁(Lock)成为了不可或缺的工具。本篇博客将深入剖析 Android 中常用的锁机制…...

bfs-最小步数问题
最小步长模型 特征: 主要是解决权值为1且状态为字符串类型的最短路问题,实质上是有向图的最短路问题,可以简化为bfs求最短路问题。 代表题目: acwing 845 八数码问题: 八数码题中由于每次交换的状态是由x进行上下左右…...
sqlalchemy库详细使用
SQLAlchemy 是 Python 中最强大、最受欢迎的 ORM(对象关系映射)库,它允许你使用 Python 对象来操作数据库,而不需要直接编写 SQL 语句。同时,它也提供了对底层 SQL 的完全控制能力,适用于从简单脚本到大型企…...

java----------->代理模式
目录 什么是代理模式? 为什么会有代理模式? 怎么写代理模式? 实现代理模式总共需要三步: 什么是代理模式? 代理模式:给目标对象提供一个代理对象,并且由代理对象控制目标对象的引用 代理就是…...
ET ProcessInnerSender类(实体) 分析
ProcessInnerSender 作用是进程内部发送Actor消息 字段 TIMEOUT_TIME 超时时间RpcId 用来累加requestCallback 存储RPC的回调事件list 用来获取MessageQueue中的Actor消息 方法 Awake 初始化在MessageQueue中注册待处理的消息队列Destroy 移除在MessageQueue中的消息队列U…...