(数据库必知必会:TiDB(2)TiDB Server)
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型数据(聚簇型)。
案例中,关系型数据中的编号是数据的主键,表号是为了区分该数据是哪张表的数据,用表+数据主键即可唯一区分数据。
表+主键作为K,其余列做列簇作为V,最终形成Region,Region的大小是96MB~144MB,当数据超过一定的量,Region就会分裂。
SQL读写相关模块
复杂SQL,比如需要全表扫描的,会走DistSQL,复杂SQL会转化成对单表的查询SQL交给DistSQL进行处理,DistSQL处理单表、多Region的SQL。
点查SQL,会走KV。
无论是复杂SQL的DistSQL,还是点查的KV,最终都会交由TiKV Client与TiKV进行交互。
在线DDL相关模块
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 Server,并根据tidb_table_cache_lease设置的时间作为缓存租约,在租约期内,所有对于该表数据的读操作都从TiDB Server的缓存中读取,在租约期内,所有对于该表数据的写操作都被阻塞,不能写,只能读,保证数据的一致性。在租约过期后,对该表的数据的写操作和读操作都是直接在TiKV上执行的。数据更新完毕后,新一轮的小表缓存开启,缓存刷新refresh,再次启动租约机制,不能写,只能读。
应用
- TiDB对于小表缓存的大小限制为64MB
- 适用于查询频繁、数据量不大、极少修改的场景(需要保证在租约到期的极短时间内完成写操作,修改太多写不完)
- 在租约期内,写操作会被阻塞
- 租约到期时,读TiKV,读性能会下降
- 不支持对缓存表直接做DDL,需要先关闭缓存再做DDL
- 对于修改极少的表,可以适当增加租约时间,可以减少读性能抖动
知识点回顾
- 下列哪些模块直接与 TiDB 的事务处理有关?( 选 2 项 )
A. KV
B. Parse
C. Schema load
D. Transaction
E. GC
F. start job
解析:从架构图上看,KV和Transaction是与事务处理有关的
- 关于关系型数据与 KV 的转化,下列说法不正确的是?
A. 如果没有定义主键,key 中包含 RowID,Index ID 和 Table ID,都是 int64 类型
B. Table ID 在整个集群内唯一
C. 如果定义了主键,那么将使用主键作为 RowID
D. 不需要为每张表指定主键
解析:如果表有主键,聚簇型转换以主键作为RowID,但非聚簇型的不是