diff --git a/TOC.md b/TOC.md index 79adf0d7ef7f..6c170c7c72ee 100644 --- a/TOC.md +++ b/TOC.md @@ -882,6 +882,7 @@ - [`SET ROLE`](/sql-statements/sql-statement-set-role.md) - [`SET TRANSACTION`](/sql-statements/sql-statement-set-transaction.md) - [`SET `](/sql-statements/sql-statement-set-variable.md) + - [`SHOW AFFINITY`](/sql-statements/sql-statement-show-affinity.md) - [`SHOW [BACKUPS|RESTORES]`](/sql-statements/sql-statement-show-backups.md) - [`SHOW ANALYZE STATUS`](/sql-statements/sql-statement-show-analyze-status.md) - [`SHOW BINDINGS`](/sql-statements/sql-statement-show-bindings.md) @@ -999,6 +1000,7 @@ - [临时表](/temporary-tables.md) - [缓存表](/cached-tables.md) - [外键约束](/foreign-key.md) + - [表级数据亲和性](/table-affinity.md) - 字符集和排序规则 - [概述](/character-set-and-collation.md) - [GBK](/character-set-gbk.md) diff --git a/information-schema/information-schema-partitions.md b/information-schema/information-schema-partitions.md index 007113f7b1b1..3c5235f15309 100644 --- a/information-schema/information-schema-partitions.md +++ b/information-schema/information-schema-partitions.md @@ -45,8 +45,9 @@ DESC PARTITIONS; | TABLESPACE_NAME | varchar(64) | YES | | NULL | | | TIDB_PARTITION_ID | bigint(21) | YES | | NULL | | | TIDB_PLACEMENT_POLICY_NAME | varchar(64) | YES | | NULL | | +| TIDB_AFFINITY | varchar(128) | YES | | NULL | | +-------------------------------+--------------+------+------+---------+-------+ -27 rows in set (0.00 sec) +28 rows in set (0.00 sec) ``` ```sql @@ -85,6 +86,7 @@ SUBPARTITION_ORDINAL_POSITION: NULL TABLESPACE_NAME: NULL TIDB_PARTITION_ID: 89 TIDB_PLACEMENT_POLICY_NAME: NULL + TIDB_AFFINITY: NULL *************************** 2. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: test @@ -113,6 +115,7 @@ SUBPARTITION_ORDINAL_POSITION: NULL TABLESPACE_NAME: NULL TIDB_PARTITION_ID: 90 TIDB_PLACEMENT_POLICY_NAME: NULL + TIDB_AFFINITY: NULL 2 rows in set (0.00 sec) ``` diff --git a/information-schema/information-schema-tables.md b/information-schema/information-schema-tables.md index ff7ac01c5887..a1b38ae3294a 100644 --- a/information-schema/information-schema-tables.md +++ b/information-schema/information-schema-tables.md @@ -41,8 +41,12 @@ DESC tables; | TABLE_COMMENT | varchar(2048) | YES | | NULL | | | TIDB_TABLE_ID | bigint(21) | YES | | NULL | | | TIDB_ROW_ID_SHARDING_INFO | varchar(255) | YES | | NULL | | +| TIDB_PK_TYPE | varchar(64) | YES | | NULL | | +| TIDB_PLACEMENT_POLICY_NAME | varchar(64) | YES | | NULL | | +| TIDB_TABLE_MODE | varchar(16) | YES | | NULL | | +| TIDB_AFFINITY | varchar(128) | YES | | NULL | | +---------------------------+---------------+------+------+----------+-------+ -23 rows in set (0.00 sec) +27 rows in set (0.00 sec) ``` {{< copyable "sql" >}} @@ -76,6 +80,10 @@ SELECT * FROM tables WHERE table_schema='mysql' AND table_name='user'\G TABLE_COMMENT: TIDB_TABLE_ID: 5 TIDB_ROW_ID_SHARDING_INFO: NULL + TIDB_PK_TYPE: CLUSTERED +TIDB_PLACEMENT_POLICY_NAME: NULL + TIDB_TABLE_MODE: Normal + TIDB_AFFINITY: NULL 1 row in set (0.00 sec) ``` @@ -115,7 +123,7 @@ SHOW TABLES * `CREATE_OPTIONS`:创建选项。 * `TABLE_COMMENT`:表的注释、备注。 -表中的信息大部分定义自 MySQL,只有两列是 TiDB 新增的: +表中的大部分列都和 MySQL 相同,除了以下列是 TiDB 新增的: * `TIDB_TABLE_ID`:标识表的内部 ID,该 ID 在一个 TiDB 集群内部唯一。 * `TIDB_ROW_ID_SHARDING_INFO`:标识表的 Sharding 类型,可能的值为: @@ -123,4 +131,8 @@ SHOW TABLES - `"NOT_SHARDED(PK_IS_HANDLE)"`:一个定义了整型主键的表未被 Shard。 - `"PK_AUTO_RANDOM_BITS={bit_number}"`:一个定义了整型主键的表由于定义了 `AUTO_RANDOM` 而被 Shard。 - `"SHARD_BITS={bit_number}"`:表使用 `SHARD_ROW_ID_BITS={bit_number}` 进行了 Shard。 - - NULL:表属于系统表或 View,无法被 Shard。 + - `NULL`:表属于系统表或 View,无法被 Shard。 +* `TIDB_PK_TYPE`:表的主键类型,可能的值包括 `CLUSTERED`(聚簇主键)和 `NONCLUSTERED`(非聚簇主键)。 +* `TIDB_PLACEMENT_POLICY_NAME`:应用于该表的放置策略 (placement policy) 名称。 +* `TIDB_TABLE_MODE`:表的模式,例如 `Normal`、`Import` 或 `Restore`。 +* `TIDB_AFFINITY`:表的亲和性等级,非分区表为 `table`,分区表为 `partition`,未开启亲和性时为 `NULL`。 diff --git a/pd-configuration-file.md b/pd-configuration-file.md index 27baea8258f2..910e075d8f69 100644 --- a/pd-configuration-file.md +++ b/pd-configuration-file.md @@ -287,6 +287,13 @@ pd-server 相关配置项。 + 控制 Region Merge 的 key 上限,当 Region key 大于指定值时 PD 不会将其与相邻的 Region 合并。 + 默认:540000。在 v8.4.0 之前,默认值为 200000;从 v8.4.0 开始,默认值为 540000。 +### `max-affinity-merge-region-size` 从 v8.5.5 版本开始引入 + ++ 控制属于同一[亲和性](/table-affinity.md)分组中相邻的小 Region 自动合并的阈值。当 Region 属于某个亲和性分组,且其大小小于该配置值时,PD 会尝试将该 Region 与同一亲和性分组中相邻的其它小 Region 进行合并,以减少 Region 数量并保持亲和性效果。 ++ 设置为 `0` 表示关闭亲和性分组中相邻小 Region 的自动合并。 ++ 默认值:256 ++ 单位:MiB + ### `patrol-region-interval` + 控制 checker 检查 Region 健康状态的运行频率,越短则运行越快,通常状况不需要调整 @@ -362,6 +369,11 @@ pd-server 相关配置项。 + 同时进行的 Region Merge 调度的任务,设置为 0 则关闭 Region Merge。 + 默认值:8 +### `affinity-schedule-limit` 从 v8.5.5 版本开始引入 + ++ 控制同时进行的[亲和性](/table-affinity.md)调度任务数量。设置为 `0` 表示禁用亲和性调度。 ++ 默认值:0 + ### `high-space-ratio` + 设置 store 空间充裕的阈值。当节点的空间占用比例小于该阈值时,PD 调度时会忽略节点的剩余空间,主要根据实际数据量进行均衡。此配置仅在 `region-score-formula-version = v1` 时生效。 diff --git a/sql-statements/sql-statement-alter-table.md b/sql-statements/sql-statement-alter-table.md index 91701dbda670..5fc6ee3761f6 100644 --- a/sql-statements/sql-statement-alter-table.md +++ b/sql-statements/sql-statement-alter-table.md @@ -54,6 +54,7 @@ AlterTableSpec ::= | TTLEnable EqOpt ( 'ON' | 'OFF' ) | TTLJobInterval EqOpt stringLit ) +| 'AFFINITY' EqOpt stringLit | PlacementPolicyOption PlacementPolicyOption ::= @@ -172,6 +173,7 @@ TiDB 中的 `ALTER TABLE` 语法主要存在以下限制: - 不支持分区表上的列类型变更。 - 不支持生成列上的列类型变更。 - 不支持部分数据类型(例如,部分时间类型、Bit、Set、Enum、JSON 等)的变更,因为 TiDB 中的 `CAST` 函数与 MySQL 的行为存在兼容性问题。 +- `AFFINITY` 选项为 TiDB 扩展语法。开启 `AFFINITY` 后,不支持变更该表的分区方案(如添加、删除、重组或交换分区),需要先移除 `AFFINITY`。 - 不支持空间数据类型。 - `ALTER TABLE t CACHE | NOCACHE` 不是 MySQL 标准语法,而是 TiDB 扩展功能,参见[缓存表](/cached-tables.md)。 diff --git a/sql-statements/sql-statement-create-table.md b/sql-statements/sql-statement-create-table.md index 7b4fdd224fc3..2c571491dad6 100644 --- a/sql-statements/sql-statement-create-table.md +++ b/sql-statements/sql-statement-create-table.md @@ -117,6 +117,7 @@ TableOption ::= | 'UNION' EqOpt '(' TableNameListOpt ')' | 'ENCRYPTION' EqOpt EncryptionOpt | 'TTL' EqOpt TimeColumnName '+' 'INTERVAL' Expression TimeUnit (TTLEnable EqOpt ( 'ON' | 'OFF' ))? (TTLJobInterval EqOpt stringLit)? +| 'AFFINITY' EqOpt StringName | PlacementPolicyOption OnCommitOpt ::= @@ -170,10 +171,12 @@ TiDB 支持以下 `table_option`。TiDB 会解析并忽略其他 `table_option` |`CHARACTER SET` |指定该表所使用的[字符集](/character-set-and-collation.md) | `CHARACTER SET` = 'utf8mb4'| |`COLLATE` |指定该表所使用的字符集排序规则 | `COLLATE` = 'utf8mb4_bin'| |`COMMENT` |注释信息 | `COMMENT` = 'comment info'| +|`AFFINITY` |为表或分区开启亲和性调度。非分区表可设置为 `'table'`,分区表可设置为 `'partition'`。设置为 `'none'` 或留空可关闭亲和性调度 |`AFFINITY` = 'table'| > **注意:** > -> 在 TiDB 配置文件中,`split-table` 默认开启。当该配置项开启时,建表操作会为每个表建立单独的 Region,详情参见 [TiDB 配置文件描述](/tidb-configuration-file.md)。 +> - 在 TiDB 配置文件中,`split-table` 默认开启。当该配置项开启时,建表操作会为每个表建立单独的 Region,详情参见 [TiDB 配置文件描述](/tidb-configuration-file.md)。 +> - 使用 `AFFINITY` 时,当前不支持对该表进行分区方案变更(如添加、删除、重组或交换分区),也不支持在临时表或视图上设置该选项。 ## 示例 diff --git a/sql-statements/sql-statement-show-affinity.md b/sql-statements/sql-statement-show-affinity.md new file mode 100644 index 000000000000..500d16fbd2c1 --- /dev/null +++ b/sql-statements/sql-statement-show-affinity.md @@ -0,0 +1,61 @@ +--- +title: SHOW AFFINITY +summary: 介绍 TiDB 数据库中 SHOW AFFINITY 的使用概况。 +--- + +# SHOW AFFINITY 从 v8.5.5 开始引入 + +`SHOW AFFINITY` 语句用于查看配置了 `AFFINITY` 选项的表的[亲和性](/table-affinity.md)调度信息,以及 PD 当前记录的目标副本分布。 + +## 语法图 + +```ebnf+diagram +ShowAffinityStmt ::= + "SHOW" "AFFINITY" ShowLikeOrWhereOpt +``` + +`SHOW AFFINITY` 支持使用 `LIKE` 或 `WHERE` 子句过滤表名。 + +## 示例 + +以下示例创建两个启用了亲和性调度的表,并查看其调度信息: + +```sql +CREATE TABLE t1 (a INT) AFFINITY = 'table'; +CREATE TABLE tp1 (a INT) AFFINITY = 'partition' PARTITION BY HASH(a) PARTITIONS 2; + +SHOW AFFINITY; +``` + +输出结果示例如下: + +```sql ++---------+------------+----------------+-----------------+------------------+----------+--------------+----------------------+ +| Db_name | Table_name | Partition_name | Leader_store_id | Voter_store_ids | Status | Region_count | Affinity_region_count| ++---------+------------+----------------+-----------------+------------------+----------+--------------+----------------------+ +| test | t1 | NULL | 1 | 1,2,3 | Stable | 8 | 8 | +| test | tp1 | p0 | 4 | 4,5,6 | Preparing| 4 | 2 | +| test | tp1 | p1 | 4 | 4,5,6 | Preparing| 3 | 2 | ++---------+------------+----------------+-----------------+------------------+----------+--------------+----------------------+ +``` + +各列含义如下: + +- `Leader_store_id`、`Voter_store_ids`:PD 为该表或分区记录的目标 Leader 副本和 Voter 副本所在的 TiKV Store ID。如果亲和性分组尚未确定目标副本位置或 [`schedule.affinity-schedule-limit`](/pd-configuration-file.md#affinity-schedule-limit-从-v855-版本开始引入) 为 `0`,则显示为 `NULL`。 +- `Status`:表示当前亲和性调度的状态。可能的取值如下: + - `Pending`:PD 尚未对该表或分区进行亲和性调度(比如未确定 Leader 或 Voter 时)。 + - `Preparing`:PD 正在调度 Region 以满足亲和性要求。 + - `Stable`:所有 Region 已达到目标分布。 +- `Region_count`:当前在该亲和性组中的 Region 数量。 +- `Affinity_region_count`:当前已满足亲和性副本分布要求的 Region 数量。 + - 当 `Affinity_region_count` 小于 `Region_count` 时,表示仍有部分 Region 尚未完成基于亲和性的副本调度。 + - 当 `Affinity_region_count` 等于 `Region_count` 时,表示基于亲和性的 Region 副本迁移调度已完成,也就意味着所有 Region 的分布已经满足亲和性要求,但并不代表相关 Region 的合并操作已完成。 + +## MySQL 兼容性 + +该语句是 TiDB 对 MySQL 语法的扩展。 + +## 另请参阅 + +- [`CREATE TABLE`](/sql-statements/sql-statement-create-table.md) +- [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md) diff --git a/table-affinity.md b/table-affinity.md new file mode 100644 index 000000000000..f0a818fd0667 --- /dev/null +++ b/table-affinity.md @@ -0,0 +1,109 @@ +--- +title: 表级数据亲和性 +summary: 通过为表或分区配置亲和性约束,控制 Region 副本的分布并查看调度状态。 +--- + +# 表级数据亲和性 从 v8.5.5 开始引入 + +> **警告:** +> +> 该功能为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 + +表级数据亲和性是 PD 在表级别上的数据分布调度机制,用于控制同一个表或分区中 Region 的 Leader 和 Voter 副本在 TiKV 集群中的分布。 + +开启 PD 数据亲和性调度,并将表的 `AFFINITY` 选项设置为 `table` 或 `partition` 后,PD 会将同一张表或同一个分区的 Region 归入同一个亲和性分组,并在调度过程中优先将这些 Region 的 Leader 和 Voter 副本放置到相同的少数 TiKV 节点上,从而减少查询过程中跨节点访问带来的网络延迟,提升查询性能。 + +## 使用限制 + +使用表级数据亲和性前,请注意以下限制: + +- 在 [PD 微服务模式](/pd-microservices.md)下,该功能不会生效。 +- [临时表](/temporary-tables.md)和[视图](/views.md)不支持配置数据亲和性。 +- 为[分区表](/partitioned-table.md)配置数据亲和性后,**不支持修改该表的分区方案**,包括新增、删除、重组或交换分区。如需调整分区配置,请先移除该表的亲和性设置。 +- **数据量较大时需提前评估磁盘容量**:开启数据亲和性后,PD 会优先将表或分区的 Region 调度到相同的少数 TiKV 节点上。对于数据量较大的表或分区,可能导致这些节点的磁盘使用率显著升高。建议提前评估磁盘容量并做好监控。 +- 数据亲和性调度仅影响 Leader 和 Voter 副本的分布。如果表有 Learner 副本(如 TiFlash),Learner 副本的分布不受亲和性配置影响。 + +## 前提条件 + +PD 亲和性调度特性默认关闭。在设置表或分区的亲和性前,请开启并配置该特性。 + +1. 将 PD 配置项 [`schedule.affinity-schedule-limit`](/pd-configuration-file.md#affinity-schedule-limit-从-v855-版本开始引入) 设置为大于 `0` 的值,以开启 PD 的亲和性调度。 + + 例如,执行以下命令将该配置项设置为 `4`,表示允许 PD 最多同时执行 4 个亲和性调度任务: + + ```bash + pd-ctl config set schedule.affinity-schedule-limit 4 + ``` + +2. (可选)根据需要设置 PD 配置项 [`schedule.max-affinity-merge-region-size`](/pd-configuration-file.md#max-affinity-merge-region-size-从-v855-版本开始引入)(默认值为 `256`,单位为 MiB),用于控制属于同一亲和性分组中相邻的小 Region 自动合并的阈值。设置为 `0` 表示关闭亲和性分组中相邻的小 Region 的自动合并。 + +## 使用方法 + +本节介绍如何配置表或分区的亲和性,以及如何查看亲和性调度状态。 + +### 配置表或分区的亲和性 + +你可以通过 `CREATE TABLE` 或 `ALTER TABLE` 语句中的 `AFFINITY` 选项配置表或分区的亲和性。 + +| 亲和性等级 | 适用范围 | 效果 | +|---|---|---| +| `AFFINITY='table'` | 非分区表 | 开启该表的亲和性,PD 会为此表的所有 Region 创建一个亲和性分组。 | +| `AFFINITY='partition'` | 分区表 | 开启该表中每个分区的亲和性,PD 会为此表的**每个分区**对应的 Region 分别创建独立的亲和性分组。例如,当表包含 4 个分区时,PD 将为该表创建 4 个相互独立的亲和性分组。 | +| `AFFINITY=''` 或 `AFFINITY='none'` | 已设置 `AFFINITY='table'` 或 `AFFINITY='partition'` 的表 | 关闭该表或分区的亲和性。设置后,PD 会删除对应表或分区的亲和性分组,表或分区的 Region 将不再受到亲和性调度约束。TiKV 上 Region 的自动分裂将在最长 10 分钟内恢复为默认状态。 | + +**示例**: + +创建非分区表时开启该表的亲和性: + +```sql +CREATE TABLE t1 (a INT) AFFINITY = 'table'; +``` + +创建分区表时开启该表中每个分区的亲和性: + +```sql +CREATE TABLE tp1 (a INT) + AFFINITY = 'partition' + PARTITION BY HASH(a) PARTITIONS 4; +``` + +为现有非分区表开启亲和性: + +```sql +CREATE TABLE t2 (a INT); +ALTER TABLE t2 AFFINITY = 'table'; +``` + +关闭表的亲和性: + +```sql +ALTER TABLE t1 AFFINITY = ''; +``` + +### 查看亲和性 + +可以通过以下方式查看表或分区的亲和性信息: + +- 执行 [`SHOW AFFINITY`](/sql-statements/sql-statement-show-affinity.md) 语句,在 `Status` 列查看已开启亲和性的表或分区及其调度状态。`Status` 列的值含义如下: + + - `Pending`:PD 尚未对该表或分区进行亲和性调度,比如未确定 Leader 或 Voter 时。 + - `Preparing`:PD 正在调度 Region 以满足亲和性要求。 + - `Stable`:所有 Region 已达到目标分布。 + +- 查询 [`INFORMATION_SCHEMA.TABLES`](/information-schema/information-schema-tables.md) 表的 `TIDB_AFFINITY` 列查看表的亲和性等级。 +- 查询 [`INFORMATION_SCHEMA.PARTITIONS`](/information-schema/information-schema-partitions.md) 表的 `TIDB_AFFINITY` 列查看分区的亲和性等级。 + +## 注意事项 + +- **Region 的自动分裂**:当 Region 属于某个亲和性分组且亲和性生效时,Region 默认不会自动分裂,以避免产生过多 Region 影响亲和性效果。只有当 Region 大小超过 [`schedule.max-affinity-merge-region-size`](/pd-configuration-file.md#max-affinity-merge-region-size-从-v855-版本开始引入) 值的四倍时,才会触发自动分裂。需要注意的是,非 TiKV 或 PD 自动触发的 Region 分裂(例如手动执行的 [`SPLIT TABLE`](/sql-statements/sql-statement-split-region.md))不受此限制。 + +- **降级与过期机制**:如果亲和性分组中目标 Leader 或 Voter 所在的 TiKV 节点处于不可用状态(例如节点宕机或磁盘空间不足)、Leader 被驱逐,或与现有放置规则发生冲突时,PD 会将该亲和性分组标记为降级状态。在降级期间,对应表或分区的亲和性调度将暂停。 + + - 若相关节点在 10 分钟内恢复正常,PD 会继续按照原有亲和性设置进行调度。 + - 若超过 10 分钟仍未恢复,该亲和性分组将被标记为过期。此时 PD 会先恢复常规调度行为([`SHOW AFFINITY`](/sql-statements/sql-statement-show-affinity.md) 的状态会回到 `Pending`),然后自动更新亲和性分组中的 Leader 和 Voter,以重新启用亲和性调度。 + +## 相关语句与配置 + +- [`CREATE TABLE`](/sql-statements/sql-statement-create-table.md) 和 [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md) 的 `AFFINITY` 选项 +- [`SHOW AFFINITY`](/sql-statements/sql-statement-show-affinity.md) +- PD 配置项:[`schedule.affinity-schedule-limit`](/pd-configuration-file.md#affinity-schedule-limit-从-v855-版本开始引入) 和 [`schedule.max-affinity-merge-region-size`](/pd-configuration-file.md#max-affinity-merge-region-size-从-v855-版本开始引入) \ No newline at end of file