全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-15 15 分钟 ✍️ juanwangdev

Redo Log与Undo Log

Redo Log和Undo Log是InnoDB保证事务ACID特性的核心机制。

Redo Log(重做日志)

核心作用

  • 保证事务持久性(Durability)
  • 崩溃恢复时重放已提交事务
  • WAL(Write-Ahead Logging)核心组件

存储结构

SQL
┌─────────────────────────────────────────────────┐
│                Redo Log架构                      │
├─────────────────────────────────────────────────┤
│  ┌─────────────┐     ┌─────────────────────┐   │
│  │ Log Buffer  │ ──→ │   Redo Log Files    │   │
│  │  (内存中)    │     │  ib_logfile0/1      │   │
│  └─────────────┘     └─────────────────────┘   │
│         ↑                      ↑                │
│    事务写入                顺序写入              │
└─────────────────────────────────────────────────┘

循环写入机制

SQL
        ib_logfile0              ib_logfile1
    ┌──────────────┐         ┌──────────────┐
    │   →→→→→→→→→→→→→→→→→→→→→│→→→→→→→→→→→→→→│
    └──────────────┘         └──────────────┘
           ↑                        ↑
      write pos                  check point
      (当前写入位置)              (检查点位置)

已使用空间 = write pos - check point
可用空间 = 总大小 - 已使用空间

写入流程

SQL
1. 事务修改数据
      ↓
2. 记录修改到Redo Log Buffer
      ↓
3. 根据策略刷入Redo Log文件
      ↓
4. 提交事务(Commit)

关键参数

SQL
-- Redo Log刷盘策略(0/1/2)
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';

-- 值说明
-- 0: 每秒刷盘,崩溃可能丢失1秒数据
-- 1: 每次提交刷盘,最安全(默认)
-- 2: 每次提交写入OS缓存,每秒刷盘

-- Redo Log文件大小
SHOW VARIABLES LIKE 'innodb_log_file_size';

-- Redo Log文件数量
SHOW VARIABLES LIKE 'innodb_log_files_in_group';

-- Log Buffer大小
SHOW VARIABLES LIKE 'innodb_log_buffer_size';

刷盘策略对比

刷盘时机性能安全性
0每秒刷盘最高最低(可能丢1秒数据)
1每次提交刷盘最低最高(默认)
2提交写OS缓存,每秒刷盘中等中等

Undo Log(回滚日志)

核心作用

  • 保证事务原子性(Atomicity)
  • 支持事务回滚
  • 支持MVCC多版本读

存储结构

text
Undo Log存储在系统表空间或独立Undo表空间

┌─────────────────────────────────────┐
│            Undo Log记录              │
├─────────────────────────────────────┤
│  trx_id: 事务ID                      │
│  roll_ptr: 回滚指针                  │
│  undo_type: 操作类型(INSERT/UPDATE) │
│  old_values: 修改前的数据             │
└─────────────────────────────────────┘

数据行隐藏列

text
每行数据包含隐藏列:
┌────────┬──────────┬───────────┐
│ DB_TRX_ID │ DB_ROLL_PTR │ DB_ROW_ID │
│  事务ID   │  回滚指针    │  行ID     │
│  (6字节)  │  (7字节)    │  (6字节)  │
└────────┴──────────┴───────────┘

版本链示意

text
当前数据行 ←── DB_ROLL_PTR ──→ Undo Log记录1
                                      ↓
                              Undo Log记录2
                                      ↓
                              Undo Log记录3
                                      ↓
                                  历史版本

MVCC读取流程

text
1. 事务开始,获取Read View
      ↓
2. 根据DB_TRX_ID判断可见性
      ↓
3. 不可见 → 通过DB_ROLL_PTR找Undo Log
      ↓
4. 遍历版本链直到找到可见版本
      ↓
5. 返回该版本数据

Undo Log类型

类型适用操作存储内容
insert undo logINSERT主键值
update undo logUPDATE/DELETE修改前数据

两者的协作关系

事务提交流程

text
┌─────────────────────────────────────────────────┐
│              事务提交流程                         │
├─────────────────────────────────────────────────┤
│  1. 修改数据,写入Buffer Pool                   │
│              ↓                                  │
│  2. 记录Undo Log(修改前数据)                   │
│              ↓                                  │
│  3. 记录Redo Log(修改操作)                    │
│              ↓                                  │
│  4. 修改Buffer Pool中的数据页                   │
│              ↓                                  │
│  5. 写入Redo Log Buffer                        │
│              ↓                                  │
│  6. 根据策略刷入Redo Log文件                    │
│              ↓                                  │
│  7. 提交成功                                    │
└─────────────────────────────────────────────────┘

崩溃恢复流程

text
1. 数据库启动
      ↓
2. 检查Redo Log
      ↓
3. 重放(Redo)已提交但未刷盘的事务
      ↓
4. 回滚(Undo)未提交的事务
      ↓
5. 恢复完成

性能优化

Redo Log优化

text
-- 高并发写入场景
SET innodb_log_file_size = 512M;  -- 增大日志文件
SET innodb_log_buffer_size = 64M; -- 增大缓冲区

-- 追求性能可接受少量数据丢失
SET innodb_flush_log_at_trx_commit = 2;

Undo Log优化

text
-- 使用独立Undo表空间(MySQL 8.0+)
SHOW VARIABLES LIKE 'innodb_undo_tablespaces';

-- Undo日志保留时间(用于长事务回滚)
SHOW VARIABLES LIKE 'innodb_max_undo_log_size';

监控指标

text
-- Redo Log状态
SHOW STATUS LIKE 'Innodb_os_log_written';
SHOW STATUS LIKE 'Innodb_log_waits';

-- Undo Log状态
SHOW STATUS LIKE 'Innodb_undo_log_active';
SHOW STATUS LIKE 'Innodb_undo_log_expunge';

要点总结

  • Redo Log保证持久性,崩溃恢复时重放已提交事务
  • Undo Log保证原子性,支持回滚和MVCC
  • Redo Log采用循环写入,WAL机制提升性能
  • Undo Log通过版本链实现MVCC,支持一致性非锁定读
  • innodb_flush_log_at_trx_commit=1是默认最安全设置
  • 合理配置日志大小和刷盘策略,平衡性能与可靠性

📝 发现内容有误?点击此处直接编辑

← 上一篇 MySQL架构与存储引擎概述
下一篇 → 存储引擎比较与选择
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库