mysql 源码分析
MySQL 源码分析可以从服务器架构 → SQL执行流程 → 存储引擎(InnoDB) → 事务系统 → 索引 → 日志恢复 → 网络层几个层次深入。MySQL 是一个大型 C/C++ 工程,核心代码主要在 sql/ 和 storage/innobase/。官方源码仓库为 mysql/mysql-server。(GitHub)
下面按源码阅读路线分析。
1. MySQL 整体源码架构
源码目录:
mysql-server/
│
├── sql/ # MySQL Server核心
│ ├── mysqld.cc # 服务启动入口
│ ├── sql_parse.cc # SQL解析
│ ├── sql_yacc.yy # SQL语法规则
│ ├── sql_optimizer.cc # 优化器
│ ├── sql_executor.cc # 执行器
│ ├── handler.cc # 存储引擎接口
│ ├── item*.cc # SQL表达式
│ └── table*.cc # 表管理
│
├── storage/
│ ├── innobase/ # InnoDB源码
│ │ ├── buf/ # Buffer Pool
│ │ ├── btr/ # B+Tree索引
│ │ ├── trx/ # 事务
│ │ ├── row/ # 行操作
│ │ ├── log/ # redo日志
│ │ ├── lock/ # 锁
│ │ └── dict/ # 数据字典
│ │
│ ├── myisam/
│ └── ndb/
│
├── client/ # mysql客户端
├── include/ # 公共头文件
├── unittest/
└── cmake/
MySQL 使用插件式存储引擎架构,SQL层和存储层通过 Handler 接口连接。(MySQL开发者区)
2. MySQL 启动流程源码
入口:
sql/mysqld.cc
主要函数:
main()
|
|-- mysqld_main()
|
|-- init_server_components()
|
|-- plugin_init()
|
|-- network_init()
|
|-- start_signal_handler()
|
|-- server_loop()
启动后进入:
while(true)
{
accept connection
create THD
handle client request
}
3. 客户端连接源码分析
客户端:
mysql client
|
|
TCP/IP
|
v
mysqld
核心:
sql/sql_connect.cc
连接对象:
class THD
{
MYSQL_THREAD_ID thread_id;
MEM_ROOT mem_root;
Query_arena;
Security_context;
};
每一个连接对应一个:
Client
|
|
THD对象
|
|
SQL执行上下文
4. 一条SQL执行流程
例如:
select * from user where id=10;
执行路径:
客户端
|
|
MYSQL协议
|
v
mysqld
|
|
创建THD
|
|
SQL Parser
|
|
语法树 AST
|
|
Optimizer
|
|
执行计划
|
|
Executor
|
|
Handler接口
|
|
InnoDB
|
|
Buffer Pool
|
|
磁盘
5. SQL解析源码
位置:
sql/sql_parse.cc
入口:
mysql_parse()
流程:
mysql_parse()
|
|
+-- parse_sql()
|
|
sql_yacc.yy
|
|
AST
例如:
SQL:
select name from user;
生成:
SELECT_LEX
|
+-- Item_field(name)
|
+-- TABLE_LIST(user)
6. 查询优化器
源码:
sql/sql_optimizer.cc
作用:
把:
SQL
|
v
多个执行方案
|
v
选择成本最低方案
例如:
表:
user
id
name
age
SQL:
select *
from user
where id=100;
优化器比较:
方案1:
全表扫描
cost=100000
方案2:
B+Tree索引
cost=5
选择:
Index Lookup
7. 执行器
源码:
sql/sql_executor.cc
核心:
execute_sqlcom_select()
执行:
Iterator模型
例如:
TableScanIterator
|
|
IndexScanIterator
|
|
FilterIterator
|
|
ProjectionIterator
8. Handler层(非常重要)
文件:
sql/handler.cc
SQL层不知道:
数据怎么存。
只调用:
handler->ha_read_row()
例如:
SQL层
|
|
Handler API
|
|
InnoDB
|
|
Page
所以:
MyISAM:
handler
|
myisam
InnoDB:
handler
|
innodb
9. InnoDB源码结构
InnoDB 是 MySQL 最核心部分。(MySQL开发者区)
目录:
storage/innobase/
buf/
Buffer Pool
btr/
B+Tree
row/
行记录
trx/
事务
lock/
锁
log/
redo日志
dict/
数据字典
10. InnoDB 查询流程
查询:
select *
from user
where id=10;
流程:
Handler
|
|
ha_index_read()
|
|
B+Tree
|
|
Root Page
|
|
Intermediate Page
|
|
Leaf Page
|
|
Record
结构:
Root
|
--------------
| |
Node Node
|
Leaf
|
Row
11. Buffer Pool源码
目录:
storage/innobase/buf/
作用:
缓存磁盘页:
Disk Page
|
|
Buffer Pool
|
|
CPU
结构:
Buffer Pool
+----------------+
| Page Frame |
| |
| Page Header |
| Data |
+----------------+
主要:
buf0buf.cc
buf0lru.cc
12. InnoDB B+Tree源码
目录:
storage/innobase/btr/
核心:
btr0btr.cc
btr0cur.cc
索引:
Primary Key
Root
|
Branch Node
|
Leaf
|
Row Data
13. 事务系统
目录:
storage/innobase/trx/
核心:
trx0trx.cc
事务:
trx_t
{
id;
state;
undo;
locks;
};
支持:
- ACID
- MVCC
- 回滚
14. Undo / MVCC
例如:
事务A:
update user
set name='Tom'
where id=1;
InnoDB:
不会直接覆盖。
保存:
当前数据
Tom
undo log
Jerry
其他事务:
看到:
Read View
|
|
undo chain
15. Redo日志
目录:
storage/innobase/log/
目的:
崩溃恢复。
写:
修改数据
|
|
redo log
|
|
commit
|
|
刷磁盘
恢复:
Crash
|
|
redo replay
|
|
数据库恢复
16. 一次INSERT完整路径
SQL:
insert into user values(1,'Tom');
源码逻辑:
mysql_execute_command()
|
write_record()
|
handler::ha_write_row()
|
ha_innobase::write_row()
|
row_insert_for_mysql()
|
btr_insert()
|
modify page
|
write redo
|
commit
17. 推荐源码阅读顺序
不要直接读 InnoDB。
建议:
第一阶段:服务器框架
阅读:
mysqld.cc
THD
sql_parse.cc
handler.cc
理解:
连接
SQL
执行
第二阶段:SQL执行
阅读:
sql_yacc.yy
sql_optimizer.cc
sql_executor.cc
理解:
SQL如何变成机器执行
第三阶段:InnoDB
顺序:
1. handler/
2. buf/
3. btr/
4. row/
5. trx/
6. lock/
7. log/
18. 如果你有 C++ / CPU / Linux 内核基础,MySQL重点看:
| 模块 | 类似Linux |
|---|---|
| THD | 进程控制块PCB |
| Buffer Pool | 页缓存 |
| Redo Log | 内核日志 |
| B+Tree | 文件系统索引 |
| 事务 | 内核同步机制 |
| Lock | 并发控制 |
如果目标是深入源码级掌握 MySQL,建议下一步分析:
- mysqld 启动源码调用链(main→mysqld_main)
- 一条 SELECT 从客户端到磁盘完整源码跟踪
- InnoDB B+Tree源码分析
- InnoDB事务/MVCC源码分析
- 自己实现一个 mini-mysql(C++)
这几个方向和你之前研究 Linux内核、CPU、O3DE源码架构 的路线非常接近。