Skip to content

Commit

Permalink
replace images in blog-cn (part 4) (pingcap#197)
Browse files Browse the repository at this point in the history
* replace images in tidb-jepsen

* replace images in tidb-meets-spark

* replace images in tidb-operator-introduction

* replace images in tidb-optimization-for-subquery

* replace images in tidb-source-code-reading-2

* replace images in tidb-source-code-reading-3

* replace image in tidb-source-code-reading-4

* replace images in tidb-source-code-reading-5

* replace images in tidb-source-code-reading-6

* replace image in tidb-source-code-reading-7
  • Loading branch information
siyu-hu authored and YiniXu9506 committed Apr 2, 2019
1 parent b1906f9 commit c6f1d16
Show file tree
Hide file tree
Showing 41 changed files with 31 additions and 31 deletions.
Binary file added media/tidb-jepsen/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-jepsen/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-jepsen/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-jepsen/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-jepsen/5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-meets-spark/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-meets-spark/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-meets-spark/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-meets-spark/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-operator-introduction/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-operator-introduction/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-optimization-for-subquery/9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-2/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-2/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-3/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-3/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-4/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/tidb-source-code-reading-5/1.png
Binary file added media/tidb-source-code-reading-5/2.png
Binary file added media/tidb-source-code-reading-6/1.png
Binary file added media/tidb-source-code-reading-6/2.jpg
Binary file added media/tidb-source-code-reading-6/3.png
Binary file added media/tidb-source-code-reading-7/1.png
10 changes: 5 additions & 5 deletions tidb-jepsen.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Jepsen 验证系统由 6 个节点组成,一个控制节点(control node)

Checker 用于对测试生成的历史进行验证,判断测试结果是否符合预期,历史的格式如下图所示:

![](https://static.zybuluo.com/zyytop/hmc5dbcl7p5jv0qaaaozm7g3/bank.png)
![](media/tidb-jepsen/1.png)

+ **Nemesis**

Expand All @@ -43,7 +43,7 @@ Jepsen 验证系统由 6 个节点组成,一个控制节点(control node)

下图展示了 parts nemesis 引入测试中后某些语句执行时出现了 time-out 的错误。

![](https://static.zybuluo.com/zyytop/pt7oc0dau02iayxlt6tz52mn/parts.png)
![](media/tidb-jepsen/2.png)

+ **Generator**

Expand Down Expand Up @@ -79,7 +79,7 @@ TiDB 中的 Jepsen 测试有 3 个,分别是 bank、set 和 register 测试。

下面是测试进行中的某次截图:

![](https://static.zybuluo.com/zyytop/dljzfx54t3s17yrdf61z3805/bank2.png)
![](media/tidb-jepsen/3.png)

在快照隔离下,所有的转账都必须保证每一时刻所有账户的总金额是相同的。TiDB 在即使引入了各种 nemesis 的情况下仍旧顺利地通过了测试。

Expand All @@ -89,15 +89,15 @@ TiDB 中的 Jepsen 测试有 3 个,分别是 bank、set 和 register 测试。

下面是测试进行中的某次截图:

![](https://static.zybuluo.com/zyytop/tjzrb4ru9nr6l7g99fvj21j4/sets.png)
![](media/tidb-jepsen/4.png)

同样,TiDB 通过了测试。

#### Register Test

这个测试很好理解,建一个表,然后插入一条值,然后我们把这个值看做是一个寄存器,然后在测试中并发地从各个节点对其进行 read、write 和 cas 操作。

![](https://static.zybuluo.com/zyytop/gonzbaekpqfkhnhfg1vw2mwq/register.png)
![](media/tidb-jepsen/5.png)

然后利用 Jepsen 产生的一系列操作历史(如上图)进行 Linearizability 一致性验证。这个算法是 Jepsen 的核心,也是 Jepsen 被业界所熟知的原因之一,所以花时间去深入学习了下,我会在另一篇文章具体介绍这个算法。

Expand Down
8 changes: 4 additions & 4 deletions tidb-meets-spark.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ tags: ['TiDB', 'TiSpark', 'Spark']

然后什么是 TiKV,可能我们今天要说很多次了。TiKV 其实是 TiDB 这个产品底下的数据库存储引擎,更形象,更具体一点,这是一个架构图。

![](https://static.zybuluo.com/zyytop/7wgvtdo71rs6h5i0o9zuuw1y/%E6%9E%B6%E6%9E%84%E5%9B%BE.png)
![](media/tidb-meets-spark/1.png)

大家可以看到,TiDB 做为一个完整的数据库来说,它是这样的一个架构,上层是 DB 层,DB 层是负责做 DB 相关的东西,比如说一部分的 Transaction,SQL 的解析,然后执行 Query Processing 相关的一些东西。

Expand All @@ -37,7 +37,7 @@ CBO 这里有两部分,一部分是说,因为我们有索引,所以在这

现在开始说一下整个架构是什么样的。后面会有一个具体的解说,先看一下架构图。

![](https://static.zybuluo.com/zyytop/qy1de5t3z0hds4g3x17zheo0/%E5%9B%BE%E7%89%87%201.png)
![](media/tidb-meets-spark/2.png)

在 Spark Driver 上,需要接入 TiSpark 的接口,现在 TiSpark 也支持 JDBC。Worker / Executor 那边也需要一个这样的架构。 整个部署,采用 Spark 外接 JAR 的方式,并没有说需要到我整个把 Spark 部署全都换掉属于我们的版本,只需要提交一个 JAR 包就可以。每个 TiSpark 组件会与 TiKV 进行通讯,Driver 这边会和 Placement Driver 进行通讯,然后这边具体干了什么,后面会解释。

Expand All @@ -63,7 +63,7 @@ CBO 这里有两部分,一部分是说,因为我们有索引,所以在这

刚才说的有几种可能比较抽象,现在来一个具体的例子,具体看这个东西怎么 Work,可以看一个具体的例子。

![](https://static.zybuluo.com/zyytop/047uw1uxxjavorh23zqs1604/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202017-08-29%20%E4%B8%8B%E5%8D%884.31.50.png)
![](media/tidb-meets-spark/3.png)

这是一个查询,根据所给的学号和学院等条件计算学生平均值。这张表上,有两个索引,一个索引是主键索引,另外一个索引是在 Secondary Index ,建立在 School 上。lottery 是一个用户自定义函数,并不在 TiDB 和 TiKV 的支持范围之内。

Expand All @@ -86,7 +86,7 @@ TiDB 本身是有收集统计信息的, TiSpark 现在正在实现统计信息

还是刚才的 SQL 查询:

![](https://static.zybuluo.com/zyytop/z2xmfso7q9yhp0rmlmvt0zk0/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202017-08-29%20%E4%B8%8B%E5%8D%884.33.24.png)
![](media/tidb-meets-spark/4.png)

这个例子稍微有一点特殊,因为他是计算平均值,为什么特殊,因为没有办法直接在 TiKV 做 AVG 平均值计算,然后直接在 Spark 再做直接聚合计算,因此这种情况会有一个改写,将 AVG 拆解成 SUM 和 COUNT,然后会把他们分别下推到 Coprocessor,最后在 Spark 继续做聚合计算。

Expand Down
4 changes: 2 additions & 2 deletions tidb-operator-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ TiDB 作为一个开源的分布式数据库产品,具有多副本强一致性

上面的这三个组件,每个角色都是一个多节点组成的集群,所以最终 TiDB 的架构看起来是这样的。

![TiDB-架构.png](https://upload-images.jianshu.io/upload_images/542677-07e435ea2eeaa00c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![TiDB-架构.png](media/tidb-operator-introduction/1.png)

Kubernetes 最早是作为一个纯粹的容器编排系统而诞生的,用户部署好 Kubernetes 集群之后,直接使用其内置的各种功能部署应用服务。 

Expand Down Expand Up @@ -57,7 +57,7 @@ Kubernetes 直到 v1.7 才试验性引入本地 PV,在这之前只有网络 PV

Operator 本质上是 Kubernetes 的控制器(Controller),其核心思想是用户给定一个 Spec 描述文件,Controller 根据 Spec 的变化,在 Kubernetes 集群中创建对应资源,并且不断调整资源使其状态满足用户预期的 Spec。

![TiDB-Operator.png](https://upload-images.jianshu.io/upload_images/542677-bc69ec093f27ad80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![TiDB-Operator.png](media/tidb-operator-introduction/2.png)


上图是 TiDB Operator 工作流程原理图,其中 TidbCluster 是通过 CRD(Custom Resource Definition)扩展的内置资源类型:
Expand Down
18 changes: 9 additions & 9 deletions tidb-optimization-for-subquery.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TiDB 沿袭了 SQL Server 对子查询的处理思想,引入 Apply 算子将

Apply 算子的语义是:

![](https://static.zybuluo.com/zyytop/d33ip11f4i69dbosfxdsir1m/1.png)
![](media/tidb-optimization-for-subquery/1.png)

公式中的 E 代表一个“参数化”的子查询。在每一次执行中,Apply 算子会向关系 R 取一条记录 r,作为参数传入 E 中,然后让 r 和 E(r) 做 ⊗ 操作。⊗ 会根据子查询类型的不同而不同,通常是半连接 ⋉。

Expand All @@ -50,15 +50,15 @@ EXISTS(SELECT * FROM TMP WHERE TMP.id = SRC.id)
```
它的 Apply 算子表示是:

![](https://static.zybuluo.com/zyytop/j3bd2utrbeqeaw4hr43ydpxd/2.png)
![](media/tidb-optimization-for-subquery/2.png)

对于出现在 `SELECT` 列表中、`GROUP BY` 列表中的子查询,道理也是类似的。所以 Apply 是可以表示出现在任意位置的子查询的。

## 去关联化

引入了 Apply,我们就可以将子查询去关联化了。去关联化的规则如下:

![](https://static.zybuluo.com/zyytop/4ehtrm40su82a1zfr35k8cq2/3.png)
![](media/tidb-optimization-for-subquery/3.png)

根据上述规则,你可以将所有的确定性 SQL 子查询去关联化。例如 SQL 语句:

Expand All @@ -71,19 +71,19 @@ FROM ORDER WHERE O_CUSTKEY = C_CUSTKEY)

其中两个 `CUSTKEY` 均为主键。转换成 Apply 之后的表达式为:

![](https://static.zybuluo.com/zyytop/y6o28jwzzn1dnnx4sbfa3q8j/4.png)
![](media/tidb-optimization-for-subquery/4.png)

因为主键的存在,利用规则(9),可以转化为:

![](https://static.zybuluo.com/zyytop/nhwbswuiwwybhdj2qj8r90i6/5.png)
![](media/tidb-optimization-for-subquery/5.png)

此时根据规则(2),我们可以彻底消除 Apply,转化为只有连接的 SQL 表达式:

![](https://static.zybuluo.com/zyytop/dtwp9s0xcqzfn8qf9zzi6sn1/6.png)
![](media/tidb-optimization-for-subquery/6.png)

再根据外连接化简的原则,可以进一步化简为:

![](https://static.zybuluo.com/zyytop/m5eci39o6eyqeucgvzp561xl/7.png)
![](media/tidb-optimization-for-subquery/7.png)

利用上述九条规则,理论上已经解决去关联化的问题了。是不是对于所有的情况,去关联化都是最好的呢?答案是否定的。如果 SQL 的结果很小,同时子查询可以利用索引,有时候使用 correlated execution 是最好的。是否去关联化还需要统计信息的帮助。而到了这一步,普通的优化器已经无能为力了。只有 Volcano 或 Cascade Style 的优化器,可以同时考虑逻辑等价规则和代价选择。因此,想要完美解决子查询的问题,要需要优秀的优化器框架的支撑。

Expand All @@ -98,7 +98,7 @@ EXISTS(SELECT * FROM TMP WHERE TMP.id = SRC.id)

TiDB 做出的 Plan 为:

![](https://static.zybuluo.com/zyytop/yuw7v761re6dclra4lvpg3bi/8.png)
![](media/tidb-optimization-for-subquery/8.png)

当子查询出现在 SELECT 子句当中时:

Expand All @@ -110,6 +110,6 @@ THEN 1 ELSE 2 END FROM SRC

Projection 算子需要知道 Exists 结果是 True 或者 False。这时需要左外半连接,当然外表匹配时,有一个辅助列 aux 输出 True,当不匹配时,输出 False。

![](https://static.zybuluo.com/zyytop/2klgi6syt4e8tlzawxd32c07/9.png)
![](media/tidb-optimization-for-subquery/9.png)

对于半连接的算法实现,其实和 Join 差别不大,可以选择 MergeSortJoin,HashJoin,IndexLoopUpJoin,NestedLoop 等等。确定使用 SemiJoin 之后,优化器会根据统计信息选择最合适的算法,这里不再赘述。
4 changes: 2 additions & 2 deletions tidb-source-code-reading-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tags: ['TiDB 源码阅读','社区']

## TiDB 架构

![](https://upload-images.jianshu.io/upload_images/542677-f99ab87773a67264.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-2/1.png)

本次 TiDB 源码之旅从这幅简单的架构图开始,这幅图很多人都看过,我们可以用一句话来描述这个图:『TiDB 是一个支持 MySQL 协议,以某种支持事务的分布式 KV 存储引擎为底层存储的 SQL 引擎』。从这句话可以看出有三个重要的事情,第一是如何支持 MySQL 协议,与 Client 交互,第二是如何与底层的存储引擎打交道,存取数据,第三是如何实现 SQL 的功能。本篇文章会先介绍一些 TiDB 有哪些模块及其功能简要介绍,然后以这三点为线索,将这些模块串联起来。

Expand Down Expand Up @@ -121,7 +121,7 @@ TiDB 的模块非常多,这里做一个整体介绍,大家可以看到每个

## SQL 层架构

![](https://upload-images.jianshu.io/upload_images/542677-daff1c5d2fd2b96e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-2/2.png)

这幅图比上一幅图详细很多,大体描述了 SQL 核心模块,大家可以从左边开始,顺着箭头的方向看。

Expand Down
4 changes: 2 additions & 2 deletions tidb-source-code-reading-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ Session 中最重要的函数是 [Execute](https://github.com/pingcap/tidb/blob/

TiDB 的执行引擎是以 Volcano 模型运行,所有的物理 Executor 构成一个树状结构,每一层通过调用下一层的 Next/NextChunk() 方法获取结果。 举个例子,假设语句是 `SELECT c1 FROM t WHERE c2 > 1;`,并且查询计划选择的是全表扫描+过滤,那么执行器树会是下面这样:

![](https://upload-images.jianshu.io/upload_images/542677-a05056e04d640820.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-3/1.png)

大家可以从图中看到 Executor 之间的调用关系,以及数据的流动方式。那么最上层的 Next 是在哪里调用,也就是整个计算的起始点在哪里,谁来驱动这个流程? 有两个地方大家需要关注,这两个地方分别处理两类语句。 第一类语句是 Select 这种查询语句,需要对客户端返回结果,这类语句的执行器调用点在[给客户端返回数据的地方](https://github.com/pingcap/tidb/blob/master/server/conn.go#L909)

Expand All @@ -242,7 +242,7 @@ TiDB 的执行引擎是以 Volcano 模型运行,所有的物理 Executor 构

上面描述了整个 SQL 层的执行框架,这里用一幅图来描述整个过程:

![](https://upload-images.jianshu.io/upload_images/542677-91e0bb2f3bbef234.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-3/2.png)

通过这篇文章,相信大家已经了解了 TiDB 中语句的执行框架,整个逻辑还是比较简单,框架中具体的模块的详细解释会在后续章节中给出。下一篇文章会用具体的语句为例,帮助大家理解本篇文章。

Expand Down
2 changes: 1 addition & 1 deletion tidb-source-code-reading-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ writeBufs.RowValBuf, err = tablecodec.EncodeRow(ctx.GetSessionVars().StmtCtx, ro

Insert 语句在诸多 DML 语句中算是最简单的语句,本文也没有涉及 Insert 语句中更复杂的情况,所以相对比较好理解。上面讲了这么多代码,让我们用一幅图来再回顾一下整个流程。

![Insert.png](https://upload-images.jianshu.io/upload_images/542677-276fce09300cecc6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Insert.png](media/tidb-source-code-reading-4/1.png)

最后给大家留一个思考题,本文描述了如何写入数据,那么 TiDB 是如何删除数据的呢?也就是 Delete 语句的执行流程是什么样子的,请大家追踪源码,调研一下这个流程,有兴趣的读者可以仿照本文写一篇源码解析文档,投稿给我们。

Expand Down
4 changes: 2 additions & 2 deletions tidb-source-code-reading-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tags: ['TiDB 源码阅读','社区']
PingCAP 发布了 TiDB 的[源码阅读系列文章](https://pingcap.com/blog-cn/#%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB),让我们可以比较系统的去学习了解TiDB的内部实现。最近的一篇[《SQL 的一生》](https://pingcap.com/blog-cn/tidb-source-code-reading-3/),从整体上讲解了一条 SQL 语句的处理流程,从网络上接收数据,MySQL 协议解析和转换,SQL 语法解析,查询计划的制定和优化,查询计划执行,到最后返回结果。

![](https://upload-images.jianshu.io/upload_images/542677-681f36030427da3e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-5/1.png)

其中,`SQL Parser` 的功能是把 SQL 语句按照 SQL 语法规则进行解析,将文本转换成抽象语法树(`AST`),这部分功能需要些背景知识才能比较容易理解,我尝试做下相关知识的介绍,希望能对读懂这部分代码有点帮助。

Expand All @@ -33,7 +33,7 @@ parser: goyacc

[Lex & Yacc](https://dinosaur.compilertools.net/) 是用来生成词法分析器和语法分析器的工具,它们的出现简化了编译器的编写。`Lex & Yacc` 分别是由贝尔实验室的 [Mike Lesk](https://en.wikipedia.org/wiki/Mike_Lesk)[Stephen C. Johnson](https://en.wikipedia.org/wiki/Stephen_C._Johnson) 在 1975 年发布。对于 Java 程序员来说,更熟悉的是 [ANTLR](https://www.antlr.org/)`ANTLR 4` 提供了 `Listener`+`Visitor` 组合接口, 不需要在语法定义中嵌入`actions`,使应用代码和语法定义解耦。`Spark` 的 SQL 解析就是使用了 `ANTLR``Lex & Yacc` 相对显得有些古老,实现的不是那么优雅,不过我们也不需要非常深入的学习,只要能看懂语法定义文件,了解生成的解析器是如何工作的就够了。我们可以从一个简单的例子开始:

![](https://upload-images.jianshu.io/upload_images/542677-6f5c07124b51e618.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-5/2.png)


上图描述了使用 `Lex & Yacc` 构建编译器的流程。`Lex` 根据用户定义的 `patterns` 生成词法分析器。词法分析器读取源代码,根据 `patterns` 将源代码转换成 `tokens` 输出。`Yacc` 根据用户定义的语法规则生成语法分析器。语法分析器以词法分析器输出的 `tokens` 作为输入,根据语法规则创建出语法树。最后对语法树遍历生成输出结果,结果可以是产生机器代码,或者是边遍历 `AST` 边解释执行。
Expand Down
6 changes: 3 additions & 3 deletions tidb-source-code-reading-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ columnPruner(列裁剪) 规则,会将不需要的列裁剪掉,考虑这

经过逻辑优化,我们可以得到这样一个查询计划:

![logical-select.png](https://upload-images.jianshu.io/upload_images/542677-b0925ace28091e54.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![logical-select.png](media/tidb-source-code-reading-6/1.png)

其中 `FROM t` 变成了 DataSource 算子,`WHERE age > 10` 变成了 Selection 算子,这里留一个思考题,`SELECT name` 中的列选择去哪里了?

Expand Down Expand Up @@ -273,14 +273,14 @@ type task interface {

如果了解过 TiDB 的 Explain 结果,那么可以看到每个 Operator 都会标明属于哪种 Task,比如下面这个例子:

![explain.jpg](https://upload-images.jianshu.io/upload_images/542677-6718743b95ee12d5.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![explain.jpg](media/tidb-source-code-reading-6/2.png)


整个流程是一个树形动态规划的算法,大家有兴趣可以跟一下相关的代码自行研究或者等待后续的文章。

经过整个优化过程,我们已经得到一个物理查询计划,这个 `SELECT name FROM t WHERE age > 10;` 语句能够指定出来的查询计划大概是这样子的:

![simple-select.png](https://upload-images.jianshu.io/upload_images/542677-6c7c5fa4df2443c3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![simple-select.png](media/tidb-source-code-reading-6/3.png)

读者可能会比较奇怪,为什么只剩下这样一个物理算子?`WHERR age > 10` 哪里去了?实际上 age > 10 这个过滤条件被合并进了 PhysicalTableScan,因为 `age > 10` 这个表达式可以下推到 TiKV 上进行计算,所以会把 TableScan 和 Filter 这样两个操作合在一起。哪些表达式会被下推到 TiKV 上的 Coprocessor 模块进行计算呢?对于这个 Query 是在下面 [这个地方](https://github.com/pingcap/tidb/blob/source-code/plan/predicate_push_down.go#L72) 进行识别:

Expand Down
2 changes: 1 addition & 1 deletion tidb-source-code-reading-7.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ select b from t1, t2 where t1.c = t2.c and t1.a > 5

变成逻辑查询计划之后,t1 t2 对应的 DataSource,负责将数据捞上来。上面接个 Join 算子,将两个表的结果按 `t1.c = t2.c`连接,再按 `t1.a > 5` 做一个 Selection 过滤,最后将 b 列投影。下图是未经优化的表示:

![](https://upload-images.jianshu.io/upload_images/542677-81a998b09e87f90e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](media/tidb-source-code-reading-7/1.png)

- Sort 就是 `select xx from xx order by` 里面的 `order by`

Expand Down

0 comments on commit c6f1d16

Please sign in to comment.