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

前言

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 做法:

事务修改内存页(Buffer Pool)
写入 redo log buffer
事务提交时,只需要把 redo log 刷入磁盘
数据页慢慢后台刷盘即可
只要 redo log 落盘成功,数据就永久安全。

2. redo log 崩溃恢复流程
MySQL 运行中宕机
内存数据丢失
重启后 InnoDB 扫描 redo log
把已提交但未刷盘的数据重新 “重做” 到数据页
数据库恢复到崩溃前一致状态
这就是 redo log 最核心的价值:保证事务持久性 + 大幅提升写入性能。

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

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

所以总体流程就是

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

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

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 状态
事务完成

上一篇 BGP的配置问题?
下一篇 MongoDB迁移至金仓实战:从数据孤岛到KES-AI时代融合数据库架构