CockroachDB开发学习文档04 SQL工作原理

本文详细解析了CRDB中的SQL语句执行流程,包括抽象语法树(AST)的构建及节点处理,以及如何根据数据分布情况选择单机或分布式执行路径。

目标:分析一个SQL语句的执行过程。

 

从目前的CRDB源代码来看,整个流程框架如下所示:

首先,要了解一下什么是AST树。

抽象语法树(abstract syntax code,AST)是源代码的抽象语法结构的树状表示,树上的每个节点都表示源代码中的一种结构,这所以说是抽象的,是因为抽象语法树并不会表示出真实语法出现的每一个细节,比如说,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现。抽象语法树并不依赖于源语言的语法,也就是说语法分析阶段所采用的上下文无文文法,因为在写文法时,经常会对文法进行等价的转换(消除左递归,回溯,二义性等),这样会给文法分析引入一些多余的成分,对后续阶段造成不利影响,甚至会使合个阶段变得混乱。因些,很多编译器经常要独立地构造语法分析树,为前端,后端建立一个清晰的接口。

从CRDB的工作流程图来看,这些一个个planNode就是抽象的语法树节点。

打开pkg/sql/plan.go文件,找到planNode的定义:

type planNode interface {

 Start(params runParams) error

 Next(params runParams) (bool, error)

 Values() parser.Datums

 Close(ctx context.Context)

}

Start()函数的功能是初始运行当前节点,Next()函数相当于对下一行数据进行处理,得到的数据可以通过Values()进行读取,最后销毁节点时调用Close()。

这是一个接口类型,看看下面,定义了许多的全局变量,这些就是AST树上的节点,但都是空的,这里主要是做一些空节点的初始化。

再看一个接口类型, 

type planMaker interface {

    newPlan(ctx context.Context, stmt parser.Statement, desiredTypes []parser.Type,) (planNode, error)

    makePlan(ctx context.Context, stmt Statement) (planNode, error)

    prepare(ctx context.Context, stmt parser.Statement) (planNode, error)

}

通过这个planMaker就可以递归地对构建AST树了,一条复杂的SQL语句最后都是返回一个planNode的接口。

在得到根结点的planNode之后,CRDB会进行执行期优化,检测并判断当前SQL走的是单机工作流程还是分布式的工作流程。

通常,一些系统的查询就会走单机工作流程模式,直接调用startPlan()对根结点进行Start,Next,Values,Close的工作。

最后,通过一个ForEachRow()函数就可以对每行的数据进行相应的编排处理了。

而当数据分布在多节点上的时候,就会走分布式流程的结果。

比如一条简单的SELECT * FROM TABLE_NAME;

可以查看pkg/sql/executor.go文件,这里和单机的查询最大区别就是用了一个distSQLPlanner。

这个Planner能够将请求封装成runnerRequest,然后下发到节点上去处理。

而节点的具体处理逻辑在pkg/sql/distsqlrun/tablereader.go文件中进行了实现。

最后的数据就会由RowFetcher一行行地读出来。

你要是问我怎么知道是在这里找到的,请看

https://github.com/cockroachdb/cockroach/issues/27551

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值