【MySQL 三大日志深度解析】:redo log、undo log、binlog 作用与两阶段提交原理

🔥你好我是fengxin_rou这是我的个人主页 fengxin_rou的主页

❄️欢迎查看我的专栏我的专栏

《Java后端学习》《JAVASE基础》《JUC并发》《redis》《JVM虚拟机》《MYSQL》《黑马点评》《rabbitmq》《JavaWeb+AI的talis学习系统》《苍穹外卖》

前言

MYSQL已经学习过了事务和锁,今天就来讲一讲日志的相关知识,主要讲解了mysql的三大日志,以及其对应的作用,并且探究了mysql是如何做到数据持久化,遇到mysql重启时数据丢失怎么恢复,mysql在提交事务时redolog和binlog的两阶段提交原理

一、MySQL 三大日志核心作用

MySQL 有三种最核心的日志:

1. redo log(重做日志)

作用:是InnoDB的引擎层生成的日志,保证事务持久性,用于掉电等故障恢复

  • 属于 InnoDB 引擎层日志
  • 记录物理日志:某个数据页被修改了什么
  • 固定大小、循环写
  • 核心价值:事务提交不用立即刷盘,MySQL 重启后能把已提交事务 "重做" 回来

2. undo log(回滚日志)

作用:是InnoDB的引擎层生成的日志,保证事务原子性,事务回滚,支撑 MVCC

  • 记录逻辑日志:数据修改前的样子
  • 用于事务回滚、多版本并发控制
  • 不参与崩溃恢复,负责 "可回滚、可快照"

3. binlog(归档日志)

作用:是一种二进制日志文件,是Servicer层日志,数据归档、主从复制、时间点恢复

  • 属于 MySQL Server 层日志
  • 记录逻辑变更:SQL 或行变化
  • 追加写、可无限扩容
  • 支撑主从同步、增量备份、数据回档

二、redo log 为什么能保证崩溃恢复?WAL 机制

1. 什么是 WAL?

WAL = Write-Ahead Logging(预写日志) 核心思想:先写日志,再写磁盘。

如果每次事务提交都直接刷数据页:

  • 随机 I/O 极慢
  • 高并发下数据库直接卡死

WAL 做法:

  1. 事务修改内存页(Buffer Pool)
  2. 写入 redo log buffer
  3. 事务提交时,只需要把 redo log 刷入磁盘
  4. 数据页慢慢后台刷盘即可

只要 redo log 落盘成功,数据就永久安全。

2. redo log 崩溃恢复流程

  1. MySQL 运行中宕机
  2. 内存数据丢失
  3. 重启后 InnoDB 扫描 redo log
  4. 把已提交但未刷盘的数据重新 "重做" 到数据页
  5. 数据库恢复到崩溃前一致状态

这就是 redo log 最核心的价值:保证事务持久性 + 大幅提升写入性能

3.Redo log的顺序写入:

redo log采用追加写入的方式,将redo日志记录追加到文件末尾,而不是随机写入。这样可以减少磁盘的随机I/O操作,提高写入性能**,因为redo log是一个环形大小的缓冲区,那么在末尾时会从头开始写,覆盖已经刷盘、不再需要的旧记录(循环写)**

4.Checkpoint机制

因为数据库会定期将内存中的数据刷新到磁盘,此时就会将最新的LSN(log sequence number)写入磁盘,LSN标志了当前redo log刷新磁盘的操作到哪一个位置了。这个 LSN 表示:此 LSN 之前的数据都已经安全落盘

所以总体流程就是

  1. 数据页 = MySQL 真实落在磁盘上的数据文件(.ibd)
  2. 崩溃前:磁盘数据页的 LSN 一定 ≤ redo log 的 LSN
  3. 恢复时:从「较小的那个 LSN(数据页 LSN)」开始,重做 redo log 里更大、更新的部分
  4. 最终把内存没来得及刷盘的数据,重新补写到磁盘数据页里

三、binlog 是什么?statement /row/mixed 区别

binlog 是 MySQL Server 层 的逻辑日志,Server层每进行一次数据操作 就会生成一条binlog,等事务结束后,统一把所有binlog写入binlog文件 ,并且binlog不会记录select语句,只会记录修改表结构和数据的语句

binlog是追加写,一个文件写满后再新建一个文件继续写。

1. binlog 三大格式对比

(1)STATEMENT 模式,又称逻辑日志
  • 每进行执行一条sql语句就记录**SQL 语句原文,**主从复制中 slave 端再根据 SQL 语句重现
  • 优点:日志小、性能好
  • 缺点:有动态函数问题,如uuid、now这样随时在变函数会导致主从节点不一致,MySQL 5.7.7 之后将默认格式改为 ROW 的主要原因。
(2)ROW 模式(企业推荐)(MySQL 5.7.7 及之后的默认格式)
  • 记录行的修改前后数据,一条update语句修改了多少行数据,就记录多少行
  • 优点:主从完全一致、安全、可精准恢复,不会有动态函数问题
  • 缺点:日志体积稍大
  • 现在互联网公司默认使用 ROW
(3)MIXED 模式
  • 混合 STATEMENT 和 ROW
  • 简单 SQL 用 STATEMENT
  • 不安全 SQL 自动切 ROW
  • 折中方案,逐步被 ROW 取代

结论:生产环境直接用 ROW 格式。


四、redo log 和 binlog 的核心区别

对比项 redo log binlog
所属层级 InnoDB 引擎层 MySQL Server 层
日志类型 物理日志(数据页修改) 逻辑日志(SQL / 行变化)
写入方式 循环写(固定大小) 追加写(无限文件)
主要作用 崩溃恢复 主从复制、数据备份
事务保证 保证 ACID 持久性 不保证事务,只记录变更
生成时机 事务执行中持续写 事务提交时一次性写

一句话记忆:redo 管崩溃,bin 管复制。


五、事务提交:redo log + binlog 两阶段提交原理

1. 为什么需要两阶段提交?

如果没有两阶段提交:

  • redo 写成功、binlog 没写 → 主库恢复了数据,从库没有
  • binlog 写成功、redo 没写 → 从库有数据,主库没有 最终导致主从数据不一致

两阶段提交就是为了:让 redo log 与 binlog 逻辑完全一致

2. 两阶段提交完整流程

阶段 1:prepare 准备阶段
  • InnoDB 将 redo log 写盘
  • 标记事务为 prepare 状态(未最终提交)
阶段 2:写入 binlog
  • 执行器写 binlog
  • 刷盘成功,才算事务真正成功
阶段 3:commit 提交阶段
  • InnoDB 将 redo log 标记为 commit 状态
  • 事务完成

3. 崩溃恢复怎么判断?

  • prepare 阶段:将 XID(内部 XA 事务的 ID) 写入到 redo log,同时将 redo log 对应的事务状态设置为 prepare,然后将 redo log 持久化到磁盘(innodb_flush_log_at_trx_commit = 1 的作用);
  • commit 阶段:把 XID 写入到 binlog,然后将 binlog 持久化到磁盘(sync_binlog = 1 的作用),接着调用引擎的提交事务接口,将 redo log 状态设置为 commit,此时该状态并不需要持久化到磁盘,只需要 write 到文件系统的 page cache 中就够了,因为只要 binlog 写磁盘成功,就算 redo log 的状态还是 prepare 也没有关系,一样会被认为事务已经执行成功;

prepare阶段是XID写入redo log, commit阶段是XID写入binlog

  • 如果 binlog 中没有当前内部 XA 事务的 XID,说明 redolog 完成刷盘,但是 binlog 还没有刷盘,则回滚事务。对应时刻 A 崩溃恢复的情况。
  • 如果 binlog 中有当前内部 XA 事务的 XID,说明 redolog 和 binlog 都已经完成了刷盘,则提交事务。对应时刻 B 崩溃恢复的情况。
  • 如果 binlog 已写入 + redo 是 commit (时刻B后)→ 提交
  • 如果 binlog 已写入 + redo 是 prepare (时刻B前)→ 提交
  • 如果 binlog 未写入(时刻A) → 回滚

只要 binlog 已经写入了该事务的 XID(事务 ID),恢复时就一定会把事务提交 ,不管此时 redo log 是 prepare 还是 commit 状态。

两阶段提交 = MySQL 分布式事务的基石。

六、UndoLog日志的作用是什么?

undo log是用于回滚的日志,在一个事务中记录sql语句执行前的数据,在失败之后就做sql语句的反操作来回退

  • 插入 一条记录时,要把这条记录的主键值记下来,这样之后回滚时只需要把这个主键值对应的记录删掉就好了;
  • 删除 一条记录时,要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了;
  • 更新 一条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值就好了。
相关推荐
ECT-OS-JiuHuaShan3 小时前
存在是微分张量积,标量是参数但不可能是本质。还原论泛化,是语义劫持和以偏概全的逻辑谋杀伪科学庞氏骗局
数据库·人工智能·算法·机器学习·数学建模
IT策士3 小时前
Django 从 0 到 1 打造完整电商平台:使用 Django 消息框架与用户权限初步
数据库·django·sqlite
星河耀银海3 小时前
JAVA 注解(Annotation):从原理到实战应用
java·开发语言·数据库
lzp07913 小时前
基于多模态视觉模型和图文向量模型的工业图像知识库研究与应用(伍)
数据库·学习·neo4j
sunshine8853 小时前
合并报表自动化:数据治理如何助力集团企业突破成本与合规瓶颈?
大数据·数据库·人工智能
云边有个稻草人3 小时前
金仓数据库KingbaseES自动创建表空间目录:简化运维,适配国产生态
数据库·数据加密·kingbasees·信创适配·国产化数据库·表空间自动创建
imuliuliang4 小时前
Laravel5.x核心特性全解析
android·运维·数据库·nginx
Miss roro4 小时前
企业合同管理系统选型的核心维度:功能完整性、协作效率与安全合规
java·数据库·安全·法律科技
Irene19914 小时前
数据库锁机制:表锁、行锁(Oracle 默认)、共享锁、排他锁、乐观锁、悲观锁、死锁、Hive 中的锁
数据库