原理

本文概述了分区表模块的主要实现原理,便于用户了解分区表在底层实现时的一些细节,从而能够更好地学习如何去使用分区表。

分区表创建原理

分区表的创建主要涉及语法解析模块和执行模块。

语法解析模块

分区表创建是分区表整个功能的核心部分,任何分区表都需要经过一个完整的语法树创建出来,这个语法树上包含了诸多分区表的特性,如下图所示。

其中主要的关键字包括:

  • PARTITION BY:指定一级分区的类型和字段。

  • SUBPARTITION BY:指定二级分区的类型和字段。

  • INTERVAL:指定自动间隔分区的属性。

  • SUBPARTITION TEMPLATE:子分区模板的属性。

  • (PARTITION xxx): 子分区列表。

接收到用户的输入后,第一步是将语法树转换为数据库中的Node节点。下图详细解释了这个转换的过程。

image.png

  1. 整个语法树挂在了CreateStmt节点下,分区表本质上还是创建一张表的过程;

  2. partspec节点是一级分区管理节点,它承载了分区键和分区策略;

  3. PartitionInfo节点是二级的管理节点,承载了大部分语法树上的结构。根据颜色我们可以大致将其分为如下几个模块,后续由这些模块的结合来完成分区创建过程:

    • Interval分区模块

    • 一级分区模块

    • 二级子分区模块

    • 分区模板模块

    • 二级节点列表模块

语法执行模块

执行器根据步骤大致分为以下三个部分。

转储表定义存储模块

第一步是转储表定义存储模块。该模块将未来创建子表可能的模板信息转储到表定义中去,为了能够在表之后的使用中保留元信息。

将表定义存储到表的Option结构上,包括这些数据需要存储:

  • interval_expr:这个结构存储间隔分区的间隔大小。

  • sub_part_strategy/sub_part_params:存储二级分区的分区键和分区类型信息。

  • partition_template_list:存储了模板分区列表,用于后续的子分区模块分区的创建。

  • sub_hash_number:存储了模板分区的HASH数量,用于后续构建出正确的HASH分区。

image.png

子表定义模块

第二步为子表定义模块。将创建信息切换成实际的创建列表。

  1. 将抽象的HASH分区/模块分区生成实际的节点树,用于创建后续的分区。

    说明
    • 对于一级分区表,通过hash_number生成partition_node_list,该列表实际会创建HASH分区表。

    • 对于二级分区表,通过template_list生成partition_node_list, 如果用户定义了分区模板,需要生成该列表。

  2. 遍历生成的partition_node_list,补充分区策略、分区键等分区表的关键信息。

  3. 如果判断出sub_hash_number或者template_list不为空,说明节点还记录了二级分区的属性。需要将二级分区的这些属性填入一级分区(或者生成的一级分区中),后续等待二级分区创建时递归处理。

image.png

实际创建模块

第三步为实际创建模块。将节点列表转换成创建列表。

将之前用来代表子节点的PartitionRelNode节点转换成CreateStmt节点,然后进行创建操作。

image.png

分区表管理原理

分区表管理是分区表另一个核心的组成部分,相比于普通表,分区表有更丰富的管理方式。

image.png

分区表的管理可以分为以下10个主要模块:

  • MODIFY:管理分区,是一类操作的集合,对象是一个一级分区,可以通过该指令管理这个分区下的二级分区。

  • MOVE:移动分区,通常是移动其存储位置。

  • ADD:增加分区,为分区表增加一个一级分区。

  • COLESCE:裁剪分区,只用于HASH分区,该命令使得HASH分区的数量减一。

  • DROP:删除分区,可以指定删除掉一个RANGE/LIST分区。

  • RENAME:为分区重命名。

  • TRUNCATE:重整分区,将整个分区清空。

  • SPLIT:拆分分区,用于RANGE/LIST分区,将一个分区拆分为两个分区,可以指定一个分区届作为拆分的界限。

  • MERGE:归并分区,用于RANGE/LIST分区,将两个分区归并为一个分区。

  • EXCHANGE:交换分区,交换两个分区的内容,需要通过分区的界限检查。