这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 MySQL 8.0 可以分为 Server 层、存储引擎层、插件、复制和工具链。理解模块边界比记住函数细节更重要。
4.1 分层
Client
-> Protocol / Connection
-> Server SQL Layer
|-- Parser
|-- Resolver / Transformer
|-- Optimizer
|-- Executor
|-- Metadata Lock
|-- Query Cache removed in 8.0
+-- Binlog
-> handler API
-> InnoDB / MyISAM / CSV / engines
4.2 Server 层模块
| 模块 | 目录线索 | 职责 |
|---|---|---|
| Connection | sql/conn_handler/ |
连接和线程管理 |
| Protocol | sql/protocol* |
客户端协议 |
| Parser | sql/sql_yacc.yy |
语法解析 |
| Resolver | sql/sql_resolver.cc |
表列解析和改写 |
| Optimizer | sql/sql_optimizer.cc |
计划选择 |
| Executor | sql/sql_executor.cc |
迭代执行 |
| Item | sql/item* |
表达式和函数 |
| Field | sql/field* |
字段类型 |
| Table | sql/table* |
表定义和缓存 |
| Lock | sql/lock.cc |
元数据锁 |
| Session | sql/sql_class* |
THD 上下文 |
4.3 InnoDB 模块
| 前缀 | 职责 |
|---|---|
btr |
B+Tree 查找、插入、分裂 |
page |
页头、记录、目录 |
rem |
记录格式 |
row |
行级读写和更新 |
buf |
Buffer Pool 和页面淘汰 |
ibuf |
Change Buffer |
lock |
行锁和表锁 |
trx |
事务状态 |
undo |
回滚段和 undo 日志 |
log |
redo log |
mtr |
mini transaction |
fil |
文件和表空间 |
dict |
数据字典缓存 |
purge |
undo 清理 |
row0mysql |
handler 到行操作的桥 |
4.4 关键接口
handler 是 Server 调用引擎的核心接口:
handler::ha_open
handler::ha_index_init
handler::ha_index_read
handler::ha_rnd_next
handler::ha_write_row
handler::ha_update_row
handler::ha_delete_row
handler::ha_external_lock
InnoDB 侧入口常见于 ha_innobase:
ha_innobase::index_read
ha_innobase::general_fetch
ha_innobase::write_row
ha_innobase::update_row
ha_innobase::delete_row
4.5 事务边界
BEGIN / first statement
-> transaction begin
-> InnoDB trx assigned
-> row changes
-> undo
-> redo
-> XA prepare
-> binlog write
-> engine commit
相关模块:
sql/transaction.ccsql/rpl_binlog_sender.ccstorage/innobase/trx/storage/innobase/log/storage/innobase/undo/
4.6 元数据
MySQL 8.0 使用事务性数据字典,取代 5.7 的 .frm 文件。
| 组件 | 职责 |
|---|---|
| DD tables | MySQL 系统表存储元数据 |
dd::Table |
表定义对象 |
| Dictionary Client | Server 层访问接口 |
| InnoDB dict cache | 引擎层缓存 |
| MDL | 元数据并发控制 |
这使许多 DDL 具备原子性,但仍要区分算法和锁模式。
4.7 复制模块
| 模块 | 职责 |
|---|---|
| Binlog | 记录逻辑变更 |
| Dump thread | 主库发送 binlog |
| IO thread | 从库接收 relay log |
| SQL thread / applier | 重放事务 |
| GTID | 事务标识和幂等 |
| MGR | 组复制一致性协议 |
源码目录包括 sql/rpl_*、libbinlogevents/、plugin/group_replication/。
4.8 观测接口与源码关系
| 观测 | 源码入口 |
|---|---|
| processlist | THD |
| performance_schema stages | stage instrumentation |
| waits | instrument classes |
| innodb_trx | trx_t |
| innodb_locks / data_locks | lock system |
| optimizer trace | optimizer candidates |
| show status | status variables |
定位方式:
rg "Innodb_data_reads" storage/innobase
rg "stage/executing" sql
rg "row_lock_waits" storage/innobase
4.9 插件体系
常见插件:
- 存储引擎;
- 全文索引插件;
- 认证插件;
- 审计插件;
- daemon 插件;
- clone 插件;
- group replication;
- 半同步复制。
插件通过 MySQL 插件 API 注册,但仍要尊重 Server 层锁和事务语义。
4.10 学习地图
第一层:SQL 层一条语句路径
第二层:handler 与 InnoDB 行操作
第三层:Page / B+Tree / Buffer Pool
第四层:trx / lock / undo / redo
第五层:binlog / replication / recovery
第六层:后台线程与性能诊断
本章小结
MySQL 8.0 的核心边界是 Server 层与存储引擎层。Server 负责协议、解析、优化、执行、元数据和 Binlog;InnoDB 负责页面、行、事务、锁、MVCC、日志和恢复。按模块地图推进,可以避免在庞大源码中迷失。
思考题
handler接口为什么重要?- MySQL 8.0 数据字典与 5.7 有什么关键差异?
- 一条 UPDATE 涉及哪些 Server 和 InnoDB 模块?
- 如何从状态变量定位源码位置?
- InnoDB 模块推荐阅读顺序是什么?