tencent cloud

TDSQL Boundless

产品动态
产品简介
产品概述
应用场景
产品架构
实例类型
兼容性说明
自研内核
内核概述
内核版本更新动态
功能类特性
性能类特性
产品计费
计费概述
购买方式
价格详情
续费说明
欠费说明
退费说明
快速入门
创建实例
连接实例
用户指南
数据迁移
数据同步/订阅
实例管理
配置变更
参数配置
账号管理
安全组
备份与恢复
数据库审计
标签管理
实践教程
Online DDL 的技术演进与使用实践
锁机制解析与问题排查实践
数据智能调度及相关性能优化实践
TDSQL Boundless 选型指南与实践教程
开发指南
开发指南(MySQL 兼容模式)
开发指南(HBase 兼容模式)
性能调优
性能调优概述
SQL 调优
DDL 调优
性能白皮书
性能概述
TPC-C 测试
Sysbench 测试
API 文档
History
Introduction
API Category
Making API Requests
Instance APIs
Security Group APIs
Task APIs
Backup APIs
Rollback APIs
Parameter APIs
Database APIs
Data Types
Error Codes
通用参考
系统原理
SQL 参考
数据库参数说明
TPC-H 基准测试数据模型参考
错误码信息
安全与合规
常见问题
服务协议
服务等级协议
服务条款
隐私政策
数据处理和安全协议
联系我们
词汇表

Distribution Policy

PDF
聚焦模式
字号
最后更新时间: 2026-03-06 18:48:23
Distribution Policy(DP) 是 TDSQL Boundless 管理数据对象分布的规则系统,通过对数据对象显式设置规则,元数据服务(MC)可以进行相应的调度。通过设置不同的调度规则,用户可以精细化控制数据对象的分布,如副本数量,副本位置分布,Replication Group Leader 位置等。

规则介绍

Distribution Policy 通常由多条具体的规则组成。元数据服务会对用户指定的多条规则进行校验,以确保规则本身的正确性以及多条规则之间不会互相冲突,具体的校验规则可参考注意事项。DP 的单条规则的设计参考了 Kubernetes 的 LabelConstraint 的设计,通常由含有 key, op, values 字段的 JSON 组成,如下所示:
{"key": "key1", "op": "op1", "values": ["value1","value2"]}
目前 TDSQL Boundless 支持的规则如下所示:
key
op
values
region
"in", "notIn", "exists", "notExists"
地域列表,如 ["guangzhou"]
zone
"in", "notIn", "exists", "notExists"
可用区列表,如 ["guangzhou-1"]
rack
"in", "notIn", "exists", "notExists"
机架列表,如 ["rack-1","rack-2"]
host
"in", "notIn", "exists", "notExists"
主机列表,如 ["host-1","host-2","host-3"]
node
"in", "notIn"
节点列表,如 ["node-tdsql3-xxx-001"]
replica-count
"="
副本数量,如 ["3"]
follower-count
"="
RG follower 数量,如 ["2"]
learner-count
"="
RG learner 数量,如 ["1"]
witness-count
"="
RG witness 数量,如 ["1"]
leader-preferences
"="
RG leader 偏好,用法参考说明2
fault-tolerance-level
"="
容灾级别,如 ["zone"]
tdsql-storage-type
"in", "notIn", "exists", "notExists"
磁盘类型列表,如 ["CLOUD_TCS","CLOUD_BSSD"]
说明:
1. 操作符含义:
in:给定 key 对应的 value 包含在给定的 values 列表中。
notIn:给定 key 对应的 value 不包含在给定的 values 列表中。
exists:包含给定 key。
notExists:不包含给定 key。
2. leader-preferences 的 values 由嵌套结构组成,例如:["{\\"key\\": \\"zone\\", \\"op\\": \\"in\\", \\"values\\": [\\"guangzhou-1\\"]}", "{\\"key\\": \\"zone\\", \\"op\\": \\"in\\", \\"values\\": [\\"guangzhou-2\\"]}"]。为了方便您的使用,推荐您 使用 SQL 创建 Distribution Policy
注意:
1. RG 副本相关的规则说明:RG leader 数量 + RG follower 数量 = replica-count - learner-count - witness-count。
当不指定 learner-count 或 witness-count 时,默认 learner 和 witness 的数量均为0。
例如指定 replica-count = 4 时表示 RG leader 数量为1,follower 数量为3。
2. 使用 node 作为 key 时的规则说明:
2.1 必须保证 values 中的节点是真实存在于实例中。
2.2 如指定副本数时,values 中的节点数量需要大于等于副本数,否则 DP 将无法调度。
3. 使用 leader-preferences 时的规则说明:RG leader 的位置应该始终是副本位置约束的子集,例如当指定副本位置位于可用区 ["zone1", "zone2", "zone3"] 时,需要保证 RG leader 的位置也指定在上述可用区中。
警告:
元数据服务在发现不合理的 DP 设置时,会拒绝进行调度,但不会影响其他功能的可用性以及数据的正确性。

使用 Distribution Policy

本节以工具 mc-ctl 为例,使用对应的 HTTP 接口也可得到相同的效果。

开启和关闭 Distribution Policy

distribution-policy-enabled 在 v18.0.0 默认开启
开启 Distribution Policy:
./mc-ctl schedule set --config_key distribution-policy-enabled --config_value 1
关闭 Distribution Policy:
./mc-ctl schedule set --config_key distribution-policy-enabled --config_value 0

创建 Distribution Policy

./mc-ctl dp create --data
'{
"policy_name":"$name",
"constraints":[
{"key": "key1", "op": "op1", "values": ["value1","value2"]},
...
]
}'
说明:
创建 DP 输入的 JSON 字符串需要指定 policy_name 和 constraints,constraints 可包含多条如前文所述的 DP 规则。

修改 Distribution Policy

./mc-ctl dp modify --data
'{
"policy_id": $id,
"policy_name":"$name",
"constraints":[
{"key": "key1", "op": "op1", "values": ["value1","value2"]},
...
]
}'

注意:
修改 DP 输入的 JSON 字符串要指定 policy_id,同时需要指定需要修改的 policy_name 或 constraints。只有未绑定数据对象的 DP 规则可以被修改,如果需要修改已绑定数据对象的 DP,需要先解除数据对象与 DP 的绑定。

删除 Distribution Policy

# 通过 ID 删除
./mc-ctl dp delete --distribution_policy_id ${id}
# 通过 distribution policy name 删除
./mc-ctl dp delete --distribution_policy_name ${policy_name}
注意:
DP 可以通过 distribution_policy_id 或 distribution_policy_name 删除。只有未绑定数据对象的 DP 规则可以被删除,如果需要删除已绑定数据对象的 DP,需要先解除数据对象与 DP 的绑定。

查看 Distribution Policy

# 查看已创建的所有 DP
./mc-ctl dp info all
# 通过 distribution policy name 查看单条 DP
./mc-ctl dp info single --distribution_policy_name ${policy_name}

数据对象绑定 DP

在创建 DP 完成之后,可将数据对象与 DP 绑定,从而达到对应的调度效果。

数据库绑定 DP

CREATE DATABASE db1 USING distribution policy ${policy_name};

单表绑定 DP

CREATE TABLE t1(INT) USING distribution policy ${policy_name}; 

分区表绑定 DP

CREATE TABLE t1(INT) PARTITION BY HASH(a) PARTITIONS 4 USING distribution policy ${policy_name};
说明:
DP 在数据对象中遵循继承规则。例如上述例子中,创建数据库 db1 并绑定 DP 后,在该数据库中创建的所有单表和分区表都将使用与数据库相同的 DP,但如果直接对该数据库中的一张表绑定另一种 DP,其优先级高于继承规则。

典型 DP 示例

场景1:创建一个5副本的 DP。
./mc-ctl dp create --data '{"policy_name": "policy_1", "constraints": [{"key": "replica-count", "op": "=", "values": ["5"]}]}'
场景2:创建一个4副本并包含一个 learner 的 DP。
./mc-ctl dp create --data '{"policy_name": "policy_2", "constraints": [{"key": "replica-count", "op": "=", "values": ["4"]}, {"key": "learner-count", "op": "=", "values": ["1"]}]}'
场景3:创建一个副本位于 node-001, node-002, node-003 节点,且 RG Leader 位于 node-001 节点的 DP。
./mc-ctl dp create --data '{"policy_name": "policy_3", "constraints": [
{"key": "node", "op": "in", "values": ["node-001", "node-002", "node-003"]},
{
"key": "leader-preferences", "op": "=", "values": [
"{\\"key\\": \\"node\\", \\"op\\": \\"in\\", \\"values\\": [\\"node-001\\"]}"
]
}]}'
场景4:创建一个副本放置于磁盘类型是 SSD 的 DP。
./mc-ctl dp create --data '{"policy_name": "policy_4", "constraints": [{"key": "tdsql-storage-type", "op": "in", "values": ["SSD"]}]}'

使用 SQL 创建 Distribution Policy

v21.2.3版本提供了 SQL 语法用于创建 Distribution Policy。使用 SQL 创建 DP 在语法设计上尽量贴合了 mc-ctl 的用法,避免用户二次学习成本。具体的用法如下:
SQL in DP 中与规则 key 相关的关键字有:
REGION, ZONE, RACK, HOST, NODE, REPLICA_COUNT, FOLLOWER_COUNT, LEARNER_COUNT, WITNESS_COUNT, STORAGE_TYPE
FAULT_TOLERANCE_LEVEL, LEADER_PREFERENCES
op 相关的关键字有:
IN, NOT IN, EXISTS, NOT EXISTS

SQL 创建 Distribution Policy

# 创建一条副本需要放置在 zone1 和 zone2 的可用区上并且副本数为 2 的 DP
CREATE DISTRIBUTION POLICY "policy_1" SET ZONE IN ("zone1", "zone2") AND REPLICA_COUNT = 2;

SQL 修改 Distribution Policy

# 将名称为 "policy_1" 的 DP 约束修改为:副本需要放置在磁盘类型为 "SSD" 的磁盘上
ALTER DISTRIBUTION POLICY "policy_1" SET STORAGE_TYPE IN ("SSD");

# 将 DP "old_dp_name" 的名称修改为 "new_dp_name"
RENAME DISTRIBUTION POLICY "old_dp_name" TO "new_dp_name";

SQL 删除 Distribution Policy

# 将名称为 "policy_1" 的 DP 删除
DROP DISTRIBUTION POLICY "policy_1";

SQL 查询 Distribution Policy

information_schema 中新增了视图 META_CLUSTER_DPS,表结构如下:

使用该视图可以实时查询已有的 DP。

高级特性

v21.2.3版本提供了一种高级 DP 特性,RANGE 和 RANGE COLUMNS 并以时间类型为分区键的分区表可以绑定该种高级 DP,其效果可以让分区表的部分分区在指定时间后再进行调度,一种典型的场景是自动对分区进行落冷,以下是具体介绍:
使用 SQL 创建如下 DP
CREATE DISTRIBUTION POLICY "policy_x" SET PARTITION_METHOD = "RANGE" AND
PARTITION_KEY_TO_TIME_TYPE = "predefined:TO_DAYS" AND
EXPIRE = "1 YEAR" AND
START_TIME = "2024-06-11 00:11:22" AND
END_TIME = "2025-06-11 00:11:22" AND
STORAGE_TYPE IN ("HDD");
这条 DP 中的几个关键字解释如下:
PARTITION_METHOD:表示 DP 支持的分区表所对应的分区方式,目前仅支持 RANGERANGE COLUMNS
PARTITION_KEY_TO_TIME_TYPE:仅在RANGE分区方式时需要指定,用来将分区边界值转换为时间类型。该 key 对应的 values 是转换函数,系统提供了三个预定义的转换函数,即 TO_DAYS, UNIX_TIMESTAMPYEAR。用户也可自定义转换函数,自定义函数需要给出年月日时分秒的计算公式,遵从的格式为:year/month/day/hour/minute/second:(含有标识符 v 的数学公式),其中v是标识符,表示的是分区边界的整型值。如将 values 设置为 ["year:v/100", "month:v%100"],省略的 day/hour/minute/second 则按照对应时间单位的零值处理。
EXPIRE:分区过期时间,正整数 + 单位的格式,如 1 YEAR 。可用单位有:YEAR, MONTH, DAY, HOUR
START_TIME:非必选项,默认为分区的起始,如指定这一项,则表示从这个时间之后开始应用 DP 规则。
END_TIME:非必选项,默认为分区的结束,如指定这一项,则表示从这个时间之后拒绝应用 DP 规则。
注意:
1. 仅支持一级 RANGE 和 RANGE COLUMNS 分区使用相关特性,其分区键也必须是时间类型。
2. RANGE COLUMNS 分区仅支持一个分区列。

案例说明

案例1:基于 UNIX_TIMESTAMP 的自动冷数据归档

# 使用预定义函数 UNIX_TIMESTAMP 创建 policy_x1
CREATE DISTRIBUTION POLICY "policy_x1" SET PARTITION_METHOD = "RANGE" AND
PARTITION_KEY_TO_TIME_TYPE = ("predefined:UNIX_TIMESTAMP") AND
EXPIRE = "1 MONTH" AND
STORAGE_TYPE IN ("HDD");

# 创建 RANGE 分区表并绑定 policy_x1
CREATE TABLE t_order_1(
id bigint NOT NULL,
gmt_modified timestamp NOT NULL)
PARTITION BY RANGE(unix_timestamp(gmt_modified))(
PARTITION p1 VALUES LESS THAN(unix_timestamp('2025-11-11')),
PARTITION p2 VALUES LESS THAN(unix_timestamp('2025-12-11'))
) USING DISTRIBUTION POLICY policy_x1;
调度行为说明
p1 分区调度
分区边界时间:2025-11-11
过期时间偏移:1个月
调度触发时间:2025-11-11 + 1个月 = 2025-12-11
调度动作:将 p1 分区的数据副本迁移到 HDD 存储
p2 分区调度
分区边界时间:2025-12-11
过期时间偏移:1个月
调度触发时间:2025-12-11 + 1个月 = 2026-01-11
调度动作:将 p2 分区的数据副本迁移到 HDD 存储

案例2:自定义时间转换函数的精确调度控制

# 使用自定义函数创建 policy_x2
CREATE DISTRIBUTION POLICY "policy_x2" SET PARTITION_METHOD = "RANGE" AND
PARTITION_KEY_TO_TIME_TYPE = ("year:v/100", "month:v%100") AND
EXPIRE = "1 MONTH" AND
LEADER_PREFERENCES = (ZONE in ("zone1")) AND
START_TIME = "2025-12-10 00:00:00";

# 创建 RANGE 分区表并绑定 policy_x2
CREATE TABLE t_order_2(
id bigint NOT NULL,
gmt_modified datetime NOT NULL)
PARTITION BY RANGE(YEAR(gmt_modified) * 100 + MONTH(gmt_modified))(
PARTITION p1 VALUES LESS THAN(202511),
PARTITION p2 VALUES LESS THAN(202512),
PARTITION p3 VALUES LESS THAN(202601)
) USING DISTRIBUTION POLICY policy_x2;
转换函数解析
自定义函数: year:v/100, month:v%100

分区边界值 v = YEAR(gmt_modified) * 100 + MONTH(gmt_modified)

示例计算:
- p1: v=202511 → year=202511/100=2025, month=202511%100=11
- p2: v=202512 → year=202512/100=2025, month=202512%100=12
- p3: v=202601 → year=202601/100=2026, month=202601%100=1
分区时间边界计算
分区
边界值
转换后时间
调度触发时间
是否受约束
p1
202511
2025-11-01 00:00:00
2025-12-01 00:00:00
不受约束
p2
202512
2025-12-01 00:00:00
2026-01-01 00:00:00
不受约束
p3
202601
2026-01-01 00:00:00
2026-02-01 00:00:00
受约束
START_TIME 影响分析
START_TIME = "2025-12-10 00:00:00"
只有分区边界时间 ≥ START_TIME 的分区才会应用 DP 约束
p1(2025-11-01) 和 p2(2025-12-01) < START_TIME(2025-12-10) → 不受约束
p3(2026-01-01) > START_TIME(2025-12-10) → 受约束

案例3:RANGE COLUMNS 分区的时间窗口调度

# 创建 policy_x3
CREATE DISTRIBUTION POLICY "policy_x3" SET PARTITION_METHOD = "RANGE COLUMNS" AND
EXPIRE = "1 YEAR" AND
NODE NOT IN ("node-tdsql3-x-001") AND
START_TIME = "2025-12-10 00:00:00" AND
END_TIME = "2026-12-10 00:00:00";

# 创建 RANGE COLUMNS 分区表并绑定 policy_x3
CREATE TABLE t_order_3(
id bigint NOT NULL,
gmt_modified datetime NOT NULL)
PARTITION BY RANGE COLUMNS(gmt_modified)(
PARTITION p1 VALUES LESS THAN("2024-12-10 00:00:00"),
PARTITION p2 VALUES LESS THAN("2025-12-10 00:00:00"),
PARTITION p3 VALUES LESS THAN("2026-12-10 00:00:00"),
PARTITION p4 VALUES LESS THAN("2027-12-10 00:00:00")
) USING DISTRIBUTION POLICY policy_x3;
由于是 RANGE COLUMNS 时间分区绑定的 DP,因此不需要使用 PARTITION_KEY_TO_TIME_TYPE 字段给出转换函数,因为此时分区边界已经是时间类型的值了。同时由于指定了 START_TIME 和 END_TIME,因此只有 p2 和 p3 分区会在到达分区边界时间的一年(EXPIRE = "1 YEAR")后发起调度。
分区
边界时间
调度触发时间
是否在时间窗口内
p1
2024-12-10
2025-12-10
早于 START_TIME
p2
2025-12-10
2026-12-10
在 [START_TIME, END_TIME] 内
p3
2026-12-10
2027-12-10
在 [START_TIME, END_TIME] 内
p4
2027-12-10
2028-12-10
晚于 END_TIME

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈