MySQL InnoDB 内核机制 — 系列规划
本文是写作规划,不是可发布正文。按
WRITING_GUIDE.md流程:先定来源台账、实验台账、篇目结构,再写 index.md 和正文。
一、为什么写这个系列
1.1 现有内容的覆盖情况
| 已有系列 | 视角 | 与 InnoDB 的重叠 |
|---|---|---|
| postgresql-kernel (26) | PG 完整内核 + 运维实战 | 刚完成;MVCC/WAL/Buffer/B-Tree 均有 PG 视角 |
| db/mvcc (1) | PG MVCC 源码 | 未覆盖 undo log 方案 |
| storage (79) | 通用 Buffer Pool、B-Tree、WAL/ARIES | 不到 InnoDB 具体实现 |
| db/lsm-tree (9) | 写优化引擎 | B-Tree 体系,对照价值在 compaction vs B+Tree |
| distributed (69) | 复制理论 | 不涉及 binlog/半同步复制实现 |
结论:PG 26 篇填上了「开源 RDBMS 内核拆解」的第一块拼图。InnoDB 是第二块——中国工程环境中 PG + MySQL 并存极普遍,且 InnoDB 的 undo log MVCC、gap lock、binlog 双写与 PG 的设计分叉,是对照学习的最佳材料。
1.2 为什么选 InnoDB(而不是 MySQL Server 全栈)
| 维度 | InnoDB | MySQL Server 其他部分 |
|---|---|---|
| 源码集中度 | storage/innobase/,~15 万行 C++ |
优化器、复制、权限分散多目录 |
| 与 PG 对照价值 | MVCC、锁、Buffer、B+Tree、崩溃恢复 | SQL 层、权限模型对照价值低 |
| 生产问题密度 | gap lock、flush 列表、长事务 undo、主从延迟 | 相对分散 |
| 文档 | MySQL Internals Manual + 源码注释 | 官方文档偏使用层 |
1.3 系列定位
两条腿走路:内核机制拆解 + 生产运维实战(与 PG 系列对称,略短)。
- 内核线(第 1–15 章):对着 InnoDB 源码追踪 DML/查询路径
- 运维线(第 16–20 章):经典故障、性能调查、配置陷阱、主从切换边界
与 PG 系列的显式对照:MVCC(undo vs 多版本行)、锁(gap lock vs 行锁)、复制(binlog+redo 2PC vs WAL 流复制)——每章末尾设「PG 对照」小节,不超过 300 字,引用 PG 系列对应篇章。
二、核心问题与目标读者
2.1 七个关键问题
InnoDB 的线程模型和内存布局是什么? Master thread、purge thread、IO thread、page cleaner——各自职责?Buffer Pool 如何划分? → 第 1、2 章。
一条 UPDATE 从 SQL 到磁盘经历了什么? 解析(Server 层)→ 优化器 → InnoDB handler → Buffer Pool → undo → redo → doublewrite → 数据文件。 → 第 3、4、5、6 章。
InnoDB 的 MVCC 为什么用 undo log 而不是 PG 式的多版本行? Read View、undo 链、RC vs RR 的差异、幻读与 gap lock 的关系。 → 第 7、8 章。
InnoDB 的锁到底锁的是什么? 记录锁、间隙锁、Next-Key Lock、意向锁、MDL——与 PG 行锁模型的差异。 → 第 9 章。
崩溃恢复时 redo 和 undo 各做什么? Checkpoint、LSN、Mini-Transaction、崩溃恢复两阶段。 → 第 5、10 章。
binlog 和 InnoDB redo 如何协调? 两阶段提交(2PC)、XID、组提交(group commit)、主从复制的延迟来源。 → 第 11、12 章。
InnoDB 最危险的故障模式是什么? 长事务 undo 膨胀、flush 列表堆积、IO 能力跟不上 dirty page、gap lock 死锁、主从延迟、半同步降级。 → 第 16–20 章。
2.2 目标读者
| 维度 | 说明 |
|---|---|
| 主要读者 | MySQL DBA、从 PG 转 MySQL 的后端、数据库内核开发者 |
| 次要读者 | 已读 PG 内核系列、想建立对照直觉的工程师 |
| 先修知识 | SQL、ACID、C/C++ 阅读能力、操作系统基础 |
| 先修阅读 | 建议先读 PG 系列第 3–6 章,或本站
db/mvcc/mvcc.md |
| 不假设 | MySQL 内核贡献经验 |
三、篇目结构
全系列 20 章,分五部分。每章按「问题 — 源码 — 实验 — PG 对照 — 边界」组织。
第一部分:体系结构(第 1–2 章)
第 1 章:InnoDB 架构与线程模型
- InnoDB 在 MySQL Server 中的位置:handler 接口、与 Server 层的边界
- 后台线程:master、purge、read/write IO、page cleaner、flush list coordinator
- 内存结构概览:Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer
- 源码焦点:
storage/innobase/srv/srv0srv.cc、include/srv0srv.h
第 2 章:页结构与行格式
- FIL 页头、Infimum/Supremum、User Records、Page Directory
- 聚簇索引:主键即数据;二级索引叶子存主键
- ROW_FORMAT:COMPACT/DYNAMIC/COMPRESSED 差异
- 实验:
INFORMATION_SCHEMA.INNODB_TABLESPACES+ 十六进制页 dump(xxd或工具) - 源码焦点:
include/rem0rec.h、page0page.cc
第二部分:存储与崩溃恢复(第 3–6 章)
第 3 章:Buffer Pool 与 LRU
- Buffer Pool 实例、chunk、frame
- LRU 列表 + Free 列表 + Flush 列表
- 年轻/年老 LRU
分区、
innodb_old_blocks_pct - Read-ahead(线性/随机)
- 实验:
SHOW ENGINE INNODB STATUS观察 Buffer Pool 命中率 - 源码焦点:
buf/buf0buf.cc、buf/buf0lru.cc - PG 对照:第 5 章 Buffer Manager
第 4 章:Redo Log 内部机制
- Redo log buffer → 文件循环写 → checkpoint
- LSN、flushed_to_disk_lsn、checkpoint_lsn
- Mini-Transaction(mtr)与 redo 记录类型
- 组提交(group commit)与
sync_binlog/innodb_flush_log_at_trx_commit联动 - 源码焦点:
log/log0log.cc、mtr/mtr0mtr.cc - PG 对照:第 4 章 WAL
第 5 章:Undo Log 与事务回滚
- Undo segment、rollback segment、undo page
- Insert undo vs Update undo
- Purge 线程如何回收 undo
- 长事务导致 undo history 堆积的机制
- 源码焦点:
trx/trx0undo.cc、trx/trx0purge.cc - PG 对照:PG 无 undo log——对比 VACUUM 必要性
第 6 章:Doublewrite 与页完整性
- Partial page write 问题
- Doublewrite buffer 的两阶段写
- MySQL 8.0+ 的 redo log 加密与 doublewrite 变体
- 源码焦点:
buf/buf0dblwr.cc
第三部分:并发控制(第 7–10 章)
第 7 章:MVCC 与 Read View
- 隐藏列:
DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID - Read View
构造:
m_ids、min_trx_id、max_trx_id - RC:每次语句新 Read View;RR:事务首个 Read View
- 可见性判断算法(对照
db/mvcc/mvcc.md的 PG 版本) - 源码焦点:
read/read0read.cc - PG 对照:第 3 章 MVCC/CLOG
第 8 章:隔离级别与幻读
- 四种隔离级别在 InnoDB 中的实际语义
- 当前读 vs 一致性读(快照读)
- RR 下如何用 gap lock 解决幻读
- 实验:两个 session 复现幻读与 gap lock
- 源码焦点:
lock/lock0lock.cc(select 加锁路径)
第 9 章:锁管理器
- 锁模式:S、X、IS、IX
- 记录锁、间隙锁、Next-Key Lock 的加锁规则
- 意向锁与表级锁
- 死锁检测:
lock_wait_timeoutvs 自动死锁检测 - MDL(Metadata Lock)与 InnoDB 锁的分工(Server 层)
- 实验:
performance_schema.data_locks观察锁等待 - PG 对照:第 6 章 Lock Manager
第 10 章:崩溃恢复
- Startup 阶段:redo apply → undo rollback
recv_recovery_from_checkpoint_start- 未提交事务的处理
- 源码焦点:
log/log0recv.cc
第四部分:索引与查询(第 11–15 章)
第 11 章:B+Tree 与索引
- 聚簇索引 vs 二级索引的回表
- 页分裂与合并
- Change Buffer(Insert Buffer)延迟合并
- 源码焦点:
btr/btr0btr.cc、ibuf/ibuf0ibuf.cc - PG 对照:第 14 章 B-Tree
第 12 章:Binlog 与 InnoDB 两阶段提交
- Server 层 binlog 与 InnoDB redo 的 XA 协议
- 组提交顺序:binlog prepare → InnoDB commit → binlog commit
sync_binlog=1+innodb_flush_log_at_trx_commit=1的持久性语义- 源码焦点:Server 层
sql/binlog.cc+ InnoDBtrx0trx.cc(XA 路径)
第 13 章:主从复制机制
- Dump thread、IO thread、SQL thread(异步)
- GTID、并行复制(MTS)、WRITESET 依赖跟踪
- 半同步复制(Semi-sync)的等待点
- 延迟诊断:
Seconds_Behind_Master的陷阱 - PG 对照:第 18–19 章流复制/逻辑复制
第 14 章:Optimizer 与 InnoDB 的交界
- Handler
接口:
handler::index_read、rnd_next - ICP(Index Condition Pushdown)、MRR(Multi-Range Read)
- 覆盖索引与
Using index - 不深入 Server 层优化器全文——只讲 InnoDB 提供的接口与代价
- PG 对照:第 10–12 章
第 15 章:Change Buffer 与 Adaptive Hash Index
- Change Buffer 适用条件与 merge 时机
- AHI 的维护开销与
innodb_adaptive_hash_index=OFF的场景 - 8.0 中 AHI 默认关闭的工程背景
第五部分:运维实战(第 16–20 章)
第 16 章:监控体系
SHOW ENGINE INNODB STATUS关键段落精读- Performance
Schema:
events_transactions_*、data_locks、memory/innodb - 与 Prometheus
mysqld_exporter的关键指标 - PG 对照:第 21 章监控
第 17 章:经典故障模式
- 长事务 + undo 膨胀 + purge 跟不上
- Buffer Pool 脏页过多 + flush 跟不上 + 用户感知卡顿
- Gap lock 死锁链
- 主从延迟(大事务、单线程 SQL thread、磁盘 IO)
- 每个故障:现象 → 内核机制 → 排查 SQL → 修复边界
第 18 章:性能调查方法论
EXPLAIN ANALYZE(8.0.18+)→performance_schema→SHOW PROFILE(legacy)- 等锁:
data_locks+data_lock_waits - 等
IO:
innodb_os_log_written、Innodb_buffer_pool_pages_dirty - OS 层:
iostat、perf追踪io_submit - PG 对照:第 23 章
第 19 章:主从切换与数据恢复
mysqldumpvsxtrabackup/mysqlbackup的机制差异- PITR:binlog + full backup
- GTID failover 的
RESET MASTER边界 - 误操作
DROP后的 binlog 闪回边界
第 20 章:配置陷阱
innodb_buffer_pool_size:不是越大越好——实例数与 NUMAinnodb_flush_log_at_trx_commitvssync_binlog的组合语义innodb_lock_wait_timeoutvs 死锁检测innodb_thread_concurrency(已废弃但旧库仍有)max_connections× 每连接内存- 每条配查验方法和症状
四、篇目依赖关系
第 1 章 ──→ 第 2 章 ──→ 第 3 章 ──→ 第 4 章
│ │
↓ ↓
第 11 章 第 5 章 ──→ 第 7 章 ──→ 第 8 章
│ │
↓ ↓
第 10 章 第 9 章
│
↓
第 12 章 ──→ 第 13 章
│
第 14、15 章 ←─────┘
│
↓
第 16 章 ──→ 第 17 章
│
↓
第 18 章
│
┌─────────┴─────────┐
↓ ↓
第 19 章 第 20 章
弱依赖(可独立阅读)
- 第 15 章(Change Buffer/AHI)只依赖第 3、11 章
- 第 17 章(故障)可作为运维入口,但需第 5、7、9 章前置概念
- 第 20 章(配置)强烈依赖第 3、4、12 章
五、阅读路径
| 路径 | 篇目 | 适合 |
|---|---|---|
| A:MySQL DBA 日常 | 1→3→7→9→16→17→20 | 排查问题为主 |
| B:从 PG 转 MySQL | 7→8→9→5→12→13(每章读 PG 对照) | 建立差异直觉 |
| C:内核开发者 | 1→2→3→4→5→10→11 | 存储与恢复 |
| D:高可用 | 4→12→13→19 | 复制与切换 |
| E:应急 | 17→18→20→16 | 先止血再深入 |
六、来源台账
A 级
- MySQL 8.0 源码:
storage/innobase/(标注 tag,如mysql-8.0.36) - MySQL Internals Manual(InnoDB 章节)
- MySQL 8.0 Reference Manual(InnoDB 相关章节)
- 论文:InnoDB 早期设计(Heikki Tuuri 等)
B 级
- Percona 博客、MySQL Performance Blog(有作者和版本上下文)
- 《MySQL 技术内幕:InnoDB 存储引擎》— 对照 8.0 标注过时处
C 级(线索)
- 论坛高票回答、无版本上下文的调优帖
与 PG 系列交叉引用(A 级)
../postgresql-kernel/各对应章节
七、实验台账
| 环境项 | 说明 |
|---|---|
| MySQL 版本 | 8.0.36+(涉及 8.0 特性标注版本) |
| 编译 | 源码编译 --with-debug(可选,用于
gdb) |
| 工具 | performance_schema、SHOW ENGINE INNODB STATUS、gdb |
| 数据集 | sysbench oltp_read_write + 定制 gap lock
场景 |
| 章节 | 实验 |
|---|---|
| 第 2 章 | 页十六进制 dump + 行格式解析 |
| 第 7 章 | 两 session 可见性 + undo 链观察 |
| 第 8 章 | RC vs RR 幻读复现 |
| 第 9 章 | 构造 gap lock 死锁 + data_locks 查看 |
| 第 12 章 | sync_binlog/flush_log_at_trx_commit
四种组合的 crash 测试(VM) |
| 第 13 章 | 主从延迟 + 半同步降级观察 |
| 第 17 章 | 长事务 undo 膨胀 + purge 滞后 |
八、与其他系列的联动
| 系列 | 联动 |
|---|---|
postgresql-kernel/ |
每章 PG 对照小节 |
db/mvcc/mvcc.md |
第 7 章前置 |
storage/ |
Buffer Pool、B-Tree、WAL 通用原理 |
distributed/ |
复制一致性理论背景 |
九、边界承诺
承诺
- 核心流程配源码路径和函数名
- 关键流程 Mermaid 时序图
- 每章可复现实验
- PG 对照准确引用对应篇章,不编造 PG 行为
- 版本差异标注(至少 5.7 vs 8.0 关键变化)
不承诺
- MySQL Server 层优化器全文拆解
- MySQL NDB、MyRocks 等其他引擎
- Cloud RDS/Aurora 内部实现
- 万能调优公式
十、写作顺序
- 第 1、2 章(架构与页)
- 第 3、4、5 章(Buffer、Redo、Undo)
- 第 7、8、9 章(MVCC 与锁)
- 第 10、11 章(恢复与 B+Tree)
- 第 12、13 章(binlog 与复制)
- 第 14、15、6 章(查询交界、Change Buffer、Doublewrite)
- 第 16–20 章(运维实战)
十一、待确认问题
- 版本锚定:以 8.0 LTS 为主,5.7 差异是否单独成附录?
- 系列规模:20 章是否合适?Change Buffer/AHI 是否合并入第 11 章?
- PG 对照深度:每章 300 字小节 vs 独立「PG vs InnoDB」番外篇?
- MariaDB:是否标注 MariaDB 10.x 与 MySQL 8.0 的 InnoDB 分叉点?
- 示例环境:Docker 官方镜像 vs 源码编译——实验章统一哪种?
规划版本:v1,2026-06-18 下一步:确认待确认问题 → 编写系列 index.md → 开始第 1、2 章
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【MySQL InnoDB 内核】InnoDB 存储引擎机制深度拆解
从线程模型到页格式、从 undo log MVCC 到 binlog 两阶段提交——对 MySQL InnoDB 做源码级拆解,并与 PostgreSQL 内核系列逐章对照。20 篇覆盖内核机制与生产运维实战,面向 MySQL DBA、从 PG 转 MySQL 的后端与数据库内核开发者。