From ebc6c2e5af028d8eb236f57efde95073ef99ca53 Mon Sep 17 00:00:00 2001 From: xhe Date: Mon, 16 Mar 2026 17:27:28 +0800 Subject: [PATCH] sql: new syntax persist policies of splitting regions for tables Signed-off-by: xhe --- sql-statements/sql-statement-alter-table.md | 25 +++++++++++ sql-statements/sql-statement-create-table.md | 47 ++++++++++++++++++++ sql-statements/sql-statement-split-region.md | 27 +++++++++++ 3 files changed, 99 insertions(+) diff --git a/sql-statements/sql-statement-alter-table.md b/sql-statements/sql-statement-alter-table.md index a3975fbc0728..f285f609732d 100644 --- a/sql-statements/sql-statement-alter-table.md +++ b/sql-statements/sql-statement-alter-table.md @@ -57,6 +57,13 @@ AlterTableSpec ::= ) | 'AFFINITY' EqOpt stringLit | PlacementPolicyOption +| 'SPLIT' ('INDEX' IndexName | PRIMARY KEY)? 'BETWEEN' RowValue 'AND' RowValue 'REGIONS' NUM + +RowValue ::= + '(' ValuesOpt ')' + +ValuesOpt ::= + ( LiteralValue | Expr ) (',' (LiteralValue | Expr) )* PlacementPolicyOption ::= "PLACEMENT" "POLICY" EqOpt PolicyName @@ -162,6 +169,24 @@ Query OK, 0 rows affected, 1 warning (0.25 sec) 1 row in set (0.00 sec) ``` +修改已有表的持久化区域分割策略: + +{{< copyable "sql" >}} + +```sql +ALTER TABLE orders + SPLIT BETWEEN (0) AND (2000000) REGIONS 32 + SPLIT INDEX idx_customer BETWEEN (0) AND (20000) REGIONS 16; +``` + +```sql +Query OK, 0 rows affected (3.56 sec) +``` + +> **注意:** +> - 分区表的每个分区都遵循表的持久化分割策略 +> - 聚集索引表不允许对主键指定分割策略 + ## MySQL 兼容性 TiDB 中的 `ALTER TABLE` 语法主要存在以下限制: diff --git a/sql-statements/sql-statement-create-table.md b/sql-statements/sql-statement-create-table.md index 37a8e152c858..bd82b55780ad 100644 --- a/sql-statements/sql-statement-create-table.md +++ b/sql-statements/sql-statement-create-table.md @@ -120,6 +120,13 @@ TableOption ::= | 'TTL' EqOpt TimeColumnName '+' 'INTERVAL' Expression TimeUnit (TTLEnable EqOpt ( 'ON' | 'OFF' ))? (TTLJobInterval EqOpt stringLit)? | 'AFFINITY' EqOpt StringName | PlacementPolicyOption +| 'SPLIT' ('INDEX' IndexName | PRIMARY KEY )? 'BETWEEN' RowValue 'AND' RowValue 'REGIONS' NUM + +RowValue ::= + '(' ValuesOpt ')' + +ValuesOpt ::= + ( LiteralValue | Expr ) (',' (LiteralValue | Expr) )* OnCommitOpt ::= ('ON' 'COMMIT' 'DELETE' 'ROWS')? @@ -174,6 +181,9 @@ TiDB 支持以下 `table_option`。TiDB 会解析并忽略其他 `table_option` |`COLLATE` |指定该表所使用的字符集排序规则 | `COLLATE` = 'utf8mb4_bin'| |`COMMENT` |注释信息 | `COMMENT` = 'comment info'| |`AFFINITY` |为表或分区开启亲和性调度。非分区表可设置为 `'table'`,分区表可设置为 `'partition'`。设置为 `'none'` 或留空可关闭亲和性调度 |`AFFINITY` = 'table'| +|`SPLIT BETWEEN lower AND upper REGIONS N`|指定表的持久化区域分割策略,在指定范围内均匀切分 N 个 Region。该策略会保存到表定义中,进行 DDL 后会自动执行区域分割 |`SPLIT BETWEEN (0) AND (1000000) REGIONS 16`| +|`SPLIT INDEX idx_name BETWEEN lower AND upper REGIONS N`|指定单个索引的持久化区域分割策略,在指定范围内均匀切分 N 个 Region |`SPLIT INDEX idx_name BETWEEN (0) AND (100000) REGIONS 8`| +|`SPLIT PRIMARY KEY BETWEEN lower AND upper REGIONS N`|指定主键索引的持久化区域分割策略,在指定范围内均匀切分 N 个 Region |`SPLIT INDEX idx_name BETWEEN (0) AND (100000) REGIONS 8`| > **注意:** > @@ -260,6 +270,43 @@ mysql> DESC t1; 2 rows in set (0.00 sec) ``` +创建表时指定持久化区域分割策略: + +{{< copyable "sql" >}} + +```sql +CREATE TABLE orders ( + order_id BIGINT PRIMARY KEY, + customer_id INT, + order_date DATE, + INDEX idx_customer(customer_id), + INDEX idx_date(order_date) +) SPLIT BETWEEN (0) AND (1000000) REGIONS 16 + SPLIT BETWEEN (0) AND (10000) REGIONS 10 INDEX idx_customer + SPLIT BETWEEN ('2020-01-01') AND ('2025-01-01') REGIONS 20 INDEX idx_date; +``` + +```sql +mysql> CREATE TABLE orders ( + -> order_id BIGINT PRIMARY KEY, + -> customer_id INT, + -> order_date DATE, + -> INDEX idx_customer(customer_id), + -> INDEX idx_date(order_date) + -> ) SPLIT BETWEEN (0) AND (1000000) REGIONS 16 + -> SPLIT BETWEEN (0) AND (10000) REGIONS 10 INDEX idx_customer + -> SPLIT BETWEEN ('2020-01-01') AND ('2025-01-01') REGIONS 20 INDEX idx_date; +Query OK, 0 rows affected (2.35 sec) +``` + +> **注意:** +> +> - 持久化区域分割策略与 `PRE_SPLIT_REGIONS` 的区别: +> - `PRE_SPLIT_REGIONS` 基于 `SHARD_ROW_ID_BITS` 或 `AUTO_RANDOM` 自动计算分割点,只能进行 2 的幂次方个 Region 分割 +> - `SPLIT BETWEEN ... AND ... REGIONS` 允许指定任意范围和任意数量的 Region 分割,与 `SPLIT TABLE` 类似 +> - 分区表的每个分区都遵循表的持久化分割策略 +> - 聚集索引表不允许对主键指定分割策略 + ## MySQL 兼容性 * 支持除空间类型以外的所有数据类型。 diff --git a/sql-statements/sql-statement-split-region.md b/sql-statements/sql-statement-split-region.md index b6a766519b07..d7d1ad574b09 100644 --- a/sql-statements/sql-statement-split-region.md +++ b/sql-statements/sql-statement-split-region.md @@ -378,6 +378,31 @@ region3: [ 2<<61 , 3<<61 ) region4: [ 3<<61 , +inf ) ``` +## 持久化区域分割策略 + +TiDB 从 v9.0.0 版本开始引入了持久化区域分割策略,允许在 `CREATE TABLE` 和 `ALTER TABLE` 语句中通过 `SPLIT BETWEEN ... AND ... REGIONS` 子句定义区域分割规则。与 `SPLIT TABLE` 语句的临时分割不同,持久化分割策略会保存在表定义中,可以避免分区表重复手动操作。 + +```sql +-- 创建表时定义持久化分割策略 +CREATE TABLE orders ( + order_id BIGINT PRIMARY KEY, + customer_id INT, + order_date DATE, + INDEX idx_customer(customer_id), + INDEX idx_date(order_date) +) SPLIT BETWEEN (0) AND (1000000) REGIONS 16 + SPLIT INDEX `idx_customer` BETWEEN (0) AND (10000) REGIONS 10 + SPLIT INDEX `idx_date` BETWEEN ('2020-01-01') AND ('2025-01-01') REGIONS 20; + +-- 修改已有表的分割策略 +ALTER TABLE orders + SPLIT BETWEEN (0) AND (2000000) REGIONS 32 + SPLIT INDEX `idx_customer` BETWEEN (0) AND (20000) REGIONS 16; + +-- 查看持久化分割策略 +SHOW CREATE TABLE orders\G +``` + ## 注意事项 Split Region 语句切分的 Region 会受到 PD 中 [Region merge](/best-practices/pd-scheduling-best-practices.md#region-merge) 调度的控制,需要使用[表属性](/table-attributes.md)或者[动态修改](/pd-control.md) Region merge 相关的配置项,避免新切分的 Region 不久后又被 PD 重新合并的情况。 @@ -389,5 +414,7 @@ Split Region 语句切分的 Region 会受到 PD 中 [Region merge](/best-practi ## 另请参阅 * [SHOW TABLE REGIONS](/sql-statements/sql-statement-show-table-regions.md) +* [CREATE TABLE](/sql-statements/sql-statement-create-table.md) +* [ALTER TABLE](/sql-statements/sql-statement-alter-table.md) * Session 变量:[`tidb_scatter_region`](/system-variables.md#tidb_scatter_region),[`tidb_wait_split_region_finish`](/system-variables.md#tidb_wait_split_region_finish) 和[`tidb_wait_split_region_timeout`](/system-variables.md#tidb_wait_split_region_timeout).