本文概述了分区表模块的主要实现原理,便于用户了解分区表在底层实现时的一些细节,从而能够更好地学习如何去使用分区表。
分区表创建原理
分区表的创建主要涉及语法解析模块和执行模块。
语法解析模块
分区表创建是分区表整个功能的核心部分,任何分区表都需要经过一个完整的语法树创建出来,这个语法树上包含了诸多分区表的特性,如下图所示。
其中主要的关键字包括:
PARTITION BY
:指定一级分区的类型和字段。SUBPARTITION BY
:指定二级分区的类型和字段。INTERVAL
:指定自动间隔分区的属性。SUBPARTITION TEMPLATE
:子分区模板的属性。(PARTITION xxx)
: 子分区列表。
接收到用户的输入后,第一步是将语法树转换为数据库中的Node节点。下图详细解释了这个转换的过程。
整个语法树挂在了
CreateStmt
节点下,分区表本质上还是创建一张表的过程;partspec
节点是一级分区管理节点,它承载了分区键和分区策略;PartitionInfo
节点是二级的管理节点,承载了大部分语法树上的结构。根据颜色我们可以大致将其分为如下几个模块,后续由这些模块的结合来完成分区创建过程:Interval分区模块
一级分区模块
二级子分区模块
分区模板模块
二级节点列表模块
语法执行模块
执行器根据步骤大致分为以下三个部分。
转储表定义存储模块
第一步是转储表定义存储模块。该模块将未来创建子表可能的模板信息转储到表定义中去,为了能够在表之后的使用中保留元信息。
将表定义存储到表的Option结构上,包括这些数据需要存储:
interval_expr:这个结构存储间隔分区的间隔大小。
sub_part_strategy/sub_part_params:存储二级分区的分区键和分区类型信息。
partition_template_list:存储了模板分区列表,用于后续的子分区模块分区的创建。
sub_hash_number:存储了模板分区的HASH数量,用于后续构建出正确的HASH分区。
子表定义模块
第二步为子表定义模块。将创建信息切换成实际的创建列表。
将抽象的HASH分区/模块分区生成实际的节点树,用于创建后续的分区。
说明对于一级分区表,通过hash_number生成partition_node_list,该列表实际会创建HASH分区表。
对于二级分区表,通过template_list生成partition_node_list, 如果用户定义了分区模板,需要生成该列表。
遍历生成的partition_node_list,补充分区策略、分区键等分区表的关键信息。
如果判断出sub_hash_number或者template_list不为空,说明节点还记录了二级分区的属性。需要将二级分区的这些属性填入一级分区(或者生成的一级分区中),后续等待二级分区创建时递归处理。
实际创建模块
第三步为实际创建模块。将节点列表转换成创建列表。
将之前用来代表子节点的PartitionRelNode节点转换成CreateStmt节点,然后进行创建操作。
分区表管理原理
分区表管理是分区表另一个核心的组成部分,相比于普通表,分区表有更丰富的管理方式。
分区表的管理可以分为以下10个主要模块:
MODIFY:管理分区,是一类操作的集合,对象是一个一级分区,可以通过该指令管理这个分区下的二级分区。
MOVE:移动分区,通常是移动其存储位置。
ADD:增加分区,为分区表增加一个一级分区。
COLESCE:裁剪分区,只用于HASH分区,该命令使得HASH分区的数量减一。
DROP:删除分区,可以指定删除掉一个RANGE/LIST分区。
RENAME:为分区重命名。
TRUNCATE:重整分区,将整个分区清空。
SPLIT:拆分分区,用于RANGE/LIST分区,将一个分区拆分为两个分区,可以指定一个分区届作为拆分的界限。
MERGE:归并分区,用于RANGE/LIST分区,将两个分区归并为一个分区。
EXCHANGE:交换分区,交换两个分区的内容,需要通过分区的界限检查。