MySQL三大日志 binglog(历史档案) redolog(草稿本/记账本) undolog(后悔药)

MySQL 中的三大日志(binlog 、redo log 、undo log )是数据库能够实现 ACID 特性 (特别是原子性、持久性)以及主从复制 、数据恢复的关键。

为了让你条理清晰地理解,我们可以从作用、所属层级、记录内容这几个维度来拆解。

我们可以把它们比作:

  • binlog :"历史档案"(记录所有发生过的事,用于归档和传给别人)。
  • redo log :"草稿本/记账板"(防止突然断电,用于崩溃恢复)。
  • undo log :"后悔药"(事务失败了要回滚,或者看过去的数据)。

一、 redo log(重做日志)------ 保证"持久性" (Durability)

1. 核心作用:Crash-safe(崩溃恢复)

MySQL 为了性能,更新数据时是先更新内存(Buffer Pool),然后异步刷到磁盘。如果内存更新了但还没刷盘时数据库宕机,数据就丢了。
redo log 的作用就是:只要事务提交成功,即使数据库立刻宕机,重启后也能通过 redo log 找回数据。 这就是 WAL 技术(Write-Ahead Logging,先写日志,再写磁盘)。

2. 所属层级

  • 特属于 InnoDB 存储引擎。

3. 记录内容(物理日志)

  • 它记录的是物理修改。比如:"在第 X 号表空间的第 Y 号数据页上,偏移量 Z 处做了什么修改"。

4. 写入方式(循环写)

  • redo log 的文件大小是固定的(例如一组 4 个文件,每个 1GB)。
  • 它像一个圆环,写满了一个就回到开头覆盖写。
  • write pos:当前记录的位置。
  • checkpoint:当前已经擦除(同步到磁盘)的位置。
  • 如果 write pos 追上了 checkpoint,说明空间满了,必须停下来把脏页刷到磁盘,腾出空间。

二、 undo log(回滚日志)------ 保证"原子性" (Atomicity)

1. 核心作用:事务回滚 & MVCC

  • 事务回滚 :如果一个事务执行到一半出了错,或者用户执行了 ROLLBACK,MySQL 需要把数据恢复到事务开始前的样子。
  • MVCC(多版本并发控制):当读取记录时,若该记录被其他事务占用,可以通过 undo log 读取之前的版本(快照读),实现非阻塞读。

2. 所属层级

  • 特属于 InnoDB 存储引擎。

3. 记录内容(逻辑日志)

  • 它记录的是逻辑相反操作。
    • 你执行 INSERT,它记录一条 DELETE。
    • 你执行 DELETE,它记录一条 INSERT。
    • 你执行 UPDATE,它记录一条反向的 UPDATE。

4. 生命周期

  • 事务开始前产生,事务提交后并不会立刻删除(因为 MVCC 可能还需要用),而是放入待删除列表,由 Purge 线程清理。

三、 binlog(归档日志)------ 用于"复制"和"恢复"

1. 核心作用:主从复制 & 数据恢复

  • 主从复制:Master 端把 binlog 发送给 Slave 端,Slave 重放这些日志,从而保证主从数据一致。
  • 数据恢复:如果你误删库了,可以通过 binlog 把数据库恢复到某个时间点(PITR - Point In Time Recovery)。

2. 所属层级

  • 属于 MySQL Server 层(所有存储引擎共用,MyISAM 也有)。

3. 记录内容(逻辑日志)

  • 记录的是 SQL 语句的原始逻辑。
  • 格式有三种:
    • Statement:记录 SQL 语句原文(可能导致主从不一致,如使用了 now() 函数)。
    • Row:记录每一行具体被修改成什么样(最安全,但日志量大)。
    • Mixed:混合模式。

4. 写入方式(追加写)

  • 追加写(Append-only)。文件写到一定大小后会切换到下一个文件,不会覆盖以前的日志。

四、 重点对比:redo log vs binlog

这是面试中最常问的区别,必须清晰区分:

|----------|-----------------------|-----------------------|
| 特性 | redo log (重做日志) | binlog (归档日志) |
| 归属 | InnoDB 引擎特有 | MySQL Server 层 (引擎通用) |
| 内容类型 | 物理日志 (数据页改了啥) | 逻辑日志 (SQL语句/行变化) |
| 主要作用 | 崩溃恢复 (Crash-safe) | 主从复制 、历史恢复 |
| 写入方式 | 循环写 (空间固定,会覆盖) | 追加写 (文件切换,不覆盖) |
| 持久性 | 事务提交必须写 (保证不丢) | 事务提交必须写 (保证同步) |


五、 进阶:它们是如何配合的?(两阶段提交)

当我们要更新一条数据时,redo log 和 binlog 是如何保证一致性的?这就涉及到了两阶段提交 (Two-Phase Commit, 2PC)。

假设执行 UPDATE user SET name='A' WHERE id=1;

  1. 执行阶段:InnoDB 将内存中的数据更新。
  2. redo log prepare(预提交) :InnoDB 写 redo log,标记状态为 prepare。
  3. 写 binlog:Server 层写入 binlog 并持久化到磁盘。
  4. redo log commit(提交) :InnoDB 将 redo log 标记为 commit。

为什么要这么麻烦?

是为了防止由宕机引发的 "日志不一致"。

  • 如果先写 redo log,再写 binlog:
    • redo log 写完,机器断电,binlog 没写。
    • 重启后,redo log 恢复了数据(主库有数据),但 binlog 没记录(从库没数据)。主从不一致。
  • 如果先写 binlog,再写 redo log:
    • binlog 写完,机器断电,redo log 没写。
    • 重启后,主库数据丢了(redo log 没刷盘),但从库通过 binlog 同步了该数据。主从不一致。

两阶段提交保证了:要么两个日志都成功,要么都失败,确保主库数据和从库(以及历史归档)的一致性。

总结

  • undo log:原子性。如果我要反悔(回滚),或者想看旧数据(MVCC),找它。
  • redo log:持久性。如果服务器挂了,重启时要恢复内存里没来得及刷盘的数据,找它。
  • binlog:归档与复制。如果我要把数据同步给从库,或者恢复到上个月的状态,找它。
相关推荐
夏天的清晨3 分钟前
C++入门学习
开发语言·c++·学习
代码山河5 分钟前
Java的前世今生:从Oak语言到Java 23的发展史
java·学习·架构·教程·面向对象·项目
新鲜势力呀6 分钟前
PHP 文件上传系统实战:从上传卡顿到分片上传 + 秒传 + 云存储架构完整优化方案
开发语言·架构·php
vx_Biye_Design7 分钟前
springboot角色扮演服务平台65161-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
李游Leo8 分钟前
HarmonyOS 7 QuickDock 闪控窗开发实录 02:floatView × floatingBall:形态切换、位置恢复与单一状态源【鸿蒙心迹】
java·华为·harmonyos
企业数字化笔记9 分钟前
视频局部合成怎么做得自然?掩膜修复、边缘羽化、时序稳定与背景替换
java·javascript·音视频
仍然.15 分钟前
Redis---主从复制
java·数据库·redis
vx_Biye_Design18 分钟前
springboot咖啡厅顾客点单管理系统12080-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
QQ_216962909622 分钟前
基于微信小程序的智能膳食分析系统
java·大数据·spring boot·微信小程序·小程序·旅游
程序员老陆22 分钟前
从语法糖到类型系统:深度拆解 C++ Lambda 与可调用对象的“血缘关系”
开发语言·c++·程序设计