目录
1. DML语句读流程概要
2. DML语句写流程概要
3. DDL 流程概要
4. SQL的Parse和Compile
5. 读取的执行
6. 写入的执行
7. DDL的执行
8. 小结
1. DML语句读流程概要
TiDB Server接收sql并处理,TiKV负责持久化数据,PD提供TSO和Region的数据字典信息
- Protocol Layer:接收sql
- PD Client到PD节点获取STO
- Parse:词法解析、语法解析,将sql解析为AST语法树
- Compile:区分点查和非点查,生成执行计划
- Execute:拿着执行计划问PD在哪个TiKV Region读取想要的数据
- 读取数据后交由Execute,返回给用户
2. DML语句写流程概要
- Protocol Layer:接收sql
- PD Client到PD节点获取STO
- Parse:词法解析、语法解析,将sql解析为AST语法树
- Compile:区分点查和非点查,生成执行计划
- Execute:拿着执行计划问PD在哪个TiKV Region读取想要的数据
- 读出来的数据放在memBuffer中进行修改,当用户发起commit的时候,进入两阶段提交
- 第一阶段:prewrite,将内存中修改的信息和锁信息写入TiKV
- 第二阶段:commit,写提交信息,将锁清理掉,获取结束TSO
- 二阶段提交完成后,返回给用户提交成功数据不会丢了
3. DDL 流程概要
修改表定义、加索引等等都是DDL
- 用户发出DDL语句
- TIDB Server中的start job接收DDL语句
- 将DDL放入TiKV中的job queue中(添加索引是放在 add index queue中)
- TIDB Server谁是owner角色谁就执行DDL,owner中的worker去job queue(先进先出)中取DDL去执行
- 执行完后把该job放入history queue中
4. SQL的Parse和Compile
- Protocol Layer:接收sql
- PD Client:去PD异步获取TSO
- Parse:词法分析LEX,语法分析YACC,将sql转化成AST语法树
- compile:
- preprocess:检测sql合法性,名称是否正确,一些绑定信息等,判断是否是点查
- 如果是点查(PointGet)的话直接就执行,节约了优化的工作
- 如果是非点查的话,进入优化流程:
- ①逻辑优化:关系代数、等价交换等一些规则将sql语句进行一些逻辑的变换,比如把外连接转化为内连接等等
- ②物理优化:基于逻辑优化的结果结合相关的统计信息(行数、列的选择度、直方图等等)选择最优的算子,如何去TiKV中好的效率最高的取得数据
- 编译完成后生成物理执行计划,拿着物理执行计划去TiKV中取数据
5. 读取的执行
当Executor收到执行计划后,Executor做两件事:
- ①从information schema(缓存中,是最新的)中获得元数据(表名、列名等)
- ②要修改的数据对应Key在所在的Region以及Region所在的TiKV,第一次会从PD中获取Region的位置,然后缓存在TiKV Client中的region Cache中,如果region Cache的信息过期了(back off),访问的时候会再次从PD中读取最新的信息到region Cache中
经过了以上过程,获得了表的元数据以及Key所在的Region和TiKV
Executor读取数据:
- 如果是点查,KV模块就通过TiKV Client直接读取数据
- 如果是非点查(复杂sql语句)DistSQl模块会将复杂的sql转换成多条对单表的查询语句,然后通过TiKV Client去TiKV取数据
TiKV接收到请求后首先会构建一个快照snapshot
点查和非点查都会进入UnifyRead Pool线程池,按照优先级执行查询,到RocksDB kv去读取数据
一部分过滤和聚合在TiKV中做,叫coptask,还有一部分在TiDB中(比如三张表连接,三张表散落在3个TiKV中,先把数据读到TiDB内存中再做表连接)叫root task
6. 写入的执行
前面的读取流程是一样的,从读出数据开始,把需要修改的数据读到memBuffer中,用户commit后进入两阶段提交
第一阶段:prewrite,Transaction从memBuffer中一行一行读取数据修改数据,通过KV和TiKV Client写到TiKV中并加锁
- 写请求发送给Scheduler模块(协调事务并发写入的冲突,并将收到的修改操作向下写入),同时写入同一个Key的时候,谁持有Latch谁就可以写数据,其他的需等待Latch
- 然后到RaftStore,将写请求转换为raft log,此时会在本地RocksDB raft持久化raft log,并把raft log发送给其他节点,然后Apply模块把读取rocksdb raft log应用到rocksdb kv中持久化存储,然后反馈写入成功。
第二阶段:commit,获取结束TSO,写提交信息,清理锁
7. DDL的执行
- Protocol Layer接收DDL,经过Parse和Compile,到达start job
- start job会检查自己所在的TiDB Server是不是owner
- 如果是owner则直接给workers执行,如果不是就会把DDL做成一个job放到TiKV的job queue中持久化(添加索引放在add index queue中)
- Schema load:将最新的表的元信息载入到TiDB Server
- owner中的worker会定期去查看job queue,当job queue中有job的时候workers就根据元信息执行DDL(Job queue 和 add index queue 中的语句可以并行执行)
- 执行完毕后把job放在history queue中
owner节点是轮询的,由PD节点控制
8. 小结
- DML 语句读写流程
- DDL语句的执行流程
来自TiDB官方资料