Appearance
第五部分:MySQL 8 性能调优、Undo/Redo 日志底层、事务隔离与分库分表实战
第 1 章:Undo Log 与 Redo Log 物理概念理解、刷盘流程与生产 my.cnf 配置
在 MySQL InnoDB 存储引擎中,Undo Log (回滚日志) 与 Redo Log (重做日志) 是实现事务 ACID 特性与高可用的物理双壁。
text
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ InnoDB 双日志物理工作拓扑全景 │
│ │
│ [ UPDATE 语句 ] ➔ [ 1. 产生 Undo Log (逻辑反向 SQL) ] ➔ 存入 Undo Segment (保障原子性/MVCC)
│ │ │
│ ↓ │
│ [ 修改 Buffer Pool 脏页 ] ➔ [ 2. 产生 Redo Log (物理页改动) ] ➔ 存入 Redo Log Buffer │
│ │ │
│ (fsync 刷盘策略: 0/1/2) ─────┘ │
│ ↓ │
│ [ 3. 磁盘 ib_logfile (保障持久性/Crash Recovery) ] │
└─────────────────────────────────────────────────────────────────────────────────────────┘1.1 Undo Log vs Redo Log 物理本质深度对比表
| 维度对比 | Undo Log (回滚日志) | Redo Log (重做日志) |
|---|---|---|
| 核心职责 | 保障 原子性 (Atomicity) 与 MVCC 多版本并发控制 | 保障 持久性 (Durability) 与 崩溃恢复 (Crash Recovery) |
| 日志物理性质 | 逻辑日志 (记录相反操作:INSERT 对应 DELETE,UPDATE 对应相反更新) | 物理日志 (记录数据页物理改动:“在 Page 42 偏移量 100 处修改了 8 字节”) |
| 物理存储位置 | Undo Tablespace (.ibu 文件) 或系统表空间 ibdata1 | Redo Log 文件 (ib_logfile0, ib_logfile1 或 MySQL 8.0 redo/ 目录) |
| 产生与写入时机 | 数据被物理修改 之前 产生 | 数据被物理修改 之后, Buffer Pool 脏页刷盘 之前 产生 (WAL) |
| 触发与使用场景 | 1. 执行 ROLLBACK 语句2. 数据库崩溃后回滚未提交事务 3. MVCC 快照读构建历史版本 | 1. 数据库断电/宕机后重放物理日志恢复内存脏页 2. WAL 机制保障将随机磁盘 I/O 转化为顺序 I/O |
1.2 什么情况下会产生和使用 Undo/Redo Log?
1. Undo Log 产生的 3 大场景:
- 场景 A:执行
INSERT语句:产生的 Undo Log 记录对应的DELETE操作(事务提交后直接释放); - 场景 B:执行
UPDATE/DELETE语句:记录旧数据的物理快照(放入 Undo 链表,用于 MVCC 快照读); - 场景 C:事务显式
ROLLBACK或执行报错:MySQL 读取 Undo Log 顺藤摸瓜逆向执行反向 SQL,恢复数据。
2. Redo Log 产生的场景与 WAL 机制:
- WAL 机制 (Write-Ahead Logging):MySQL 修改数据时,先写 Redo Log 物理日志,再在内存中修改 Buffer Pool 脏页。
- 崩溃恢复 (Crash Recovery):若服务器突然断电,内存中尚未刷盘的脏页丢失。重启时,MySQL 自动扫描 Redo Log,重放 (Redo) 物理日志,将数据页恢复到断电前的状态。
1.3 Redo Log 刷盘策略 (innodb_flush_log_at_trx_commit) 物理 0/1/2 详解
Redo Log 刷盘分为 3 步:Redo Log Buffer (内存) ➔ OS Page Cache (系统缓存) ➔ Redo Log File (磁盘)。
text
[ Redo Log Buffer ] ──(write)──> [ OS Page Cache ] ──(fsync)──> [ Disk ib_logfile ]💬 innodb_flush_log_at_trx_commit 参数物理选型
0(延迟刷盘,最快但不安全): 事务提交时不主动刷盘,每秒由后台线程将 Redo Log Buffer 写入 OS Cache 并fsync到磁盘。MySQL 崩溃或 OS 崩溃会丢失 1 秒的数据;1(强一致性,默认最安全): 每次事务提交时,都强制将 Redo Log Buffer 写入 OS Cache 并立即执行fsync刷盘。即便 OS 断电也绝不丢数据(双 1 保证:innodb_flush_log_at_trx_commit=1+sync_binlog=1);2(折中高性能推荐): 每次事务提交时,将 Redo Log Buffer 写入 OS Page Cache,但仅由后台线程每秒执行fsync。MySQL 进程崩溃不丢数据,只有操作系统整机断电才会丢 1 秒数据。
1.4 MySQL 配置文件 my.cnf 生产物理参数配置
ini
[mysqld]
# 1. Redo Log 刷盘策略 (1: 金融级安全, 2: 高性能)
innodb_flush_log_at_trx_commit = 1
# 2. Binlog 同步刷盘策略 (1: 每次事务提交立即 fsync 刷盘,与 Redo Log 构成 2PC 强一致)
sync_binlog = 1
# 3. Redo Log 自动容量设置 (MySQL 8.0.30+ 建议使用 innodb_redo_log_capacity,自动管理文件)
innodb_redo_log_capacity = 2147483648 # 设置为 2GB 物理大小
# 4. Undo Log 独立表空间与自动收缩截断配置 (解决 ibdata1 物理无限膨胀爆盘死穴)
innodb_undo_tablespaces = 2 # 创建 2 个独立的 undo 表空间
innodb_undo_directory = /var/lib/mysql/undo # 指定 undo 文件物理存储目录
innodb_undo_log_truncate = ON # 开启 Undo 表空间自动物理收缩截断
innodb_max_undo_log_size = 1073741824 # 当单个 Undo 文件超过 1GB 时自动清空收缩第 2 章:MySQL 顶级建表规范与 5 大通用字段标准
text
[ 5 大通用必备字段标准 ]
1. id bigint unsigned AUTO_INCREMENT PRIMARY KEY ➔ 主键自增 (解决 B+ 树页分裂与无序离散插入)
2. created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ➔ 创建时间
3. updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ➔ 自动更新时间
4. is_deleted tinyint unsigned NOT NULL DEFAULT 0 ➔ 逻辑软删除标记 (0正常 / 1已删)
5. version int unsigned NOT NULL DEFAULT 1 ➔ CAS 乐观锁版本号🔍 本章 6 重自审计报告
- 【知识审计】:已全量补充 Undo Log vs Redo Log 物理本质深度对比表、逻辑日志 vs 物理日志、WAL 预写日志机制、崩溃恢复物理过程、
innodb_flush_log_at_trx_commit物理 0/1/2 刷盘策略选型,以及my.cnf生产 Undo/Redo 参数设置(包含innodb_undo_log_truncate自动截断收缩配置)!已适配移动端::: info 💬自适应排版!