IE盒子

搜索
查看: 102|回复: 7

我是如何开始阅读MySQL源码的?

[复制链接]

2

主题

4

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2022-12-9 02:31:38 | 显示全部楼层 |阅读模式
1. 为什么要阅读MySQL源码?

之前已经看过 高性能MySQL 和 MySQL技术内幕InnoDB存储引擎, 但总觉得只是看看书上这么说还是不够.
比如 高性能MySQL 里画的有B-Tree索引的示意图,可是B-Tree索引究竟长什么样子,在MySQL里是怎么存储的,没什么概念; 里边还提到关联查询的”泳道图”,在代码层面到底是怎么执行的,也不清楚.
2. 从哪儿开始?

直接看MySQL的源码有点困难.
好在有一本讲MySQL的书, 叫 Understanding.MySQL.Internals, 书虽然有点老,但看起来是个不错的开始.
大概过一下书的内容,发现大部分内容还是看不下去. 只有第4章 Client/Server Communication 还能看.
3. Protocol

Understanding.MySQL.Internals 的第4章 Client/Server Communication 讲了MySQL Server和客户端沟通的协议, 结合着wireshark, 很快就能搞明白.
http://heguangyu5.github.io/mysql/1-protocol.html
4. main() -> mysqld_main()

MySQL是由C++写的,入口函数main()直接调用了mysqld_main().
Server启动的代码都在这里,大部分都看不懂.
直到最后的 handle_connections_sockets().
5. handle_connections_sockets()

读过UNP的看这部分代码应该都没问题.
poll()
accept()
thread_scheduler->add_connection()
pthread_create() or thead_cache
handle_one_connection()
for (;;) {
    while (connection_alive()) {
        do_command();
    }
    cache_thread();
}
do_command() -> dispatch_command()
http://heguangyu5.github.io/mysql/2-handle-connections-sockets.html
6. dispatch_command()

这里已经能够看到很多熟悉的词语了,CHANGE_USER,STMT_EXECUTE,STMT_FETCH.
不过最关键的执行SQL语句的部分, COM_QUERY, 看不懂.
mysql_parse() -> MYSQLparse()
Understanding.MySQL.Internals 的第9章 Parser and Optimizer, 是讲这部分的.
在Parse Tree部分有提到SQL语句最终在 mysql_execute_command() 里执行.
http://heguangyu5.github.io/mysql/3-dispatch-command.html
7. mysql_execute_command()

case SQLCOM_CREATE_DB:      mysql_create_db();
case SQLCOM_CREATE_TABLE:   mysql_create_table();
case SQLCOM_INSERT:         mysql_insert();
case SQLCOM_SELECT:         execute_sqlcom_select();mysql_create_db()好理解.
mysql_create_table()里有创建一个.frm文件,要是有文档说明下.frm文件的格式就好了.
于是就找到了这个 https://dev.mysql.com/doc/internals/en/fileformats.html
从这往篇文档可以看出, MySQL的历史真的太久了,官方文档对很多字段的说明都是always, ??.
看了这个文档还是搞不明白.frm文件的格式.
http://heguangyu5.github.io/mysql/4-mysql-execute-command.html
8. .MYD and .MYI

由于之前看过InnoDB技术内幕,显然InnoDB比MyISAM要复杂多了.
MySQL Internals Manual 里边有一章讲MyISAM的,仔细分析了.MYD和.MYI文件的格式,讲的挺清楚的.
.MYD的文件格式挺简单的.
.MYI的就复杂很多了. 对着文档写个小程序读取并解析.MYI文件,有很大帮助.
http://heguangyu5.github.io/mysql/5-MyISAM.html
https://github.com/heguangyu5/heguangyu5.github.io/blob/master/mysql/read-MYI.c


搞清楚了.MYD和.MYI的文件格式,很多名词术语也混个脸儿熟了.
回过头来再看.frm.
9. .frm

创建.frm文件的代码在 mysql_create_frm() 里.
努力一番后,再写个小程序读取并解析下.frm文件,总算搞清楚其格式了.
http://heguangyu5.github.io/mysql/6-frm.html
https://github.com/heguangyu5/heguangyu5.github.io/blob/master/mysql/read-frm.c




在创建完.frm后,又调用了Storage Engine的ha_create()方法创建了其它相关的文件,比如MyISAM就创建了.MYD和.MYI文件.
10. plugin_init, mysql_insert, execute_sqlcom_select

这个时间回过头来再看下启动代码里的plugin_init部分,还是相对容易的搞清楚了Stroage Engine是怎么加载的了.
自己编译一个debug版本的mysqld会有一些帮助.
mysql_insert()还是比较简单的.
execute_sqlcom_select()就复杂了.
结合着Understanding.MySQL.Internals 的第9章 Parser and Optimizer, 总算看到”泳道图”是怎么执行的了.


11. 下一步

OK, 万事开头难. 到此也算是开了个头了.
缓一缓后边再看下这个 23 Writing a Custom Storage Engine
回复

使用道具 举报

0

主题

8

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-12-9 02:32:13 | 显示全部楼层
祝你旅途愉快
回复

使用道具 举报

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2022-12-9 02:33:12 | 显示全部楼层
最后一张图是什么工具,gdb吗?
回复

使用道具 举报

0

主题

10

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-12-9 02:34:05 | 显示全部楼层
Nemiver Apps/Nemiver - GNOME Wiki!
回复

使用道具 举报

2

主题

7

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2022-12-9 02:34:15 | 显示全部楼层
厉害,带带我
回复

使用道具 举报

3

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2022-12-9 02:34:54 | 显示全部楼层
github上面下载下来的mysql-server源码很大,用vs打开文件夹半天了还在建立索引中
回复

使用道具 举报

1

主题

4

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2022-12-9 02:35:34 | 显示全部楼层
我看源码用的是lxr https://lxr.sourceforge.io/en/index.php
回复

使用道具 举报

3

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2022-12-9 02:35:48 | 显示全部楼层
关于存储引擎接口,一路找下来只有官方手册能看,但写的也不清晰[为难]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表