8
8
本次 TiDB 源码之旅从这幅简单的架构图开始,这幅图很多人都看过,我们可以用一句话来描述这个图:『TiDB 是一个支持 MySQL 协议,以某种支持事务的分布式 KV 存储引擎为底层存储的 SQL 引擎』。从这句话可以看出有三个重要的事情,第一是如何支持 MySQL 协议,与 Client 交互,第二是如何与底层的存储引擎打交道,存取数据,第三是如何实现 SQL 的功能。本篇文章会先介绍一些 TiDB 有哪些模块及其功能简要介绍,然后以这三点为线索,将这些模块串联起来。
9
9
10
10
## 代码简介
11
- TiDB 源码完全托管在 Github 上,从[ 项目主页] ( https://github.com/pingcap/tidb " 项目主页 ") 可以看到所有信息。整个项目使用 Go 语言开发,按照功能模块分了很多 Package,通过一些依赖分析工具,可以看到项目内部包之间的依赖关系。
12
- 大部分包都以接口的形式对外提供服务,大部分功能也都集中在某个包中,不过有一些包提供了非常基础的功能,会被很多包依赖,这些包需要特别注意。
13
- 项目的 main 文件在 tidb-server/main.go,这里面定义了服务如何启动。整个项目的 Build 方法可以在 [ Makefile] ( https://github.com/pingcap/tidb/blob/source-code/Makefile#L140 ) 中找到。
14
- 除了代码之外,还有很多测试用例,可以在 xx\_ test.go 中找到。另外 ` cmd ` 目录下面还有几个工具包,用来做性能测试或者是构造测试数据。
11
+ TiDB 源码完全托管在 Github 上,从[ 项目主页] ( https://github.com/pingcap/tidb " 项目主页 ") 可以看到所有信息。整个项目使用 Go 语言开发,按照功能模块分了很多 Package,通过一些依赖分析工具,可以看到项目内部包之间的依赖关系。
12
+ 大部分包都以接口的形式对外提供服务,大部分功能也都集中在某个包中,不过有一些包提供了非常基础的功能,会被很多包依赖,这些包需要特别注意。
13
+ 项目的 main 文件在 tidb-server/main.go,这里面定义了服务如何启动。整个项目的 Build 方法可以在 [ Makefile] ( https://github.com/pingcap/tidb/blob/source-code/Makefile#L140 ) 中找到。
14
+ 除了代码之外,还有很多测试用例,可以在 xx\_ test.go 中找到。另外 ` cmd ` 目录下面还有几个工具包,用来做性能测试或者是构造测试数据。
15
15
16
16
## 模块介绍
17
17
TiDB 的模块非常多,这里做一个整体介绍,大家可以看到每个模块大致是做什么用的,想看相关功能的代码是,可以直接找到对应的模块。
18
+
18
19
| Package | Introduction |
19
20
| ------------- | :-------------: |
20
21
| ast | 抽象语法树的数据结构定义,例如 ` SelectStmt ` 定义了一条 Select 语句被解析成什么样的数据结构 |
@@ -78,8 +79,10 @@ TiDB 的模块非常多,这里做一个整体介绍,大家可以看到每个
78
79
粗看一下 TiDB 有 80 个包,让人觉得无从下手,不过并不是所有的包都很重要,另外一些功能只会涉及到少量包,从哪里入手去看源码取决于看源码的目的。
79
80
如果是想了解某一个具体的功能的实现细节,那么可以参考上面的模块简介,找到对应的模块即可。
80
81
如果是相对源码有全面的了解,那么可以从 tidb-server/main.go 入手,看 tidb-server 是如何启动,如何等待并处理用户请求。再跟着代码一直走,看 SQL 的具体执行过程。另外一些重要的模块,需要看一下,知道是如何实现的。辅助性的模块,可以选择性的看一下,有大致的印象即可。
82
+
81
83
## 重要模块
82
84
在全部 80 个模块中,下面几个模块是最重要的,希望大家能仔细阅读,针对这些模块,我们也会用专门的文章来讲解,等所有的文章都 Ready 后,我将下面的表格中的 TODO 换成对应的文章连链接。
85
+
83
86
| Package | Related Articles |
84
87
| ------------- | ------------- |
85
88
| plan | TODO |
@@ -102,16 +105,18 @@ TiDB 的模块非常多,这里做一个整体介绍,大家可以看到每个
102
105
这幅图比上一幅图详细很多,大体描述了 SQL 核心模块,大家可以从左边开始,顺着箭头的方向看。
103
106
104
107
### Protocol Layer
105
- 最左边是 TiDB 的 Protocol Layer,这里是与 Client 交互的接口,目前 TiDB 只支持 MySQL 协议,相关的代码都在 ` server ` 包中。
108
+ 最左边是 TiDB 的 Protocol Layer,这里是与 Client 交互的接口,目前 TiDB 只支持 MySQL 协议,相关的代码都在 ` server ` 包中。
106
109
这一层的主要功能是管理客户端 connection,解析 MySQL 命令并返回执行结果。具体的实现是按照 MySQL 协议实现,具体的协议可以参考 [ MySQL 协议文档] ( https://dev.mysql.com/doc/internals/en/client-server-protocol.html ) 。这个模块我们认为是当前实现最好的一个 MySQL 协议组件,如果大家的项目中需要用到 MySQL 协议解析、处理的功能,可以参考或引用这个模块。
107
110
108
- 连接建立的逻辑在 server.go 的 [ Run()] ( https://github.com/pingcap/tidb/blob/source-code/server/server.go#L236 ) 方法中,主要是下面两行:
109
- 236: conn, err := s.listener.Accept()
110
- 258: go s.onConn(conn)
111
+ 连接建立的逻辑在 server.go 的 [ Run()] ( https://github.com/pingcap/tidb/blob/source-code/server/server.go#L236 ) 方法中,主要是下面两行:
112
+ > 236: conn, err := s.listener.Accept()
113
+ > 258: go s.onConn(conn)
114
+
111
115
单个 Session 处理命令的入口方法是调用 clientConn 类的 [ dispatch 方法] ( https://github.com/pingcap/tidb/blob/source-code/server/conn.go#L465 ) ,这里会解析协议并转给不同的处理函数。
112
116
113
117
### SQL Layer
114
118
大体上讲,一条 SQL 语句需要经过,语法解析--\> 合法性验证--\> 制定查询计划--\> 优化查询计划--\> 根据计划生成查询器--\> 执行并返回结果 等一系列流程。这个主干对应于 TiDB 的下列包:
119
+
115
120
| Package | 作用 |
116
121
| ------------- | ------------- |
117
122
| tidb | Protocol 层和 SQL 层之间的接口|
@@ -122,16 +127,17 @@ TiDB 的模块非常多,这里做一个整体介绍,大家可以看到每个
122
127
| store/tikv | TiKV Client |
123
128
124
129
### KV API Layer
125
- TiDB 依赖于底层的存储引擎提供数据的存取功能,但是并不是依赖于特定的存储引擎(比如 TiKV),而是对存储引擎提出一些要求,满足这些要求的引擎都能使用(其中 TiKV 是最合适的一款)。
126
- 最基本的要求是『带事务的 Key-Value 引擎,且提供 Go 语言的 Driver』,再高级一点的要求是『支持分布式计算接口』,这样 TiDB 可以把一些计算请求下推到 存储引擎上进行。
127
- 这些要求都可以在 ` kv ` 这个包的[ 接口] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go ) 中找到,存储引擎需要提供实现了这些接口的 Go 语言 Driver,然后 TiDB 利用这些接口操作底层数据。
130
+ TiDB 依赖于底层的存储引擎提供数据的存取功能,但是并不是依赖于特定的存储引擎(比如 TiKV),而是对存储引擎提出一些要求,满足这些要求的引擎都能使用(其中 TiKV 是最合适的一款)。
131
+ 最基本的要求是『带事务的 Key-Value 引擎,且提供 Go 语言的 Driver』,再高级一点的要求是『支持分布式计算接口』,这样 TiDB 可以把一些计算请求下推到 存储引擎上进行。
132
+ 这些要求都可以在 ` kv ` 这个包的[ 接口] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go ) 中找到,存储引擎需要提供实现了这些接口的 Go 语言 Driver,然后 TiDB 利用这些接口操作底层数据。
128
133
对于最基本的要求,可以重点看这几个接口:
129
134
* [ Transaction] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L121 ) :事务基本操作
130
135
* [ Retriever ] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L75 ) :读取数据的接口
131
136
* [ Mutator] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L91 ) :修改数据的接口
132
137
* [ Storage] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L229 ) :Driver 提供的基本功能
133
138
* [ Snapshot] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L214 ) :在数据 Snapshot 上面的操作
134
139
* [ Iterator] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L255 ) :` Seek ` 返回的结果,可以用于遍历数据
140
+
135
141
有了上面这些接口,可以对数据做各种所需要的操作,完成全部 SQL 功能,但是为了更高效的进行运算,我们还定义了一个高级计算接口,可以关注这三个 Interfce/struct :
136
142
* [ Client] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L150 ) :向下层发送请求以及获取下层存储引擎的计算能力
137
143
* [ Request] ( https://github.com/pingcap/tidb/blob/source-code/kv/kv.go#L176 ) : 请求的内容
0 commit comments