暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

了解TiDB中的DML/DDL执行流程

每个数据库都有自己的SQL执行流程,SQL语句分为DML语句和DDL语句,DML语句又分为读操作或是写操作。本文概要介绍一下TiDB数据库中DMLDDL语句执行流程。

一. DML语句读流程

DML语句的读流程如上图所示,具体可以描述为:

  1. 接收SQL请求。客户端发起SQL请求,由TiDB Server中的协议层(Protocol Layer)接收。

  2. 获取TSO当接收到SQL请求时,TiDB Server首先向PD节点申请TSO,标识SQL开始执行时间(不管是读操作还是写操作,都必须获取这样的TSO)。

  3. 解析。SQL解析,通过Parser模块对SQL进行词法解析及语法解析,将SQL解析为AST语法树。

  4. 编译。AST语法树发送到Compiler模块进行编译。Compiler判断是点查还是非点查,如果是点查,比如根据主键或索引的精确查询,则直接发送到下面执行;如果是非点查,则进入一个优化流程,包括逻辑优化和物理优化,最终生成一个物理执行计划

  5. 执行。无论是点查还是非点查,都会发送到Executor模块执行,并从TiKV中读取想要的数据。更具体一点,当Executor接收到执行计划后,首先需要做两件事:1)获取表的元数据信息(节点启动时从TiKV读取并缓存到TiDB的内存,即图中的information schema);2)获取数据所在的regionregion所属的TiKV(第一次从PD获取,之后从TiKV Client缓存中获取),如果发现TiKV Client中缓存的是错误的regionTiDB Server会重新从PD中读取正确的信息并重新缓存一份到TiKV Client

    之后Executor便可以开始从下面读取数据,根据前面Compile步骤中判断是点查还是非点查,Executor也会选择两条不同的路径来读取数据,第1个路径是走KV模块(通过TiKV Client直接从TiKV中读取相应的键值数据),第2个路径是DistSQL(针对复杂的SQL语句如多表关联,DistSQL会将复杂的SQL语句转换为对单表的简单查询再下发到TiKV节点,相当于把TiKV和复杂的SQL做了一个解耦)。

  6. 回结果。当数据从TiKV中读取到后返回到Executor模块,然后进一步返回到客户端。


二.DML语句写流程

DML语句的写流程在一开始的时候和读流程几乎一致,因为数据修改之前需要先将数据读取出来。所以写流程的开始阶段就是经过Protocol LayerParserCompilerExecutor之后通过ExecutorRocksDB中的KV数据读取到memBuffer之中,之后的步骤完全不同,具体描述为:

  1. 读取数据到缓存。与读流程类似,将数据读取到TiDB ServermemBuffer中。

  2. 修改数据。memBuffer中修改数据。

  3. 提交修改数据。进入事务两阶段提交逻辑。第一步为prewrite,即将修改的数据和锁信息写到TiKV中。第二步为commit,此时会向PD再申请一个事务提交时间戳并写入提交信息,同时释放锁信息。关于TiDB中事务两阶段提交相关内容,可以参考聊聊TiKV中的分布式事务 (qq.com)TiKV负责数据写入的有三个模块:SchedulerRaftstoreApplyScheduler负责协调事务并发写入的冲突并将收到的事务操作向下写入,它使用latch来管理并发冲突,谁拿到latch的可以继续向下写入,未拿到latch的处于等待状态。Raftstore是将写请求转化为Raft日志,Raft日志一方面需要持久到本地的RocksDB,另一方面需要复制到其他Follower节点同步。Apply模块负责读取Raft日志并应用到本地的RocksDB KV中。有关RocksDB的写入流程以及Raft复制流程,请参考浅谈TiKV中的数据持久化存储 (qq.com) 以及 了解TiKV中的Raft (qq.com)

  4. 返回。当两阶段commit完成后,返回客户端执行完成。


三.DDL语句执行流程

DDL主要是对表的定义进行修改,或是对表添加索引等操作。DDL执行流程为:

  1. SQL执行编译。DML语句执行类似,当TiDB Server接收到DDL请求时,会先进行解析和编译。Compile后发现是DDL语句,则将DDL交给TiDB Server中的start job组件进一步处理。

  2. 添加到队列。Start job组件将接收到的DDL放到TiKV中的队列(注意:实际上,start job会先判断本节点的workers是否为owner,如果是owner则直接交给owner执行,如果不是则写到TiKV队列)。TiKV中关于DDL的队列有三种,第1个队列是除add index以外的DDL、第2个队列是add index队列、第3个队列是存储历史执行完成的DDL队列。

  3. 执行DDL执行DDLTiDB Server中的workers组件负责。需要注意的是,每个TiDB Server中都有一个worker,但只有一个TiDB Server中的workerowner角色,只有处于owner角色的worker才能执行DDL操作。具有owner角色的worker采用先进先出的策略从TiKV中的job队列中取出一个DDL并执行,执行完成后放到history队列。(注意:owner角色是会轮询的,当一个TiDB Server中的worker处于owner一段时间会后重新选举并切换到另一台)

文章转载自数据源的技术后花园,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论