MySQL 8.0Notes

第 12 章:InnoDB 模块地图

zjc 于 2026-01-12 发布

这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 InnoDB 是事务存储引擎,负责页面存储、B+Tree、行操作、事务、锁、MVCC、日志、恢复和后台维护。

12.1 总体结构

ha_innobase
  -> row module
     |-- btr: B+Tree
     |-- page: page layout
     |-- rem: record format
     |-- buf: buffer pool
     |-- lock: row/table locks
     |-- trx: transaction
     |-- undo: undo log
     |-- log: redo log
     |-- mtr: physical consistency
     +-- fil: tablespace

12.2 目录地图

目录 职责
storage/innobase/btr/ B+Tree 操作
storage/innobase/page/ 页面结构
storage/innobase/rem/ 记录格式
storage/innobase/row/ 行读写与更新
storage/innobase/buf/ Buffer Pool
storage/innobase/ibuf/ Change Buffer
storage/innobase/lock/ 锁系统
storage/innobase/trx/ 事务
storage/innobase/undo/ Undo
storage/innobase/log/ Redo
storage/innobase/fil/ 表空间
storage/innobase/dict/ 引擎数据字典
storage/innobase/purge/ 清理
storage/innobase/row/row0mysql.cc handler 桥接

12.3 数据组织

Instance
  -> tablespace
     -> segments
        -> extents
           -> pages
              -> records

默认页大小 16KB:

SHOW VARIABLES LIKE 'innodb_page_size';

聚簇索引按主键组织数据;二级索引叶子存主键值,查询非索引列需要回表。

12.4 事务路径

BEGIN
  -> assign trx
     -> read / modify rows
        |-- lock records
        |-- write undo
        +-- write redo in mtr
     -> prepare
        -> write binlog
           -> commit
              -> release locks

事务模块与 undo、redo、锁和 purge 紧耦合,需要整体阅读。

12.5 后台线程

线程 职责
master thread 统筹后台任务
purge thread 清理 delete-mark 和 undo
page cleaner 刷脏页
read ahead / IO thread 异步 IO
log flusher / writer redo 日志刷盘
dict stats 统计收集

12.6 观测入口

SHOW ENGINE INNODB STATUS;
SELECT * FROM information_schema.innodb_trx;
SELECT * FROM information_schema.innodb_buffer_page_lru LIMIT 10;
SHOW GLOBAL STATUS LIKE 'Innodb_%';

源码定位:

rg "Innodb_buffer_pool_read_requests" storage/innobase
rg "row_lock_current_waits" storage/innobase

本章小结

InnoDB 可以按存储结构、行操作、事务并发、日志恢复和后台线程五条线阅读。先建立模块地图,再沿一条 SQL 的读写路径进入源码,能显著降低复杂度。

思考题

  1. 聚簇索引和二级索引的存储关系是什么?
  2. InnoDB 哪些模块参与一次 UPDATE?
  3. purge thread 清理什么数据?
  4. 如何从 InnoDB 状态变量定位源码?
  5. 为什么事务模块要与 undo、redo、lock 一起读?