DDL执行流程:
- start job负责接收DDL语句,将DDL变为job存储在tikv的job queue队列中;
- TiDB Server Onwer的workers负责执行job,按照先进先出的原则从job queue队列中依次执行;owner会周期进行选举,决定下一个onwer;同一时刻只有一个Tidb server可以执行 DDL语句,所有tidb server都可以提交job queue;
- 执行完毕的数据会放入history queue队列中;
- add index queue专门针对加索引的任务队列;
注意:
- tidb owner的选举过程:由PD按照轮训的方式选择tidb server作为owner;
SQL的解析和编译
- TiDB的Protocol Layer 协议层监听客户端发出的SQL后开始对SQL进行处理
- 由PD Client 从PD中异步获取TSO
- Parse模块进行词法分析和语法分析,生成AST语法树,传给Compile模块
- Compile模块的Preprocess预处理阶段检测SQL的合法性和名称等; 并且做判断,如果SQL是点查(读取一条数据), 直接执行
- 如果不是点查,进入Optimize优化流程;
- 逻辑优化:通过关系代数,等价交换等规则进行逻辑变换;
- 物理优化:基于逻辑优化结果结合相关统计信息(表行行数、直方图等选择最优算子)
- 出来的结果即物理执行计划,然后下一步到TiKV中取数据;
- 收到物理执行计划后,获取表的元数据(启动时从PD获取,而后加载到TiDB 节点的本地缓存的information_schmea中,修改表数据对应的KEY所在的Region和TiKV信息(第一次访问从PD获取,后续缓存到TiKV Client中的Region Cache中)
- 如果遇到元数据过期Backoff,则从PD中获取最新信息再次缓存;
- 如果是点查,则直接走KV模块,通过TiKV Client进行读数据;
- 如果是其他SQL语句,则分发给DistSQL模块,会将复杂多表的查询SQL转换成单表的简单查询,而后下发给TiKV Client
- TiKV收到之后会构建一个snapshot快照,保证查询的结果是同一时间的结果;
数据写入流程:
写入流程:
- 写入过程中会先将数据读取,读取流程和上面一致,读取结果会先放入memBuffer中;
- Transaction会先进入两阶段提交,a,修改数据和加锁; b,commit提交;
- Scheduler模块负责协调事物并发写入的冲突,并将收到的修改操作向下写入;
- Raftstore模块将写请求转化为Raft Log 转到本地rocksdb raft实例并同步到其他副本;
- raft log写入成功后,APPLY模块负责将数据写入到rocksdb kv实例中进行持久化;