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/
  数据字典

(MySQL Planet)


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,建议下一步分析:

  1. mysqld 启动源码调用链(main→mysqld_main)
  2. 一条 SELECT 从客户端到磁盘完整源码跟踪
  3. InnoDB B+Tree源码分析
  4. InnoDB事务/MVCC源码分析
  5. 自己实现一个 mini-mysql(C++)

这几个方向和你之前研究 Linux内核、CPU、O3DE源码架构 的路线非常接近。

类似文章