Placement Rules in SQL

Placement Rules in SQL 特性用于通过 SQL 接口配置数据在 TiKV 集群中的放置位置。通过该功能,用户可以将表和分区指定部署至不同的地域、机房、机柜、主机。适用场景包括低成本优化数据高可用策略、保证本地的数据副本可用于本地 Stale Read 读取、遵守数据本地要求等。

Placement Rules in SQL - 图1

注意

Placement Rules in SQL 底层的实现依赖 PD 提供的放置规则 (placement rules) 功能,参考 Placement Rules 使用文档。在 Placement Rules in SQL 语境下,放置规则既可以代指绑定对象的放置策略 (placement policy),也可以代指 TiDB 发给 PD 的放置规则。

该功能可以实现以下业务场景:

  • 合并多个不同业务的数据库,大幅减少数据库常规运维管理的成本
  • 增加重要数据的副本数,提高业务可用性和数据可靠性
  • 将最新数据存入 NVMe,历史数据存入 SSD,降低归档数据存储成本
  • 把热点数据的 leader 放到高性能的 TiKV 实例上
  • 将冷数据分离到不同的存储中以提高可用性
  • 支持物理隔离不同用户之间的计算资源,满足实例内部不同用户的隔离需求,以及不同混合负载 CPU、I/O、内存等资源隔离的需求

指定放置规则

指定放置规则,首先需要通过 CREATE PLACEMENT POLICY 语句创建放置策略 (placement policy)

  1. CREATE PLACEMENT POLICY myplacementpolicy PRIMARY_REGION="us-east-1" REGIONS="us-east-1,us-west-1";

然后可以使用 CREATE TABLE 或者 ALTER TABLE 将规则绑定至表或分区表,这样就在表或分区上指定了放置规则:

  1. CREATE TABLE t1 (a INT) PLACEMENT POLICY=myplacementpolicy;
  2. CREATE TABLE t2 (a INT);
  3. ALTER TABLE t2 PLACEMENT POLICY=myplacementpolicy;

PLACEMENT POLICY 为全局作用域,不与任何数据库表结构相关联。因此,通过 CREATE TABLE 指定放置规则时,无需任何额外的权限。

要修改放置策略,你可以使用 ALTER PLACEMENT POLICY 语句。修改将传播到所有绑定此放置策略的对象。

  1. ALTER PLACEMENT POLICY myplacementpolicy FOLLOWERS=5;

要删除没有绑定任何分区或表的放置策略,你可以使用 DROP PLACEMENT POLICY

  1. DROP PLACEMENT POLICY myplacementpolicy;

查看放置规则

如果一张表绑定了放置规则,你可以用 SHOW CREATE TABLE 来查看。还可以用 SHOW CREATE PLACEMENT POLICY 来查看已经创建的放置策略。

  1. tidb> SHOW CREATE TABLE t1\G
  2. *************************** 1. row ***************************
  3. Table: t1
  4. Create Table: CREATE TABLE `t1` (
  5. `a` int(11) DEFAULT NULL
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`myplacementpolicy` */
  7. 1 row in set (0.00 sec)
  8. tidb> SHOW CREATE PLACEMENT POLICY myplacementpolicy\G
  9. *************************** 1. row ***************************
  10. Policy: myplacementpolicy
  11. Create Policy: CREATE PLACEMENT POLICY myplacementpolicy PRIMARY_REGION="us-east-1" REGIONS="us-east-1,us-west-1"
  12. 1 row in set (0.00 sec)

你也可以用 INFORMATION_SCHEMA.PLACEMENT_POLICIES 系统表查看所有放置策略的定义。

  1. tidb> select * from information_schema.placement_policies\G
  2. ***************************[ 1. row ]***************************
  3. POLICY_ID | 1
  4. CATALOG_NAME | def
  5. POLICY_NAME | p1
  6. PRIMARY_REGION | us-east-1
  7. REGIONS | us-east-1,us-west-1
  8. CONSTRAINTS |
  9. LEADER_CONSTRAINTS |
  10. FOLLOWER_CONSTRAINTS |
  11. LEARNER_CONSTRAINTS |
  12. SCHEDULE |
  13. FOLLOWERS | 4
  14. LEARNERS | 0
  15. 1 row in set

information_schema.tables 表和 information_schema.partitions 表也有一列 tidb_placement_policy_name,用于展示所有绑定了放置规则的对象:

  1. SELECT * FROM information_schema.tables WHERE tidb_placement_policy_name IS NOT NULL;
  2. SELECT * FROM information_schema.partitions WHERE tidb_placement_policy_name IS NOT NULL;

所有绑定规则的对象都是异步调度的。可以用 SHOW PLACEMENT 来查看放置规则的调度进度。

放置选项参考

Placement Rules in SQL - 图2

注意

  • 放置选项依赖于正确地指定在每个 TiKV 节点配置中的标签 (label)。例如,PRIMARY_REGION 选项依赖 TiKV 中的 region 标签。若要查看当前 TiKV 集群中所有可用的标签,可执行 SHOW PLACEMENT LABELS 语句。

    1. mysql> show placement labels;
    2. +--------+----------------+
    3. | Key | Values |
    4. +--------+----------------+
    5. | disk | ["ssd"] |
    6. | region | ["us-east-1"] |
    7. | zone | ["us-east-1a"] |
    8. +--------+----------------+
    9. 3 rows in set (0.00 sec)
  • 使用 CREATE PLACEMENT POLICY 创建放置规则时,TiDB 不会检查标签是否存在,而是在绑定表的时候进行检查。

选项名描述
PRIMARY_REGIONRaft leader 被放置在有 region 标签的节点上,且这些 region 标签匹配本选项的值。
REGIONSRaft followers 被放置在有 region 标签的节点上,且这些 region 标签匹配本选项的值。
SCHEDULE用于调度 follower 放置位置的策略。可选值为 EVEN(默认值)或 MAJORITY_IN_PRIMARY
FOLLOWERSFollower 的数量。例如 FOLLOWERS=2 表示数据有 3 个副本(2 个 follower 和 1 个 leader)。

除以上配置选项外,你还可以使用高级配置,详细介绍见高级放置选项

选项名描述
CONSTRAINTS适用于所有角色 (role) 的约束列表。例如,CONSTRAINTS=”[+disk=ssd]”
LEADER_CONSTRAINTS仅适用于 leader 的约束列表。
FOLLOWER_CONSTRAINTS仅适用于 follower 的约束列表。
LEARNER_CONSTRAINTS仅适用于 learner 的约束列表。
LEARNERS指定 learner 的数量。
SURVIVAL_PREFERENCE指定按 label 容灾等级的优先级放置副本。例如 SURVIVAL_PREFERENCE=”[region, zone, host]”

示例

增加副本数

max-replicas 配置项的默认值为 3。如要为特定的表调大该值,可使用配置策略,示例如下:

  1. CREATE PLACEMENT POLICY fivereplicas FOLLOWERS=4;
  2. CREATE TABLE t1 (a INT) PLACEMENT POLICY=fivereplicas;

注意,PD 配置中包含了 leader 数和 follower 数。因此,5 个副本为 4 个 follower + 1 个 leader。

对于以上示例,你还可使用 PRIMARY_REGIONREGIONS 选项来描述 follower 的放置规则:

  1. CREATE PLACEMENT POLICY eastandwest PRIMARY_REGION="us-east-1" REGIONS="us-east-1,us-east-2,us-west-1" SCHEDULE="MAJORITY_IN_PRIMARY" FOLLOWERS=4;
  2. CREATE TABLE t1 (a INT) PLACEMENT POLICY=eastandwest;

SCHEDULE 选项指示 TiDB 如何平衡 follower。该选项默认的 EVEN 调度规则确保 follower 在所有区域内分布平衡。

如要保证在主区域内 (us-east-1) 放置足够多的 follower 副本,你可以使用 MAJORITY_IN_PRIMARY 调度规则来使该区域的 follower 达到指定数量。该调度牺牲一些可用性来换取更低的事务延迟。如果主区域宕机,MAJORITY_IN_PRIMARY 无法提供自动故障转移。

为分区表指定放置规则

除了给表绑定放置策略之外,你还可以给表分区绑定放置策略。示例如下:

  1. CREATE PLACEMENT POLICY p1 FOLLOWERS=5;
  2. CREATE PLACEMENT POLICY europe PRIMARY_REGION="eu-central-1" REGIONS="eu-central-1,eu-west-1";
  3. CREATE PLACEMENT POLICY northamerica PRIMARY_REGION="us-east-1" REGIONS="us-east-1";
  4. SET tidb_enable_list_partition = 1;
  5. CREATE TABLE t1 (
  6. country VARCHAR(10) NOT NULL,
  7. userdata VARCHAR(100) NOT NULL
  8. ) PLACEMENT POLICY=p1 PARTITION BY LIST COLUMNS (country) (
  9. PARTITION pEurope VALUES IN ('DE', 'FR', 'GB') PLACEMENT POLICY=europe,
  10. PARTITION pNorthAmerica VALUES IN ('US', 'CA', 'MX') PLACEMENT POLICY=northamerica,
  11. PARTITION pAsia VALUES IN ('CN', 'KR', 'JP')
  12. );

如果分区没有绑定任何放置策略,分区将尝试继承表上可能存在的策略。比如,pEurope 分区将会应用 europe 策略,而 pAsia 分区将会应用表 t1 的放置策略 p1。如果 t1 没有绑定任何策略,pAsia 就不会应用任何策略。

给分区绑定放置策略后,你可以更改指定分区的放置策略。示例如下:

  1. ALTER TABLE t1 PARTITION pEurope PLACEMENT POLICY=p1;

为数据库配置默认的放置规则

你可以为某个数据库指定默认的放置策略,类似于为数据库设置默认字符集或排序规则。如果没有指定其他选项,就会使用数据库上指定的配置。示例如下:

  1. CREATE PLACEMENT POLICY p1 PRIMARY_REGION="us-east-1" REGIONS="us-east-1,us-east-2"; -- 创建放置策略
  2. CREATE PLACEMENT POLICY p2 FOLLOWERS=4;
  3. CREATE PLACEMENT POLICY p3 FOLLOWERS=2;
  4. CREATE TABLE t1 (a INT); -- 创建表 t1,且未指定放置规则。
  5. ALTER DATABASE test PLACEMENT POLICY=p2; -- 更改默认的放置规则,但更改不影响已有的表 t1
  6. CREATE TABLE t2 (a INT); -- 创建表 t2,默认的放置策略 p2 t2 上生效。
  7. CREATE TABLE t3 (a INT) PLACEMENT POLICY=p1; -- 创建表 t3。因为语句中已经指定了其他放置规则,默认的 p2 策略在 t3 上不生效。
  8. ALTER DATABASE test PLACEMENT POLICY=p3; -- 再次更改默认的放置规则,此更改不影响已有的表。
  9. CREATE TABLE t4 (a INT); -- 创建表 t4,默认的放置策略 p3 生效。
  10. ALTER PLACEMENT POLICY p3 FOLLOWERS=3; -- 绑定策略 p3 的表,也就是 t4,会采用 FOLLOWERS=3

注意分区与表之间的继承和这里的继承不同。改变表的放置策略,也会让分区应用新的策略。但是只有建表时没有指定放置策略的时候,表才会从数据库继承放置策略,且之后再改变数据库也不影响已经继承的表。

高级放置选项

放置选项 PRIMARY_REGIONREGIONSSCHEDULE 可满足数据放置的基本需求,但会缺乏一些灵活性。在较复杂的场景下,若需要更灵活地放置数据,可以使用高级放置选项 CONSTRAINTSFOLLOWER_CONSTRAINTSPRIMARY_REGIONREGIONSSCHEDULE 选项不可与 CONSTRAINTS 选项同时指定,否则会报错。

以下示例设置了一个约束,要求数据必须位于某个 TiKV 节点,且该节点的 disk 标签必须匹配特定的值:

  1. CREATE PLACEMENT POLICY storageonnvme CONSTRAINTS="[+disk=nvme]";
  2. CREATE PLACEMENT POLICY storageonssd CONSTRAINTS="[+disk=ssd]";
  3. CREATE PLACEMENT POLICY companystandardpolicy CONSTRAINTS="";
  4. CREATE TABLE t1 (id INT, name VARCHAR(50), purchased DATE)
  5. PLACEMENT POLICY=companystandardpolicy
  6. PARTITION BY RANGE( YEAR(purchased) ) (
  7. PARTITION p0 VALUES LESS THAN (2000) PLACEMENT POLICY=storageonssd,
  8. PARTITION p1 VALUES LESS THAN (2005),
  9. PARTITION p2 VALUES LESS THAN (2010),
  10. PARTITION p3 VALUES LESS THAN (2015),
  11. PARTITION p4 VALUES LESS THAN MAXVALUE PLACEMENT POLICY=storageonnvme
  12. );

该约束可通过列表格式 ([+disk=ssd]) 或字典格式 ({+disk=ssd: 1,+disk=nvme: 2}) 指定。

在列表格式中,约束以键值对列表格式。键以 +- 开头。+disk=nvme 表示 disk 标签必须设为 nvme-disk=nvme 表示 disk 标签值不能为 nvme

在字典格式中,约束还指定了适用于该规则的多个实例。例如,FOLLOWER_CONSTRAINTS="{+region=us-east-1: 1,+region=us-east-2: 1,+region=us-west-1: 1}"; 表示 1 个 follower 位于 us-east-1,1 个 follower 位于 us-east-2,1 个 follower 位于 us-west-1。再例如,FOLLOWER_CONSTRAINTS='{"+region=us-east-1,+disk=nvme": 1,"+region=us-west-1": 1}'; 表示 1 个 follower 位于 us-east-1 区域中有 nvme 硬盘的机器上,1 个 follower 位于 us-west-1

Placement Rules in SQL - 图3

注意

字典和列表格式都基于 YAML 解析,但 YAML 语法有些时候不能被正常解析。例如 YAML 会把 "{+disk=ssd:1,+disk=nvme:2}": 后无空格)错误地解析成 '{"+disk=ssd:1": null, "+disk=nvme:2": null}',不符合预期。但 "{+disk=ssd: 1,+disk=nvme: 2}": 后有空格)能被正确解析成 '{"+disk=ssd": 1, "+disk=nvme": 2}'

生存偏好

在创建或修改放置策略时,你可以使用 SURVIVAL_PREFERENCES 选项设置数据的生存能力偏好。

例如,假设你的 TiDB 集群分布在 3 个 zone(即可用区),且每个可用区的 host(即节点)上混合部署了多个 TiKV 实例。在为该集群创建放置策略时,假设 SURVIVAL_PREFERENCES 的设置如下:

  1. CREATE PLACEMENT POLICY multiaz SURVIVAL_PREFERENCES="[zone, host]";
  2. CREATE PLACEMENT POLICY singleaz CONSTRAINTS="[+zone=zone1]" SURVIVAL_PREFERENCES="[host]";

创建好放置策略后,你可以按需将放置策略绑定到对应的表上:

  • 对于绑定了 multiaz 放置策略的表,数据将以 3 副本的形式放置在不同的可用区里,优先满足跨 zone 级别数据隔离的生存目标,再满足跨 host 级别的数据隔离的生存目标。
  • 对于绑定了 singleaz 放置策略的表,数据会优先以 3 副本的形式全部放置在 zone1 这个可用区里,再满足跨 host 级别的数据隔离的生存目标。

Placement Rules in SQL - 图4

注意

SURVIVAL_PREFERENCES 和 PD 中的 location-labels 是等价的,更多信息可以参考通过拓扑 label 进行副本调度

工具兼容性

工具名称最低兼容版本说明
Backup & Restore (BR)6.0BR 在 v6.0 之前不支持放置规则的备份与恢复,见恢复 Placement Rule 到集群时为什么会报错?
TiDB Lightning暂时不兼容导入包含放置策略的数据时会报错
TiCDC6.0忽略放置规则,不同步规则到下游集群
TiDB Binlog6.0忽略放置规则,不同步规则到下游集群

使用限制

目前已知 Placement Rules in SQL 特性存在以下限制:

  • 临时表不支持放置规则。
  • 设置 PRIMARY_REGIONREGIONS 时允许存在语法糖。但在未来版本中,我们计划为 PRIMARY_RACKPRIMARY_ZONEPRIMARY_HOST 添加变体支持,见 issue #18030
  • 放置规则仅保证静态数据被放置在正确的 TiKV 节点上。该规则不保证传输中的数据(通过用户查询或内部操作)只出现在特定区域内。