SQL的Parse与Compile
- 处理之前需要从PD异步获取一个开始TSO。
- Parse根据词法分析(rex)和语法分析(yacc)将Sql转化为AST语法树,这个抽象语法树被传到Compile模块
- Compile的preprocess预处理阶段,会检查合法性,还会判断语句是否是点查。不是点查将进入优化流程,逻辑优化将对SQL语句进行变换,物理优化将选择最优的算子。
读取的执行
获得执行计划之后
- 首先从information schema获取表的元数据。(TiDB启动时,元数据读入到information schema)
- 获取表所在region以及region所在TiKV。第一次访问不得不从PD获取,之后就可以从region Cache中获取。如果region Cache中信息过期,访问到错的节点,就会back off,重新到PD读取最新信息,然后缓存起来。
- Executor发现语句是点查,有KV负责。
- Dist SQL负责复杂Sql,将复杂Sql转化为单表的查询,再下发给TiKV。
- TiKV收到查询之后,会首先构造快照snapshot。查询都会到UnifyRead Pool线程池,按照优先级执行。
- 在TiKV中做的操作叫做cop task,在TiDB Server中做的叫做root task
写入的执行
- 写之前会将要修改的数据先读到memBuffer
- Transaction进入两阶段提交。第一阶段加锁修改数据,第二阶段commit和释放锁。除了在一开始的时候获得开始TSO之外,还要获得结束时间TSO。
- KV将查询通过TiKV Client发给TiKV
- 写请求发送给Scheduler。Scheduler用latch协调事务并发写入的冲突,并将收到的修改操作向下输入。
- Raftstore将写请求转化为RaftLog,写到rocksdb raft。并将日志发送给其他节点,同步日志。
- Apply模块读取日志,并将数据持久化到rocksdb kv中。
DDL的执行
-
同一时刻只有一个TiDB Sever的worker可以执行。这个TiDB Sever节点叫做owner
-
schema load负责在节点成为owner的时候,将最新信息载入到节点。
-
执行计划交给start job,start job收到执行计划之后先看自己所在节点是不是owner。不是owner的话会将DDL做成job放到TiKV中的job queue队列。
-
owner会定期查看job queue,job queue中有job的时候,就把job拿出来执行,将执行完的job放入history queue
-
owner轮询
-
加索引的DDL放入add index queue