数据库必知必会:TiDB(2)TiDB Server

时间:2023-02-07 11:16:41

(数据库必知必会:TiDB(2)TiDB Server)

TiDB Server架构

数据库必知必会:TiDB(2)TiDB Server

Protocol Layer、Parse、Compile主要负责SQL语句的解析、编译,生成SQL的执行计划。

Executor、DistSQL主要负责分批执行SQL的执行计划。

Transaction、KV主要负责事务相关的SQL的执行。

PD Client、TiKV Client主要负责与PD、TiKV进行交互。

schema load、worker、start job主要负责online DDL的执行。

memBuffer、cache table主要负责缓存、热点小表缓存。

GC主要负责垃圾回收,回收数据版本太旧的数据。

SQL语句的解析和编译

Parse

Parse是对SQL语句进行解析:

  • 根据用户提交的SQL语句
  • 使用词法分析器(lex)进行分析,得到SQL语句关键字、列名、表名、条件等信息
  • 再使用语法分析器(yacc)进行语法分析,分析出具体的列名列表、表名称、条件等
  • 形成最终的抽象语法树AST

Compile

Compile是对SQL语句进行编译:

  • 根据Parse生成的抽象语法树AST
  • 进行合法性验证,是否存在表、字段等
  • 验证通过后进行逻辑优化,比如进行列裁剪、谓词下推等
  • 经过逻辑优化后进行物理优化,结合数据的统计信息决定算子的选择,比如是否走索引还是全表扫描等
  • 生成最终的执行计划

关系型数据与K-V型数据的转换

下面以动画的形式演示关系型数据如何转换成K-V型数据(聚簇型)。

案例中,关系型数据中的编号是数据的主键,表号是为了区分该数据是哪张表的数据,用表+数据主键即可唯一区分数据。

数据库必知必会:TiDB(2)TiDB Server

表+主键作为K,其余列做列簇作为V,最终形成Region,Region的大小是96MB~144MB,当数据超过一定的量,Region就会分裂。

SQL读写相关模块

数据库必知必会:TiDB(2)TiDB Server

复杂SQL,比如需要全表扫描的,会走DistSQL,复杂SQL会转化成对单表的查询SQL交给DistSQL进行处理,DistSQL处理单表、多Region的SQL。

点查SQL,会走KV。

无论是复杂SQL的DistSQL,还是点查的KV,最终都会交由TiKV Client与TiKV进行交互。

在线DDL相关模块

数据库必知必会:TiDB(2)TiDB Server

worker是TiDB Server中做DDL操作的组件,每个TiDB Server都有一个worker,TiDB Server会并发接收用户的请求,但同一时刻,只会有一个TiDB Server的worker在执行DDL语句。

start job接收用户请求,将请求存放到job queue队列中,worker中的owner从job queue中取出job进行执行,保障只有一个worker在执行DDL。执行完成的job会放到history queue队列中。worker的owner角色会轮询选举,每隔一段时间owner角色可能会变更,保证其他TiDB Server的worker也有机会进行工作。

GC机制与相关模块

TiKV中的数据是保留了历史版本的,数据的修改并不是直接修改原始记录,而是以新版本的形式记录一条新的数据,旧数据当历史版本保留。一方面可以查看数据的变更历史,一方面如果数据修改错误可以基于历史版本进行回滚恢复。当版本过多,太早期的版本的作用已不大,形成了过期数据,保留太多版本会造成空间浪费,GC会对太早期的版本进行清理,以释放空间,默认10分钟清理一次。先清理被drop的表的数据,再清理被delete的数据。

TiDB Server的缓存

  • TiDB Server缓存的组成
    • SQL结果
    • 线程缓存
    • 元数据,统计信息
  • TiDB Server缓存管理
    • tidb_mem_quota_query,控制着每条SQL能够占用的缓存的大小
    • oom-action,决定了当SQL的内存使用超过上面设置的阈值后该如何处理

热点小表缓存

前提

  • 表的数据量不大
  • 只读表或者修改不频繁的表
  • 表的访问很频繁
  • 如果将表存在TiKV中,用户并发直接访问TiKV,会造成某个TiKV的热点问题
  • 表的数据大小小于64MB,则可进行小表缓存

数据库必知必会:TiDB(2)TiDB Server

原理

小表缓存是将小表的数据全部缓存到TiDB Server,并根据tidb_table_cache_lease设置的时间作为缓存租约,在租约期内,所有对于该表数据的读操作都从TiDB Server的缓存中读取,在租约期内,所有对于该表数据的写操作都被阻塞,不能写,只能读,保证数据的一致性。在租约过期后,对该表的数据的写操作和读操作都是直接在TiKV上执行的。数据更新完毕后,新一轮的小表缓存开启,缓存刷新refresh,再次启动租约机制,不能写,只能读。

应用

  • TiDB对于小表缓存的大小限制为64MB
  • 适用于查询频繁、数据量不大、极少修改的场景(需要保证在租约到期的极短时间内完成写操作,修改太多写不完)
  • 在租约期内,写操作会被阻塞
  • 租约到期时,读TiKV,读性能会下降
  • 不支持对缓存表直接做DDL,需要先关闭缓存再做DDL
  • 对于修改极少的表,可以适当增加租约时间,可以减少读性能抖动

知识点回顾

  1. 下列哪些模块直接与 TiDB 的事务处理有关?( 选 2 项 )

A. KV

B. Parse

C. Schema load

D. Transaction

E. GC

F. start job

解析:从架构图上看,KV和Transaction是与事务处理有关的

  1. 关于关系型数据与 KV 的转化,下列说法不正确的是?

A. 如果没有定义主键,key 中包含 RowID,Index ID 和 Table ID,都是 int64 类型

B. Table ID 在整个集群内唯一

C. 如果定义了主键,那么将使用主键作为 RowID

D. 不需要为每张表指定主键

解析:如果表有主键,聚簇型转换以主键作为RowID,但非聚簇型的不是