diff --git a/README.md b/README.md index 300eabe64c25..44b1f6c31a8f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,10 @@ | 文档仓库 branch | 对应 TiDB 文档版本 | |:---------|:----------| | [`master`](https://github.com/pingcap/docs-cn/tree/master) | dev 最新开发版 | +| [`release-7.0`](https://github.com/pingcap/docs-cn/tree/release-7.0) | 7.0 开发里程碑版 (DMR) | +| [`release-6.6`](https://github.com/pingcap/docs-cn/tree/release-6.6) | 6.6 开发里程碑版 (DMR) | +| [`release-6.5`](https://github.com/pingcap/docs-cn/tree/release-6.5) | 6.5 长期支持版 (LTS) | +| [`release-6.4`](https://github.com/pingcap/docs-cn/tree/release-6.4) | 6.4 开发里程碑版 (DMR) | | [`release-6.3`](https://github.com/pingcap/docs-cn/tree/release-6.3) | 6.3 开发里程碑版 (DMR) | | [`release-6.2`](https://github.com/pingcap/docs-cn/tree/release-6.2) | 6.2 开发里程碑版 (DMR) | | [`release-6.1`](https://github.com/pingcap/docs-cn/tree/release-6.1) | 6.1 长期支持版 (LTS) | diff --git a/TOC.md b/TOC.md index 35ab47fbc736..0f9e051ce03a 100644 --- a/TOC.md +++ b/TOC.md @@ -52,7 +52,6 @@ - [Follower Read](/develop/dev-guide-use-follower-read.md) - [Stale Read](/develop/dev-guide-use-stale-read.md) - [HTAP 查询](/develop/dev-guide-hybrid-oltp-and-olap-queries.md) - - [FastScan](/develop/dev-guide-use-fastscan.md) - 事务 - [概览](/develop/dev-guide-transaction-overview.md) - [乐观事务和悲观事务](/develop/dev-guide-optimistic-and-pessimistic-transaction.md) @@ -205,7 +204,9 @@ - 优化手册 - [优化概述](/performance-tuning-overview.md) - [优化方法](/performance-tuning-methods.md) - - [优化实践](/performance-tuning-practices.md) + - [OLTP 负载性能优化实践](/performance-tuning-practices.md) + - [TiFlash 性能分析方法](/tiflash-performance-tuning-methods.md) + - [TiCDC 性能分析方法](/ticdc-performance-tuning-methods.md) - [延迟的拆解分析](/latency-breakdown.md) - 配置调优 - [操作系统性能参数调优](/tune-operating-system.md) @@ -244,6 +245,7 @@ - [分区裁剪](/partition-pruning.md) - [TopN 和 Limit 下推](/topn-limit-push-down.md) - [Join Reorder](/join-reorder.md) + - [从窗口函数中推导 TopN 或 Limit](/derive-topn-from-window.md) - 物理优化 - [物理优化概览](/sql-physical-optimization.md) - [索引的选择](/choose-index.md) @@ -251,7 +253,8 @@ - [错误索引的解决方案](/wrong-index-solution.md) - [Distinct 优化](/agg-distinct-optimization.md) - [代价模型](/cost-model.md) - - [执行计划缓存](/sql-prepared-plan-cache.md) + - [Prepare 语句执行计划缓存](/sql-prepared-plan-cache.md) + - [非 Prepare 语句执行计划缓存](/sql-non-prepared-plan-cache.md) - 控制执行计划 - [控制执行计划概览](/control-execution-plan.md) - [Optimizer Hints](/optimizer-hints.md) @@ -542,7 +545,8 @@ - [TiCDC Canal-JSON Protocol](/ticdc/ticdc-canal-json.md) - [TiCDC Open Protocol](/ticdc/ticdc-open-protocol.md) - [TiCDC CSV Protocol](/ticdc/ticdc-csv.md) - - [TiCDC Open API](/ticdc/ticdc-open-api.md) + - [TiCDC Open API v2](/ticdc/ticdc-open-api-v2.md) + - [TiCDC Open API v1](/ticdc/ticdc-open-api.md) - [Storage sink 消费程序编写指引](/ticdc/ticdc-storage-consumer-dev-guide.md) - [兼容性](/ticdc/ticdc-compatibility.md) - [故障处理](/ticdc/troubleshoot-ticdc.md) @@ -611,8 +615,12 @@ - [使用 TiDB 读取 TiFlash](/tiflash/use-tidb-to-read-tiflash.md) - [使用 TiSpark 读取 TiFlash](/tiflash/use-tispark-to-read-tiflash.md) - [使用 MPP 模式](/tiflash/use-tiflash-mpp-mode.md) + - [TiFlash 存算分离架构与 S3 支持](/tiflash/tiflash-disaggregated-and-s3.md) + - [使用 FastScan 功能](/tiflash/use-fastscan.md) - [TiFlash 支持的计算下推](/tiflash/tiflash-supported-pushdown-calculations.md) - [TiFlash 查询结果物化](/tiflash/tiflash-results-materialization.md) + - [TiFlash 延迟物化](/tiflash/tiflash-late-materialization.md) + - [TiFlash 数据落盘](/tiflash/tiflash-spill-disk.md) - [TiFlash 数据校验](/tiflash/tiflash-data-validation.md) - [TiFlash 兼容性说明](/tiflash/tiflash-compatibility.md) - [系统变量](/system-variables.md) @@ -674,6 +682,8 @@ - [`ADMIN CANCEL DDL`](/sql-statements/sql-statement-admin-cancel-ddl.md) - [`ADMIN CHECKSUM TABLE`](/sql-statements/sql-statement-admin-checksum-table.md) - [`ADMIN CHECK [TABLE|INDEX]`](/sql-statements/sql-statement-admin-check-table-index.md) + - [`ADMIN CLEANUP`](/sql-statements/sql-statement-admin-cleanup.md) + - [`ADMIN RECOVER INDEX`](/sql-statements/sql-statement-admin-recover.md) - [`ADMIN SHOW DDL [JOBS|QUERIES]`](/sql-statements/sql-statement-admin-show-ddl.md) - [`ADMIN SHOW TELEMETRY`](/sql-statements/sql-statement-admin-show-telemetry.md) - [`ALTER DATABASE`](/sql-statements/sql-statement-alter-database.md) @@ -688,6 +698,8 @@ - [`BACKUP`](/sql-statements/sql-statement-backup.md) - [`BATCH`](/sql-statements/sql-statement-batch.md) - [`BEGIN`](/sql-statements/sql-statement-begin.md) + - [`CANCEL LOAD DATA` 和 `DROP LOAD DATA`](/sql-statements/sql-statement-operate-load-data-job.md) + - [`CALIBRATE RESOURCE`](/sql-statements/sql-statement-calibrate-resource.md) - [`CHANGE COLUMN`](/sql-statements/sql-statement-change-column.md) - [`CHANGE DRAINER`](/sql-statements/sql-statement-change-drainer.md) - [`CHANGE PUMP`](/sql-statements/sql-statement-change-pump.md) @@ -736,6 +748,7 @@ - [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) - [`LOAD STATS`](/sql-statements/sql-statement-load-stats.md) - [`LOCK STATS`](/sql-statements/sql-statement-lock-stats.md) + - [`LOCK TABLES` 和 `UNLOCK TABLES`](/sql-statements/sql-statement-lock-tables-and-unlock-tables.md) - [`MODIFY COLUMN`](/sql-statements/sql-statement-modify-column.md) - [`PREPARE`](/sql-statements/sql-statement-prepare.md) - [`RECOVER TABLE`](/sql-statements/sql-statement-recover-table.md) @@ -752,6 +765,7 @@ - [`SET DEFAULT ROLE`](/sql-statements/sql-statement-set-default-role.md) - [`SET [NAMES|CHARACTER SET]`](/sql-statements/sql-statement-set-names.md) - [`SET PASSWORD`](/sql-statements/sql-statement-set-password.md) + - [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) - [`SET ROLE`](/sql-statements/sql-statement-set-role.md) - [`SET TRANSACTION`](/sql-statements/sql-statement-set-transaction.md) - [`SET [GLOBAL|SESSION] `](/sql-statements/sql-statement-set-variable.md) @@ -778,6 +792,7 @@ - [`SHOW INDEX [FROM|IN]`](/sql-statements/sql-statement-show-index.md) - [`SHOW INDEXES [FROM|IN]`](/sql-statements/sql-statement-show-indexes.md) - [`SHOW KEYS [FROM|IN]`](/sql-statements/sql-statement-show-keys.md) + - [`SHOW LOAD DATA`](/sql-statements/sql-statement-show-load-data.md) - [`SHOW MASTER STATUS`](/sql-statements/sql-statement-show-master-status.md) - [`SHOW PLACEMENT`](/sql-statements/sql-statement-show-placement.md) - [`SHOW PLACEMENT FOR`](/sql-statements/sql-statement-show-placement-for.md) @@ -974,6 +989,7 @@ - v6.6 - [6.6.0-DMR](/releases/release-6.6.0.md) - v6.5 + - [6.5.1](/releases/release-6.5.1.md) - [6.5.0](/releases/release-6.5.0.md) - v6.4 - [6.4.0-DMR](/releases/release-6.4.0.md) diff --git a/alert-rules.md b/alert-rules.md index 65101c0fe0a9..18065dd1e592 100644 --- a/alert-rules.md +++ b/alert-rules.md @@ -228,7 +228,7 @@ aliases: ['/docs-cn/dev/alert-rules/','/docs-cn/dev/reference/alert-rules/'] * 报警规则: - `(sum(pd_regions_status{type="miss_peer_region_count"}) by (instance) > 100) and (sum(etcd_server_is_leader) by (instance) > 0)` + `(sum(pd_regions_status{type="miss-peer-region-count"}) by (instance) > 100) and (sum(etcd_server_is_leader) by (instance) > 0)` * 规则描述: @@ -237,7 +237,7 @@ aliases: ['/docs-cn/dev/alert-rules/','/docs-cn/dev/reference/alert-rules/'] * 处理方法: * 查看是否有 TiKV 宕机或在做下线操作,尝试定位问题产生的原因。 - * 观察 region health 面板,查看 `miss_peer_region_count` 是否在不断减少。 + * 观察 region health 面板,查看 `miss-peer-region-count` 是否在不断减少。 ### 警告级别报警项 diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 0399ee544f81..33ba7d1a4611 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -33,10 +33,12 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS(NOW() - INTERVAL 20 SECOND, NOW())` 表示读取 20 秒前到现在的时间范围内尽可能新的数据。 > **注意:** -> +> > 除了指定时间戳,`AS OF TIMESTAMP` 语法最常用使用的方式是读几秒前的数据。如果采用这种方式,推荐读 5 秒以上的历史数据。 > > 使用 Stale Read 时需要为 TiDB 和 PD 节点部署 NTP 服务,防止 TiDB 指定的时间戳超过当前最新的 TSO 分配进度(如几秒后的时间戳),或者落后于 GC safe point 的时间戳。当指定的时间戳超过服务范围,TiDB 会返回错误。 +> +> 你可以通过调整 TiKV 的 `advance-ts-interval` 配置项提高 Stale Read 数据的时效性(即减少延时)。详情参见[减少 Stale Read 延时](/stale-read.md#减少-stale-read-延时)。 ## 示例 diff --git a/auto-increment.md b/auto-increment.md index f1408b69f562..b172b7e7ab39 100644 --- a/auto-increment.md +++ b/auto-increment.md @@ -351,7 +351,7 @@ CREATE TABLE t(a int AUTO_INCREMENT key) AUTO_ID_CACHE 1; 目前在 TiDB 中使用 `AUTO_INCREMENT` 有以下限制: -- 定义的列必须为主键或者索引的首列。 +- 对于 v6.6.0 及更早的 TiDB 版本,定义的列必须为主键或者索引前缀。 - 只能定义在类型为整数、`FLOAT` 或 `DOUBLE` 的列上。 - 不支持与列的默认值 `DEFAULT` 同时指定在同一列上。 - 不支持使用 `ALTER TABLE` 来添加 `AUTO_INCREMENT` 属性。 diff --git a/basic-features.md b/basic-features.md index 439169c5e7a2..75779099707e 100644 --- a/basic-features.md +++ b/basic-features.md @@ -44,22 +44,22 @@ aliases: ['/docs-cn/dev/basic-features/','/docs-cn/dev/experimental-features-4.0 ## 索引和约束 -| 索引和约束 | 6.6 | 6.5 | 6.1 | 5.4 | 5.3 | 5.2 | 5.1 | 5.0 | 4.0 | -| ---------------------------------------------------------------------- | --- | --- | :------: | :------: | :------: | :------: | :------: | :------: | :------: | -| [表达式索引](/sql-statements/sql-statement-create-index.md#表达式索引) [^2] | Y | Y | E | E | E | E | E | E | E | -| [列式存储 (TiFlash)](/tiflash/tiflash-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [使用 FastScan 加速 OLAP 场景下的查询](/develop/dev-guide-use-fastscan.md) | E | E | N | N | N | N | N | N | N | -| [RocksDB 引擎](/storage-engine/rocksdb-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [Titan 插件](/storage-engine/titan-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [Titan Level Merge](/storage-engine/titan-configuration.md#level-merge实验功能) | E | E | E | E | E | E | E | E | E | -| [使用 bucket 提高数据扫描并发度](/tune-region-performance.md#使用-bucket-增加并发) | E | E | E | N | N | N | N | N | N | -| [不可见索引](/sql-statements/sql-statement-add-index.md) | Y | Y | Y | Y | Y | Y | Y | Y | N | -| [复合主键](/constraints.md#主键约束) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [唯一约束](/constraints.md#唯一约束) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [整型主键上的聚簇索引](/constraints.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | -| [复合或非整型主键上的聚簇索引](/constraints.md) | Y | Y | Y | Y | Y | Y | Y | Y | N | -| [多值索引](/sql-statements/sql-statement-create-index.md#多值索引) | E | N | N | N | N | N | N | N | -| [外键约束](/constraints.md#外键约束) | Y | N | N | N | N | N | N | N | +| 索引和约束 | 7.0 | 6.6 | 6.5 | 6.1 | 5.4 | 5.3 | 5.2 | 5.1 | 5.0 | 4.0 | +| ---------------------------------------------------------------------- | --- | --- | --- | :------: | :------: | :------: | :------: | :------: | :------: | :------: | +| [表达式索引](/sql-statements/sql-statement-create-index.md#表达式索引) [^2] | Y | Y | Y | E | E | E | E | E | E | E | +| [列式存储 (TiFlash)](/tiflash/tiflash-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [使用 FastScan 加速 OLAP 场景下的查询](/tiflash/use-fastscan.md) | Y | E | E | N | N | N | N | N | N | N | +| [RocksDB 引擎](/storage-engine/rocksdb-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [Titan 插件](/storage-engine/titan-overview.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [Titan Level Merge](/storage-engine/titan-configuration.md#level-merge实验功能) | E | E | E | E | E | E | E | E | E | E | +| [使用 bucket 提高数据扫描并发度](/tune-region-performance.md#使用-bucket-增加并发) | E | E | E | E | N | N | N | N | N | N | +| [不可见索引](/sql-statements/sql-statement-add-index.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | N | +| [复合主键](/constraints.md#主键约束) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [唯一约束](/constraints.md#唯一约束) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [整型主键上的聚簇索引](/constraints.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +| [复合或非整型主键上的聚簇索引](/constraints.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | N | +| [多值索引](/sql-statements/sql-statement-create-index.md#多值索引) | E | E | N | N | N | N | N | N | N | +| [外键约束](/constraints.md#外键约束) | Y | Y | N | N | N | N | N | N | N | ## SQL 语句 @@ -82,7 +82,7 @@ aliases: ['/docs-cn/dev/basic-features/','/docs-cn/dev/experimental-features-4.0 | [`BATCH [ON COLUMN] LIMIT INTEGER DELETE`](/sql-statements/sql-statement-batch.md) | Y | Y | Y | N | N | N | N | N | N | | [`BATCH [ON COLUMN] LIMIT INTEGER INSERT/UPDATE/REPLACE`](/sql-statements/sql-statement-batch.md) | Y | Y | N | N | N | N | N | N | N | | [`ALTER TABLE ... COMPACT`](/sql-statements/sql-statement-alter-table-compact.md) | Y | Y | E | N | N | N | N | N | N | -| [表级锁 (Table Lock)](/tidb-configuration-file.md#enable-table-lock-从-v400-版本开始引入) | E | E | E | E | E | E | E | E | E | +| [表级锁 (Table Lock)](/sql-statements/sql-statement-lock-tables-and-unlock-tables.md) | E | E | E | E | E | E | E | E | E | | [物化列式存储的查询结果](/tiflash/tiflash-results-materialization.md) | E | E | N | N | N | N | N | N | N | ## 高级 SQL 功能 diff --git a/blocklist-control-plan.md b/blocklist-control-plan.md index 7bd9827618e9..f13e441ba527 100644 --- a/blocklist-control-plan.md +++ b/blocklist-control-plan.md @@ -27,6 +27,7 @@ aliases: ['/docs-cn/dev/blacklist-control-plan/','/zh/tidb/dev/blacklist-control | 聚合下推 | aggregation_push_down | 尝试将执行计划中的聚合算子下推到更底层的计算节点 | | TopN 下推 | topn_push_down | 尝试将执行计划中的 TopN 算子下推到离数据源更近的算子上 | | Join 重排序 | join_reorder | 对多表 join 确定连接顺序 | +| 从窗口函数中推导 TopN 或 Limit | derive_topn_from_window | 从窗口函数中推导出 TopN 或者 Limit | ### 禁用优化规则 @@ -73,14 +74,7 @@ aliases: ['/docs-cn/dev/blacklist-control-plan/','/zh/tidb/dev/blacklist-control ### 已支持下推的表达式 -| 表达式分类 | 具体操作 | -| :-------------- | :------------------------------------- | -| [逻辑运算](/functions-and-operators/operators.md#逻辑操作符) | AND (&&), OR (||), NOT (!) | -| [比较运算](/functions-and-operators/operators.md#比较方法和操作符) | <, <=, =, != (`<>`), >, >=, [`<=>`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to), [`IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_in), IS NULL, LIKE, IS TRUE, IS FALSE, [`COALESCE()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce) | -| [数值运算](/functions-and-operators/numeric-functions-and-operators.md) | +, -, *, /, [`ABS()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs), [`CEIL()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceil), [`CEILING()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceiling), [`FLOOR()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor) | -| [控制流运算](/functions-and-operators/control-flow-functions.md) | [`CASE`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#operator_case), [`IF()`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_if), [`IFNULL()`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_ifnull) | -| [JSON 运算](/functions-and-operators/json-functions.md) | [JSON_TYPE(json_val)](https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-type),
[JSON_EXTRACT(json_doc, path[, path] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-extract),
[JSON_UNQUOTE(json_val)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-unquote),
[JSON_OBJECT(key, val[, key, val] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-object),
[JSON_ARRAY([val[, val] ...])](https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-array),
[JSON_MERGE(json_doc, json_doc[, json_doc] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge),
[JSON_SET(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-set),
[JSON_INSERT(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-insert),
[JSON_REPLACE(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-replace),
[JSON_REMOVE(json_doc, path[, path] ...)](https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-remove) | -| [日期运算](/functions-and-operators/date-and-time-functions.md) | [`DATE_FORMAT()`](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format) | +目前已经支持下推的表达式信息,请参考[表达式列表](/functions-and-operators/expressions-pushed-down.md#已支持下推的表达式列表)。 ### 禁止特定表达式下推 diff --git a/br/br-snapshot-manual.md b/br/br-snapshot-manual.md index 58fe1dc62618..41d7c4cd3ecb 100644 --- a/br/br-snapshot-manual.md +++ b/br/br-snapshot-manual.md @@ -42,6 +42,10 @@ br backup full \ - `--ratelimit`:**每个 TiKV** 执行备份任务的速度上限(单位 MiB/s)。 - `--log-file`:备份日志写入的目标文件。 +> **注意:** +> +> BR 工具已支持自适应 GC,会自动将 `backupTS`(默认是最新的 PD timestamp)注册到 PD 的 `safePoint`,保证 TiDB 的 GC Safe Point 在备份期间不会向前移动,即可避免手动设置 GC。 + 备份期间终端会显示进度条,效果如下。当进度条达到 100% 时,表示备份完成。 ```shell diff --git a/clinic/clinic-data-instruction-for-tiup.md b/clinic/clinic-data-instruction-for-tiup.md index 6ca1ab58613c..6106a4e3e44d 100644 --- a/clinic/clinic-data-instruction-for-tiup.md +++ b/clinic/clinic-data-instruction-for-tiup.md @@ -84,7 +84,7 @@ Clinic Server 是部署在云端的云服务,根据数据存储的位置不同 | 诊断数据类型 | 输出文件 | PingCAP Clinic 采集参数 | | :------ | :------ |:-------- | -| 获取 TiDB 系统变量(默认不采集,采集需要额外提供数据库帐号) | `mysql.tidb.csv` | `--include=db_vars`(默认不采集) | +| 获取 TiDB 系统变量(默认不采集,采集需要额外提供数据库账号) | `mysql.tidb.csv` | `--include=db_vars`(默认不采集) | | | `global_variables.csv` | `--include=db_vars`(默认不采集)| ### 集群节点的系统信息 diff --git a/clinic/quick-start-with-clinic.md b/clinic/quick-start-with-clinic.md index 59c807be57d0..5a84883590d4 100644 --- a/clinic/quick-start-with-clinic.md +++ b/clinic/quick-start-with-clinic.md @@ -34,13 +34,13 @@ PingCAP Clinic 由 [Diag 诊断客户端](https://github.com/pingcap/diag)(以
- 登录 [Clinic Server 中国区](https://clinic.pingcap.com.cn),选择 **Sign in with AskTUG** 进入 TiDB 社区 AskTUG 的登录界面。如果你尚未注册 AskTUG 帐号,可以在该界面进行注册。 + 登录 [Clinic Server 中国区](https://clinic.pingcap.com.cn),选择 **Sign in with AskTUG** 进入 TiDB 社区 AskTUG 的登录界面。如果你尚未注册 AskTUG 账号,可以在该界面进行注册。
- 登录 [Clinic Server 美国区](https://clinic.pingcap.com),选择 **Sign in with TiDB Account** 进入 TiDB Cloud Account 的登录界面。如果你尚未注册 TiDB Cloud 帐号,可以在该界面进行注册。 + 登录 [Clinic Server 美国区](https://clinic.pingcap.com),选择 **Sign in with TiDB Account** 进入 TiDB Cloud Account 的登录界面。如果你尚未注册 TiDB Cloud 账号,可以在该界面进行注册。 > **注意:** > diff --git a/clustered-indexes.md b/clustered-indexes.md index 691524e3ff90..660b6df68f0a 100644 --- a/clustered-indexes.md +++ b/clustered-indexes.md @@ -59,7 +59,7 @@ CREATE TABLE t (a BIGINT, b VARCHAR(255), PRIMARY KEY(a, b) /*T![clustered_index CREATE TABLE t (a BIGINT, b VARCHAR(255), PRIMARY KEY(a, b) /*T![clustered_index] NONCLUSTERED */); ``` -对于未显式指定该关键字的语句,默认行为受系统变量 `@@global.tidb_enable_clustered_index` 影响。该变量有三个取值: +对于未显式指定该关键字的语句,默认行为受系统变量 [`@@global.tidb_enable_clustered_index`](/system-variables.md#tidb_enable_clustered_index-从-v50-版本开始引入) 影响。该变量有三个取值: - `OFF` 表示所有主键默认使用非聚簇索引。 - `ON` 表示所有主键默认使用聚簇索引。 diff --git a/command-line-flags-for-tidb-configuration.md b/command-line-flags-for-tidb-configuration.md index 47541af041eb..6522d639e675 100644 --- a/command-line-flags-for-tidb-configuration.md +++ b/command-line-flags-for-tidb-configuration.md @@ -130,6 +130,11 @@ aliases: ['/docs-cn/dev/command-line-flags-for-tidb-configuration/','/docs-cn/de > > 如果使用 AWS 的 Network Load Balancer (NLB) 并开启 PROXY 协议,需要设置 NLB 的 `target group` 属性:将 `proxy_protocol_v2.client_to_server.header_place` 设为 `on_first_ack`。同时向 AWS 的 Support 提工单开通此功能的支持。注意,AWS NLB 在开启 PROXY 协议后,客户端将无法获取服务器端的握手报文,因此报文会一直阻塞到客户端超时。这是因为,NLB 默认只在客户端发送数据之后才会发送 PROXY 的报文,而在客户端发送数据包之前,服务器端发送的任何数据包都会在内网被丢弃。 +## `--proxy-protocol-fallbackable` + ++ 用于控制是否启用 PROXY 协议回退模式。如果设置为 `true`,TiDB 可以接受非 PROXY 协议规范或者没有发送 PROXY 协议头的客户端连接。默认情况下,TiDB 仅接受发送 PROXY 协议头的客户端连接。 ++ 默认:`false` + ## `--proxy-protocol-header-timeout` + PROXY 协议请求头读取超时时间 diff --git a/dashboard/continuous-profiling.md b/dashboard/continuous-profiling.md index b0cc87cdd5f3..3dc229b474b0 100644 --- a/dashboard/continuous-profiling.md +++ b/dashboard/continuous-profiling.md @@ -50,7 +50,7 @@ summary: 了解如何持续地收集 TiDB、TiKV、PD 各个实例的性能数 > > 要使用持续性能分析,你需要使用 TiUP(v1.9.0 及以上版本)或 TiDB Operator(v1.3.0 及以上版本)部署或升级集群。如果你已经使用旧版本 TiUP 或 TiDB Operator 进行了集群升级,请参见 [FAQ](/dashboard/dashboard-faq.md#界面提示-集群中未启动必要组件-ngmonitoring) 进行处理。 -从 TiDB v6.1.0 开始,持续性能分析默认处于开启状态。该功能启用后,TiDB Dashboard 会在后台持续收集性能数据,用户无需保持网页处于打开状态。后台收集的性能数据可设置保留时长,超过保留时长的性能数据将会被自动清理。 +该功能启用后,TiDB Dashboard 会在后台持续收集性能数据,用户无需保持网页处于打开状态。后台收集的性能数据可设置保留时长,超过保留时长的性能数据将会被自动清理。 你可以通过以下步骤启用该功能: diff --git a/dashboard/dashboard-statement-list.md b/dashboard/dashboard-statement-list.md index 0dfc1e240f39..3f27e1ad678c 100644 --- a/dashboard/dashboard-statement-list.md +++ b/dashboard/dashboard-statement-list.md @@ -70,6 +70,12 @@ SQL 语句分析页面所展示的所有数据都来自于 TiDB Statement 系统 > > 数据收集周期和保留时间的值会影响内存占用,因此建议根据实际情况调整,保留时间不宜设置过大。 +### Others + +[`tidb_stmt_summary_max_stmt_count`](/system-variables.md#tidb_stmt_summary_max_stmt_count-从-v40-版本开始引入) 控制 Statement Summary 系统表保存的 SQL 种类数量。当 SQL 种类超过该值时,会移除最近没有出现的 SQL。这些 SQL 将会被 `DIGEST` 为 `NULL` 的行数据统计。`DIGEST` 为 `NULL` 的行数据在 TiDB Dashboard SQL 语句分析列表页面中将会显示为 `Others`,如下所示: + +![Others 行](/media/dashboard/dashboard-statement-other-row.png) + ## 下一步 阅读[查看执行详情](/dashboard/dashboard-statement-details.md)章节了解如何进一步查看 SQL 语句的详细执行情况。 diff --git a/data-type-json.md b/data-type-json.md index 4b86b5c86a52..cb6d72c303c9 100644 --- a/data-type-json.md +++ b/data-type-json.md @@ -28,7 +28,7 @@ SELECT id FROM city WHERE population >= 100; ## 使用限制 - 暂不支持将 JSON 函数下推至 TiFlash。 -- TiDB Backup & Restore(BR)在 v6.3.0 之前不支持恢复包含 JSON 列的数据。另外,任何版本的 BR 都不支持恢复包含 JSON 列的数据到 v6.3.0 之前的 TiDB 集群。 +- TiDB Backup & Restore(BR)在 v6.3.0 版本对 JSON 列的数据的编码进行了修改。因此不建议使用 BR 恢复包含 JSON 列的数据到 v6.3.0 之前的 TiDB 集群。 - 请勿使用任何同步工具同步非标准 JSON 类型(例如 DATE、DATETIME、TIME 等)的数据。 ## MySQL 兼容性 diff --git a/derive-topn-from-window.md b/derive-topn-from-window.md new file mode 100644 index 000000000000..f089b967d95a --- /dev/null +++ b/derive-topn-from-window.md @@ -0,0 +1,192 @@ +--- +title: 从窗口函数中推导 TopN 或 Limit +summary: 介绍从窗口函数中推导 TopN 或 Limit 的优化规则,以及如何开启该规则。 +--- + +# 从窗口函数中推导 TopN 或 Limit + +[窗口函数](/functions-and-operators/window-functions.md)是一种常见的 SQL 函数。对于 `ROW_NUMBER()` 或者 `RANK()` 等编号相关的窗口函数,一种常见的用法是在进行窗口函数求值之后,对求值的结果进行过滤,例如: + +```sql +SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY a) AS rownumber FROM t) dt WHERE rownumber <= 3 +``` + +按照正常的 SQL 执行流程,TiDB 需要先对 `t` 表的所有数据进行排序,然后为每一行都求得相应的 `ROW_NUMBER()` 结果,最后再进行 `rownumber <= 3` 的过滤。 + +从 v7.0.0 开始,TiDB 支持从窗口函数中推导 TopN 或 Limit 算子。通过该优化规则,TiDB 可以将原始 SQL 等价改写成以下形式: + +```sql +WITH t_topN AS (SELECT a FROM t1 ORDER BY a LIMIT 3) SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY a) AS rownumber FROM t_topN) dt WHERE rownumber <= 3 +``` + +可以看出,改写后,TiDB 可以从窗口函数与后续的过滤条件中推导出一个 TopN 算子,相比于原始 SQL 中的 Sort 算子(对应 `ORDER BY`),TopN 算子的运行效率远高于 Sort 算子,而且 TiKV 和 TiFlash 均支持 TopN 算子的下推,因此能进一步提升改写后的 SQL 的性能。 + +从窗口函数中推导 TopN 或 Limit 默认关闭。你可以通过将 session 变量 [tidb_opt_derive_topn](/system-variables.md#tidb_opt_derive_topn-从-v700-版本开始引入) 设置为 `ON` 开启该功能。 + +开启后,如需关闭,可以进行以下操作之一: + +* 设置 session 变量 [tidb_opt_derive_topn](/system-variables.md#tidb_opt_derive_topn-从-v700-版本开始引入) 为 `false`。 +* 可参照[优化规则及表达式下推的黑名单](/blocklist-control-plan.md)中的关闭方法。 + +## 限制 + +* 目前仅 `ROW_NUMBER()` 窗口函数支持 SQL 语句改写。 +* 只有当 SQL 语句的过滤条件是针对 `ROW_NUMBER()` 结果而且过滤条件为 `<` 或者 `<=` 时,TiDB 才支持改写 SQL 语句。 + +## 示例 + +以下通过一些例子对该优化规则进行说明。 + +### 不包含 PARTITION BY 的窗口函数 + +#### 示例 1:不包含 ORDER BY 的窗口函数 + +```sql +CREATE TABLE t(id int, value int); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER () AS rownumber FROM t) dt WHERE rownumber <= 3; +``` + +``` ++----------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------+ +| Projection_9 | 2.40 | root | | Column#5 | +| └─Selection_10 | 2.40 | root | | le(Column#5, 3) | +| └─Window_11 | 3.00 | root | | row_number()->Column#5 over(rows between current row and current row) | +| └─Limit_15 | 3.00 | root | | offset:0, count:3 | +| └─TableReader_26 | 3.00 | root | | data:Limit_25 | +| └─Limit_25 | 3.00 | cop[tikv] | | offset:0, count:3 | +| └─TableFullScan_24 | 3.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++----------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------+ +``` + +在该查询中,优化器从窗口函数中推导出来了 Limit 并将它下推给了 TiKV。 + +#### 示例 2:包含 ORDER BY 的窗口函数 + +```sql +CREATE TABLE t(id int, value int); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY value) AS rownumber FROM t) dt WHERE rownumber <= 3; +``` + +``` ++----------------------------------+----------+-----------+---------------+---------------------------------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------------+----------+-----------+---------------+---------------------------------------------------------------------------------------------+ +| Projection_10 | 2.40 | root | | Column#5 | +| └─Selection_11 | 2.40 | root | | le(Column#5, 3) | +| └─Window_12 | 3.00 | root | | row_number()->Column#5 over(order by test.t.value rows between current row and current row) | +| └─TopN_13 | 3.00 | root | | test.t.value, offset:0, count:3 | +| └─TableReader_25 | 3.00 | root | | data:TopN_24 | +| └─TopN_24 | 3.00 | cop[tikv] | | test.t.value, offset:0, count:3 | +| └─TableFullScan_23 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++----------------------------------+----------+-----------+---------------+---------------------------------------------------------------------------------------------+ +``` + +在该查询中,优化器从窗口函数中推导出来了 TopN 并将它下推给了 TiKV。 + +### 包含 PARTITION BY 的窗口函数 + +> **注意:** +> +> 当窗口函数包含 PARTITION BY 时,该优化规则仅在 partition 列是主键的前缀且主键是聚簇索引的时候才能生效。 + +#### 示例 3:不包含 ORDER BY 的窗口函数 + +```sql +CREATE TABLE t(id1 int, id2 int, value1 int, value2 int, primary key(id1,id2) clustered); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY id1) AS rownumber FROM t) dt WHERE rownumber <= 3; +``` + +``` ++------------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++------------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +| Projection_10 | 2.40 | root | | Column#6 | +| └─Selection_11 | 2.40 | root | | le(Column#6, 3) | +| └─Shuffle_26 | 3.00 | root | | execution info: concurrency:2, data sources:[TableReader_24] | +| └─Window_12 | 3.00 | root | | row_number()->Column#6 over(partition by test.t.id1 rows between current row and current row) | +| └─Sort_25 | 3.00 | root | | test.t.id1 | +| └─TableReader_24 | 3.00 | root | | data:Limit_23 | +| └─Limit_23 | 3.00 | cop[tikv] | | partition by test.t.id1, offset:0, count:3 | +| └─TableFullScan_22 | 3.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++------------------------------------+---------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +``` + +在该查询中,优化器从窗口函数中推导出来了 Limit 并将它下推给了 TiKV。值得一提的是这个 Limit 其实是 partition Limit,也就是说对于每个相同 `id1` 值组成的一组数据上都会进行一次 Limit。 + +#### 示例 4:包含 ORDER BY 的窗口函数 + +```sql +CREATE TABLE t(id1 int, id2 int, value1 int, value2 int, primary key(id1,id2) clustered); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY id1 ORDER BY value1) AS rownumber FROM t) dt WHERE rownumber <= 3; +``` + +``` ++------------------------------------+----------+-----------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++------------------------------------+----------+-----------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| Projection_10 | 2.40 | root | | Column#6 | +| └─Selection_11 | 2.40 | root | | le(Column#6, 3) | +| └─Shuffle_23 | 3.00 | root | | execution info: concurrency:3, data sources:[TableReader_21] | +| └─Window_12 | 3.00 | root | | row_number()->Column#6 over(partition by test.t.id1 order by test.t.value1 rows between current row and current row) | +| └─Sort_22 | 3.00 | root | | test.t.id1, test.t.value1 | +| └─TableReader_21 | 3.00 | root | | data:TopN_19 | +| └─TopN_19 | 3.00 | cop[tikv] | | partition by test.t.id1 order by test.t.value1, offset:0, count:3 | +| └─TableFullScan_18 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++------------------------------------+----------+-----------+---------------+----------------------------------------------------------------------------------------------------------------------+ +``` + +在该查询中,优化器从窗口函数中推导出来了 TopN 并将它下推给了 TiKV。需要注意的是,这个 TopN 其实是 partition 的 TopN, 也就是说对于每个相同 `id1` 值组成的一组数据上都会进行一次 TopN。 + +#### 示例 5:PARTITION BY 列不是主键的前缀 + +```sql +CREATE TABLE t(id1 int, id2 int, value1 int, value2 int, primary key(id1,id2) clustered); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY value1) AS rownumber FROM t) dt WHERE rownumber <= 3; +``` + +``` ++----------------------------------+----------+-----------+---------------+--------------------------------------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------------+----------+-----------+---------------+--------------------------------------------------------------------------------------------------+ +| Projection_9 | 8000.00 | root | | Column#6 | +| └─Selection_10 | 8000.00 | root | | le(Column#6, 3) | +| └─Shuffle_15 | 10000.00 | root | | execution info: concurrency:5, data sources:[TableReader_13] | +| └─Window_11 | 10000.00 | root | | row_number()->Column#6 over(partition by test.t.value1 rows between current row and current row) | +| └─Sort_14 | 10000.00 | root | | test.t.value1 | +| └─TableReader_13 | 10000.00 | root | | data:TableFullScan_12 | +| └─TableFullScan_12 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++----------------------------------+----------+-----------+---------------+--------------------------------------------------------------------------------------------------+ +``` + +在该查询中,因为 partition 的列不是主键的前缀,所以 SQL 没有被改写。 + +#### 示例 6:PARTITION BY 列是主键的前缀,但主键不是聚簇索引 + +```sql +CREATE TABLE t(id1 int, id2 int, value1 int, value2 int, primary key(id1,id2) nonclustered); +SET tidb_opt_derive_topn=on; +EXPLAIN SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY id1) AS rownumber FROM t use index()) dt WHERE rownumber <= 3; +``` + +``` ++----------------------------------+----------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------------+----------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +| Projection_9 | 8000.00 | root | | Column#7 | +| └─Selection_10 | 8000.00 | root | | le(Column#7, 3) | +| └─Shuffle_15 | 10000.00 | root | | execution info: concurrency:5, data sources:[TableReader_13] | +| └─Window_11 | 10000.00 | root | | row_number()->Column#7 over(partition by test.t.id1 rows between current row and current row) | +| └─Sort_14 | 10000.00 | root | | test.t.id1 | +| └─TableReader_13 | 10000.00 | root | | data:TableFullScan_12 | +| └─TableFullScan_12 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | ++----------------------------------+----------+-----------+---------------+-----------------------------------------------------------------------------------------------+ +``` + +在该查询中,即使 PARTITION 的列是主键的前缀,但是因为主键不是聚簇索引,所以 SQL 没被改写。 diff --git a/develop/dev-guide-build-cluster-in-cloud.md b/develop/dev-guide-build-cluster-in-cloud.md index c34f593dbe2d..785286497ff0 100644 --- a/develop/dev-guide-build-cluster-in-cloud.md +++ b/develop/dev-guide-build-cluster-in-cloud.md @@ -14,8 +14,8 @@ aliases: ['/zh/tidb/dev/build-cluster-in-cloud'] ## 第 1 步:创建 Serverless Tier 集群 -1. 如果你还未拥有 TiDB Cloud 帐号,请先在此[注册](https://tidbcloud.com/free-trial)。 -2. 使用你的 TiDB Cloud 帐号[登录](https://tidbcloud.com/)。 +1. 如果你还未拥有 TiDB Cloud 账号,请先在此[注册](https://tidbcloud.com/free-trial)。 +2. 使用你的 TiDB Cloud 账号[登录](https://tidbcloud.com/)。 登录后,默认进入 [**Clusters**](https://tidbcloud.com/console/clusters) 页面。 @@ -46,8 +46,6 @@ aliases: ['/zh/tidb/dev/build-cluster-in-cloud'] 对于 macOS 操作系统,如果你没有安装 Homebrew,请参考 [Homebrew 官网](https://brew.sh/index_zh-cn)进行安装。 - {{< copyable "shell-regular" >}} - ```shell brew install mysql-client ``` @@ -68,16 +66,12 @@ aliases: ['/zh/tidb/dev/build-cluster-in-cloud'] 请运行其中的此行(命令行输出若与此处文档不一致,请以命令行输出为准): - {{< copyable "shell-regular" >}} - ```shell echo 'export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"' >> ~/.zshrc ``` 完成后,生效该配置文件(例如 `~/.zshrc`),并验证 MySQL 客户端是否安装成功: - {{< copyable "shell-regular" >}} - ```shell source ~/.zshrc mysql --version @@ -95,16 +89,12 @@ aliases: ['/zh/tidb/dev/build-cluster-in-cloud'] 对于 Linux 操作系统,下面以 CentOS 7 为例: - {{< copyable "shell-root" >}} - ```shell yum install mysql ``` 完成后,请验证 MySQL 客户端是否安装成功: - {{< copyable "shell-regular" >}} - ```shell mysql --version ``` @@ -121,8 +111,6 @@ aliases: ['/zh/tidb/dev/build-cluster-in-cloud'] 2. 运行第 1 步中得到的连接字符串。 - {{< copyable "shell-regular" >}} - ```shell mysql --connect-timeout 15 -u '.root' -h -P 4000 -D test --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/ssl/cert.pem -p ``` @@ -152,4 +140,4 @@ SELECT 'Hello TiDB Cloud!'; +-------------------+ ``` -如果你的实际输出与预期输出一致,表示你已经在 TiDB Cloud 上成功地运行了 SQL 语句。 \ No newline at end of file +如果你的实际输出与预期输出一致,表示你已经在 TiDB Cloud 上成功地运行了 SQL 语句。 diff --git a/develop/dev-guide-sample-application-spring-boot.md b/develop/dev-guide-sample-application-spring-boot.md index 1c6e4a275305..f16d9fbe07fe 100644 --- a/develop/dev-guide-sample-application-spring-boot.md +++ b/develop/dev-guide-sample-application-spring-boot.md @@ -1015,7 +1015,7 @@ public class PlayerController { **Spring Boot** -- 3.0.0-M2 +- 最新稳定版本 **Project Metadata** @@ -1032,10 +1032,6 @@ public class PlayerController { - Spring Data JPA - MySQL Driver -配置完毕后如图所示: - -![Spring Initializr Config](/media/develop/IMG_20220401-234316020.png) - > **注意:** > > 尽管 SQL 相对标准化,但每个数据库供应商都使用 ANSI SQL 定义语法的子集和超集。这被称为数据库的方言。 Hibernate 通过其 org.hibernate.dialect.Dialect 类和每个数据库供应商的各种子类来处理这些方言的变化。 @@ -1046,46 +1042,4 @@ public class PlayerController { > > _—— 节选自 Hibernate 官方文档: [Database Dialect](https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html#database-dialect)_ -随后,此项目即可正常使用,但仅可使用 TiDB 与 MySQL 相同的能力部分,即使用 MySQL 方言。这是由于 Hibernate 支持 TiDB 方言的版本为 6.0.0.Beta2 以上,而 Spring Data JPA 对 Hibernate 的默认依赖版本为 5.6.4.Final。所以,推荐对 pom.xml 作出以下修改: - -1. 如此[依赖文件](https://github.com/pingcap-inc/tidb-example-java/blob/main/spring-jpa-hibernate/pom.xml#L26)中所示,将 **Spring Data JPA** 内引入的 `jakarta` 包进行排除,即将: - - {{< copyable "" >}} - - ```xml - - org.springframework.boot - spring-boot-starter-data-jpa - - ``` - - 更改为: - - {{< copyable "" >}} - - ```xml - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.hibernate - hibernate-core-jakarta - - - - ``` - -2. 随后如此[依赖文件](https://github.com/pingcap-inc/tidb-example-java/blob/main/spring-jpa-hibernate/pom.xml#L53)中所示,引入 `6.0.0.Beta2` 版本以上的 **Hibernate** 依赖,此处以 `6.0.0.CR2` 版本为例: - - {{< copyable "" >}} - - ```xml - - org.hibernate.orm - hibernate-core - 6.0.0.CR2 - - ``` - - 更改完毕后即可获取一个空白的,拥有与示例程序相同依赖的 **Spring Boot** 应用程序。 \ No newline at end of file +随后,即可获取一个拥有与示例程序相同依赖的空白 **Spring Boot** 应用程序。 \ No newline at end of file diff --git a/develop/dev-guide-third-party-support.md b/develop/dev-guide-third-party-support.md index df2c8d31aaad..a9070752562c 100644 --- a/develop/dev-guide-third-party-support.md +++ b/develop/dev-guide-third-party-support.md @@ -7,7 +7,7 @@ aliases: ['/zh/tidb/dev/supported-by-pingcap'] > **注意:** > -> 本文档仅列举了常见的 TiDB 支持的第三方工具,未被列入其中的第三方工具并非代表不支持,但 PingCAP 无法了解其是否使用到 TiDB 不支持的特性,从而无法保证兼容性。 +> 本文档仅列举了常见的 TiDB 支持的[第三方工具](https://en.wikipedia.org/wiki/Third-party_source),未被列入其中的第三方工具并非代表不支持,但 PingCAP 无法了解其是否使用到 TiDB 不支持的特性,从而无法保证兼容性。 TiDB [高度兼容 MySQL 协议](/mysql-compatibility.md),使得大部分适配 MySQL 的 Driver、ORM 及其他工具与 TiDB 兼容。本文主要介绍这些工具和它们的支持等级。 diff --git a/develop/dev-guide-third-party-tools-compatibility.md b/develop/dev-guide-third-party-tools-compatibility.md index c299de7e6d48..5dc6f012ab5c 100644 --- a/develop/dev-guide-third-party-tools-compatibility.md +++ b/develop/dev-guide-third-party-tools-compatibility.md @@ -18,6 +18,8 @@ summary: 介绍在测试中发现的 TiDB 与第三方工具的兼容性问题 > > 这些不支持的功能不兼容将被视为预期行为,不再重复叙述。关于更多 TiDB 与 MySQL 的兼容性对比,你可以查看[与 MySQL 兼容性对比](/mysql-compatibility.md)。 +本文列举的兼容性问题是在一些 [TiDB 支持的第三方工具](/develop/dev-guide-third-party-support.md)中发现的。 + ## 通用 ### TiDB 中 `SELECT CONNECTION_ID()` 返回结果类型为 64 位整型 diff --git a/dm/task-configuration-file-full.md b/dm/task-configuration-file-full.md index ce23ddea7711..b1177b0c9b06 100644 --- a/dm/task-configuration-file-full.md +++ b/dm/task-configuration-file-full.md @@ -149,6 +149,18 @@ loaders: # load 处理单元的运行配置参数 # - "off"。表示导入完成后不进行数据校验。 # Checksum 对比失败通常表示导入异常(数据丢失或数据不一致),因此建议总是开启 Checksum。 checksum-physical: "required" + # 配置在 CHECKSUM 结束后是否对所有表执行 `ANALYZE TABLE ` 操作。 + # - "required"(默认值)。表示导入完成后进行 ANALYZE 操作,ANALYZE 操作失败时任务暂停,需要用户手动处理。 + # - "optional"。表示导入完成后进行 ANALYZE 操作,ANALYZE 操作失败时输出警告日志,任务不会暂停。 + # - "off"。表示导入完成后不进行 ANALYZE 操作。 + # ANALYZE 只影响统计数据,在大部分场景下建议不开启 ANALYZE。 + analyze: "off" + # Physical Import Mode 向 TiKV 写入 KV 数据的并发度。当 dm-worker 和 TiKV 网络传输速度超过万兆时,可适当增加这个值。 + # range-concurrency: 16 + # Physical Import Mode 向 TiKV 发送 KV 数据时是否启用压缩。目前仅支持 Gzip 压缩算法,可填写 "gzip" 或 "gz"。默认不启用压缩。 + # compress-kv-pairs: "" + # PD server 的地址,填一个即可。该值为空时,默认使用 TiDB 查询到的 PD 地址信息。 + # pd-addr: "192.168.0.1:2379" syncers: # sync 处理单元的运行配置参数 global: # 配置名称 diff --git a/dumpling-overview.md b/dumpling-overview.md index 5ba785f0b7f9..5cc028dc5afc 100644 --- a/dumpling-overview.md +++ b/dumpling-overview.md @@ -46,11 +46,10 @@ TiDB 还提供了其他工具,你可以根据需要选择使用: ### 需要的权限 -- SELECT -- RELOAD -- LOCK TABLES -- REPLICATION CLIENT -- PROCESS +- SELECT:导出目标表时需要。 +- RELOAD:使用 consistency flush 时需要。注意,只有 TiDB 支持该权限,当上游为 RDS 或采用托管服务时,可忽略该权限。 +- LOCK TABLES:使用 consistency lock 时需要,需要导出的库表都有该权限。 +- REPLICATION CLIENT:导出 metadata 记录数据快照点时需要,可选,如果不需要导出 metadata,可忽略该权限。 ### 导出为 SQL 文件 @@ -151,7 +150,7 @@ dumpling -u root -P 4000 -h 127.0.0.1 --filetype sql -t 8 -o /tmp/test -r 200000 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; ``` -+ `{schema}.{table}.{0001}.{sql|csv`}:数据源文件 ++ `{schema}.{table}.{0001}.{sql|csv}`:数据源文件 {{< copyable "shell-regular" >}} diff --git a/dynamic-config.md b/dynamic-config.md index 56cf15393f7b..d0f5e80726c1 100644 --- a/dynamic-config.md +++ b/dynamic-config.md @@ -208,7 +208,7 @@ show warnings; | server.max-grpc-send-msg-len | gRPC 可发送的最大消息长度 | | server.raft-msg-max-batch-size | 单个 gRPC 消息可包含的最大 Raft 消息个数 | | server.simplify-metrics | 精简监控采样数据的开关 | -| server.snap-max-write-bytes-per-sec | 处理 snapshot 时最大允许使用的磁盘带宽 | +| server.snap-io-max-bytes-per-sec | 处理 snapshot 时最大允许使用的磁盘带宽 | | server.concurrent-send-snap-limit | 同时发送 snapshot 的最大个数 | | server.concurrent-recv-snap-limit | 同时接受 snapshot 的最大个数 | | storage.block-cache.capacity | 共享 block cache 的大小(自 v4.0.3 起支持) | diff --git a/error-codes.md b/error-codes.md index 7b251e8a1752..d61aaf6f9df6 100644 --- a/error-codes.md +++ b/error-codes.md @@ -293,6 +293,66 @@ TiDB 兼容 MySQL 的错误码,在大多数情况下,返回和 MySQL 一样 当 [`tidb_constraint_check_in_place_pessimistic`](/system-variables.md#tidb_constraint_check_in_place_pessimistic-从-v630-版本开始引入) 设置为 `OFF` 时,为保证事务的正确性,SQL 语句执行时产生的任何错误都可能导致 TiDB 返回 `8147` 报错并中止当前事务。具体的错误原因,请参考对应的报错信息。详见[约束](/constraints.md#悲观事务)。 +* Error Number: 8154 + + 目前 `LOAD DATA` 不支持从 TiDB 服务器本地导入数据,可以指定 `LOCAL` 从客户端导入,或者将数据上传到 S3/GCS 再进行导入。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md)。 + +* Error Number: 8155 + + 目前 `LOAD DATA` 不支持从 local 导入 Parquet 格式的数据文件,只支持从 S3/GCS 导入 Parquet 格式的数据文件。你可以将数据上传到 S3/GCS 后再导入。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md)。 + +* Error Number: 8156 + + `LOAD DATA` 语句的文件路径不能为空。需要设置正确的路径再进行导入。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md)。 + +* Error Number: 8157 + + 不支持的数据格式。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 查看支持的数据格式。 + +* Error Number: 8158 + + 传入的 S3/GCS 路径无效。请参考[外部存储](/br/backup-and-restore-storages.md)设置有效的路径。 + +* Error Number: 8159 + + TiDB 无法访问 `LOAD DATA` 语句中传入的 S3/GCS 路径。请确保填入的 S3/GCS bucket 存在,且你输入了正确的 access key 和 secret access key 以让 TiDB 服务器有权限访问 S3/GCS 对应的 bucket。 + +* Error Number: 8160 + + `LOAD DATA` 读取数据文件失败。请根据具体的错误提示进行处理。 + +* Error Number: 8162 + + `LOAD DATA` 语句存在错误。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 查看已支持的功能。 + +* Error Number: 8163 + + 未知的 `LOAD DATA ... WITH ...` 选项。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 查看支持的选项。 + +* Error Number: 8164 + + `LOAD DATA ... WITH ...` 选项取值无效。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 查看有效的取值。 + +* Error Number: 8165 + + 重复指定了 `LOAD DATA ... WITH ...` 选项,每个选项只能指定一次。 + +* Error Number: 8166 + + 某些 `LOAD DATA ... WITH ...` 选项只能在特定的导入模式下才可以使用。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 查看支持的选项。 + +* Error Number: 8170 + + 指定的 `LOAD DATA` job 不存在或不是由当前用户创建。目前用户只能查看自己创建的 job。 + +* Error Number: 8171 + + 对不支持的 `LOAD DATA` 任务状态不能进行运维操作。请根据具体的错误提示进行处理。 + +* Error Number: 8172 + + 指定 `LOCAL` 的 `LOAD DATA` 不能在后台运行,只有使用 S3/GCS 路径的 `LOAD DATA` 可以在后台运行。请参考 [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) 更改 SQL 语句。 + * Error Number: 8200 尚不支持的 DDL 语法。请参考[与 MySQL DDL 的兼容性](/mysql-compatibility.md#ddl-的限制)。 diff --git a/faq/backup-and-restore-faq.md b/faq/backup-and-restore-faq.md index 16ea01a90b6a..773dc2750a0e 100644 --- a/faq/backup-and-restore-faq.md +++ b/faq/backup-and-restore-faq.md @@ -47,11 +47,9 @@ TiKV 支持[动态配置](/tikv-control.md#动态修改-tikv-的配置)自动调 Issue 链接:[#38045](https://github.com/pingcap/tidb/issues/38045) -当前[索引加速功能](/system-variables.md#tidb_ddl_enable_fast_reorg-从-v630-版本开始引入)与 PITR 功能不兼容。在使用索引加速功能时,需要确保后台没有启动 PITR 备份任务,否则可能会出现非预期结果。非预期场景包括: +当前通过[索引加速功能](/system-variables.md#tidb_ddl_enable_fast_reorg-从-v630-版本开始引入)创建的索引数据无法被 PITR 备份。 -- 如果先启动 PITR 备份任务,再添加索引,此时即使索引加速功能打开,也不会使用加速索引功能,但不影响索引兼容性。 -- 如果先启动添加索引加速任务,再创建 PITR 备份任务,此时 PITR 备份任务会报错,但不影响正在添加索引的任务。 -- 如果同时启动 PITR 备份任务和添加索引加速任务,可能会由于两个任务无法察觉到对方而导致 PITR 不能成功备份增加的索引数据。 +因此,在 PITR 恢复完成后,BR 会将通过索引加速功能创建的索引数据删除,再重新创建。如果在日志备份期间通过索引加速功能创建的索引很多或索引数据很大,建议在创建索引后进行一次全量备份。 ### 集群已经恢复了网络分区故障,为什么日志备份任务进度 checkpoint 仍然不推进? diff --git a/functions-and-operators/expressions-pushed-down.md b/functions-and-operators/expressions-pushed-down.md index 50bfe3f87211..be491e615200 100644 --- a/functions-and-operators/expressions-pushed-down.md +++ b/functions-and-operators/expressions-pushed-down.md @@ -14,186 +14,307 @@ TiFlash 也支持[本页](/tiflash/tiflash-supported-pushdown-calculations.md) | 表达式分类 | 具体操作 | | :-------------- | :------------------------------------- | -| [逻辑运算](/functions-and-operators/operators.md#逻辑操作符) | AND (&&), OR (||), NOT (!) | -| [比较运算](/functions-and-operators/operators.md#比较方法和操作符) | <, <=, =, != (`<>`), >, >=, [`<=>`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to), [`IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_in), IS NULL, LIKE, IS TRUE, IS FALSE, [`COALESCE()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce) | -| [数值运算](/functions-and-operators/numeric-functions-and-operators.md) | +, -, *, /, [`ABS()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs), [`CEIL()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceil), [`CEILING()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceiling), [`FLOOR()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor), [`MOD()`](https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_mod) | -| [控制流运算](/functions-and-operators/control-flow-functions.md) | [`CASE`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#operator_case), [`IF()`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_if), [`IFNULL()`](https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_ifnull) | -| [JSON 运算](/functions-and-operators/json-functions.md) | [JSON_TYPE(json_val)][json_type],
[JSON_EXTRACT(json_doc, path[, path] ...)][json_extract],
[JSON_OBJECT(key, val[, key, val] ...)][json_object],
[JSON_ARRAY([val[, val] ...])][json_array],
[JSON_MERGE(json_doc, json_doc[, json_doc] ...)][json_merge],
[JSON_SET(json_doc, path, val[, path, val] ...)][json_set],
[JSON_INSERT(json_doc, path, val[, path, val] ...)][json_insert],
[JSON_REPLACE(json_doc, path, val[, path, val] ...)][json_replace],
[JSON_REMOVE(json_doc, path[, path] ...)][json_remove] | -| [日期运算](/functions-and-operators/date-and-time-functions.md) | [`DATE_FORMAT()`](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format), [`SYSDATE()`](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sysdate) | -| [字符串函数](/functions-and-operators/string-functions.md) | [`RIGHT()`](https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_right) | +| [逻辑运算](/functions-and-operators/operators.md#逻辑操作符) | AND (&&), OR (||), NOT (!), XOR | +| [位运算](/functions-and-operators/operators.md#操作符) | [&][operator_bitwise-and], [~][operator_bitwise-invert], [\|][operator_bitwise-or], [^][operator_bitwise-xor], [<<][operator_left-shift], [>>][operator_right-shift] | +| [比较运算](/functions-and-operators/operators.md#比较方法和操作符) | [<][operator_less-than], [<=][operator_less-than-or-equal], [=][operator_equal], [!= (<\>)][operator_not-equal], [>][operator_greater-than], [>=][operator_greater-than-or-equal], [<=>][operator_equal-to], [BETWEEN ... AND ...][operator_between], [COALESCE()][function_coalesce], [IN()][operator_in], [INTERVAL()][function_interval], [IS NOT NULL][operator_is-not-null], [IS NOT][operator_is-not], [IS NULL][operator_is-null], [IS][operator_is], [ISNULL()][function_isnull], [LIKE][operator_like], [NOT BETWEEN ... AND ...][operator_not-between], [NOT IN()][operator_not-in], [NOT LIKE][operator_not-like], [STRCMP()][function_strcmp] | +| [数值运算](/functions-and-operators/numeric-functions-and-operators.md) | [+][operator_plus], [-][operator_minus], [*][operator_times], [/][operator_divide], [DIV][operator_div], [% (MOD)][operator_mod], [-][operator_unary-minus], [ABS()][function_abs], [ACOS()][function_acos], [ASIN()][function_asin], [ATAN()][function_atan], [ATAN2(), ATAN()][function_atan2], [CEIL()][function_ceil], [CEILING()][function_ceiling], [CONV()][function_conv], [COS()][function_cos], [COT()][function_cot], [CRC32()][function_crc32], [DEGREES()][function_degrees], [EXP()][function_exp], [FLOOR()][function_floor], [LN()][function_ln], [LOG()][function_log], [LOG10()][function_log10], [LOG2()][function_log2], [MOD()][function_mod], [PI()][function_pi], [POW()][function_pow], [POWER()][function_power], [RADIANS()][function_radians], [RAND()][function_rand], [ROUND()][function_round], [SIGN()][function_sign], [SIN()][function_sin], [SQRT()][function_sqrt] | +| [控制流运算](/functions-and-operators/control-flow-functions.md) | [CASE][operator_case], [IF()][function_if], [IFNULL()][function_ifnull] | +| [JSON 运算](/functions-and-operators/json-functions.md) | [JSON_ARRAY([val[, val] ...])][json_array],
[JSON_CONTAINS(target, candidate[, path])][json_contains],
[JSON_EXTRACT(json_doc, path[, path] ...)][json_extract],
[JSON_INSERT(json_doc, path, val[, path, val] ...)][json_insert],
[JSON_LENGTH(json_doc[, path])][json_length],
[JSON_MERGE(json_doc, json_doc[, json_doc] ...)][json_merge],
[JSON_OBJECT([key, val[, key, val] ...])][json_object],
[JSON_REMOVE(json_doc, path[, path] ...)][json_remove],
[JSON_REPLACE(json_doc, path, val[, path, val] ...)][json_replace],
[JSON_SET(json_doc, path, val[, path, val] ...)][json_set],
[JSON_TYPE(json_val)][json_type],
[JSON_UNQUOTE(json_val)][json_unquote],
[JSON_VALID(val)][json_valid] | +| [日期运算](/functions-and-operators/date-and-time-functions.md) | [DATE()][function_date], [DATE_FORMAT()][function_date-format], [DATEDIFF()][function_datediff], [DAYOFMONTH()][function_dayofmonth], [DAYOFWEEK()][function_dayofweek], [DAYOFYEAR()][function_dayofyear], [FROM_DAYS()][function_from-days], [HOUR()][function_hour], [MAKEDATE()][function_makedate], [MAKETIME()][function_maketime], [MICROSECOND()][function_microsecond], [MINUTE()][function_minute], [MONTH()][function_month], [MONTHNAME()][function_monthname], [PERIOD_ADD()][function_period-add], [PERIOD_DIFF()][function_period-diff], [SEC_TO_TIME()][function_sec-to-time], [SECOND()][function_second], [SYSDATE()][function_sysdate], [TIME_TO_SEC()][function_time-to-sec], [TIMEDIFF()][function_timediff], [WEEK()][function_week], [WEEKOFYEAR()][function_weekofyear], [YEAR()][function_year] | +| [字符串函数](/functions-and-operators/string-functions.md) | [ASCII()][function_ascii], [BIT_LENGTH()][function_bit-length], [CHAR()][function_char], [CHAR_LENGTH()][function_char-length], [CONCAT()][function_concat], [CONCAT_WS()][function_concat-ws], [ELT()][function_elt], [FIELD()][function_field], [HEX()][function_hex], [LENGTH()][function_length], [LIKE][operator_like], [LTRIM()][function_ltrim], [MID()][function_mid], [NOT LIKE][operator_not-like], [NOT REGEXP][operator_not-regexp], [REGEXP][operator_regexp], [REPLACE()][function_replace], [REVERSE()][function_reverse], [RIGHT()][function_right], [RTRIM()][function_rtrim], [SPACE()][function_space], [STRCMP()][function_strcmp], [SUBSTR()][function_substr], [SUBSTRING()][function_substring] | +| [聚合函数](/functions-and-operators/aggregate-group-by-functions.md#group-by-聚合函数) | [COUNT()][function_count], [COUNT(DISTINCT)][function_count-distinct], [SUM()][function_sum], [AVG()][function_avg], [MAX()][function_max], [MIN()][function_min], [VARIANCE()][function_variance], [VAR_POP()][function_var-pop], [STD()][function_std], [STDDEV()][function_stddev], [STDDEV_POP][function_stddev-pop], [VAR_SAMP()][function_var-samp], [STDDEV_SAMP()][function_stddev-samp], [JSON_ARRAYAGG(key)][json_arrayagg], [JSON_OBJECTAGG(key, value)][function_json-objectagg] | +| [加密和压缩函数](/functions-and-operators/encryption-and-compression-functions.md#加密和压缩函数) | [MD5()][function_md5], [SHA1(), SHA()][function_sha1], [UNCOMPRESSED_LENGTH()][function_uncompressed-length] | +| [Cast 函数](/functions-and-operators/cast-functions-and-operators.md#cast-函数和操作符) | [CAST()][function_cast], [CONVERT()][function_convert] | +| [其他函数](/functions-and-operators/miscellaneous-functions.md#支持的函数) | [UUID()][function_uuid] | ## 禁止特定表达式下推 -当[已支持下推的表达式列表](#已支持下推的表达式列表)中的函数和运算符,或特定的数据类型(**仅限** [`ENUM` 类型](/data-type-string.md#enum-类型) 和 [`BIT` 类型](/data-type-numeric.md#bit-类型))的计算过程因下推而出现异常时,你可以使用黑名单功能禁止其下推,从而快速恢复 TiDB 业务。具体而言,你可以将函数名、运算符名,或数据列类型加入黑名单 `mysql.expr_pushdown_blacklist` 中,以禁止特定表达式下推。具体方法,请参阅[加入黑名单](#加入黑名单)。 +当[已支持下推的表达式列表](#已支持下推的表达式列表)中的函数和运算符,或特定的数据类型(**仅限** [`ENUM` 类型](/data-type-string.md#enum-类型)和 [`BIT` 类型](/data-type-numeric.md#bit-类型))的计算过程因下推而出现异常时,你可以使用黑名单功能禁止其下推,从而快速恢复 TiDB 业务。具体而言,你可以将函数名、运算符名,或数据列类型加入黑名单 `mysql.expr_pushdown_blacklist` 中,以禁止特定表达式下推。具体方法,请参阅[表达式下推黑名单](/blocklist-control-plan.md#禁止特定表达式下推)。 -`mysql.expr_pushdown_blacklist` 的 schema 如下: +[function_abs]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs -```sql -tidb> desc mysql.expr_pushdown_blacklist; -+------------+--------------+------+------+-------------------+-------+ -| Field | Type | Null | Key | Default | Extra | -+------------+--------------+------+------+-------------------+-------+ -| name | char(100) | NO | | NULL | | -| store_type | char(100) | NO | | tikv,tiflash,tidb | | -| reason | varchar(200) | YES | | NULL | | -+------------+--------------+------+------+-------------------+-------+ -3 rows in set (0.00 sec) -``` - -以上结果字段解释如下: - -+ `name`:禁止下推的函数名、运算符名或数据类型。 -+ `store_type`:用于指定希望禁止该函数、运算符或数据类型下推到哪些组件进行计算。组件可选 `tidb`、`tikv` 和 `tiflash`。`store_type` 不区分大小写,如果需要禁止向多个存储引擎下推,各个存储之间需用逗号隔开。 - - `store_type` 为 `tidb` 时表示在读取 TiDB 内存表时,是否允许该函数在其他 TiDB Server 上执行。 - - `store_type` 为 `tikv` 时表示是否允许该函数在 TiKV Server 的 Coprocessor 模块中执行。 - - `store_type` 为 `tiflash` 时表示是否允许该函数在 TiFlash Server 的 Coprocessor 模块中执行。 -+ `reason`:用于记录该函数被加入黑名单的原因。 - -> **注意:** -> -> `tidb` 是一种特殊的 store_type,其含义是 TiDB 内存表,比如:`PERFORMANCE_SCHEMA.events_statements_summary_by_digest`,属于系统表的一种,非特殊情况不用考虑这种存储引擎。 - -### 加入黑名单 - -执行以下步骤,可将一个或多[函数名、运算符名](#已支持下推的表达式列表)或数据类型(**仅限** [`ENUM` 类型](/data-type-string.md#enum-类型) 和 [`BIT` 类型](/data-type-numeric.md#bit-类型))加入黑名单: - -1. 向 `mysql.expr_pushdown_blacklist` 插入以下内容: - - - 希望禁止下推的函数名、运算符名或数据类型 - - 希望禁止下推的存储引擎 - -2. 执行 `admin reload expr_pushdown_blacklist;`。 - -### 移出黑名单 - -执行以下步骤,可将一个或多个函数名、运算符名或数据类型移出黑名单: - -1. 从 `mysql.expr_pushdown_blacklist` 表中删除对应的函数名、运算符名或数据类型。 -2. 执行 `admin reload expr_pushdown_blacklist;`。 - -### 黑名单使用示例 - -以下示例首先将函数 `DATE_FORMAT()`、运算符 `>` 及数据类型 `BIT` 加入黑名单,然后再将运算符 `>` 从黑名单中移出。 - -黑名单是否生效可以从 `explain` 结果中进行观察(参见[如何理解 `explain` 结果](/explain-overview.md))。 - -```sql -tidb> create table t(a int); -Query OK, 0 rows affected (0.06 sec) - -tidb> explain select * from t where a < 2 and a > 2; -+-------------------------+----------+-----------+---------------+------------------------------------+ -| id | estRows | task | access object | operator info | -+-------------------------+----------+-----------+---------------+------------------------------------+ -| TableReader_7 | 0.00 | root | | data:Selection_6 | -| └─Selection_6 | 0.00 | cop[tikv] | | gt(ssb_1.t.a, 2), lt(ssb_1.t.a, 2) | -| └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | -+-------------------------+----------+-----------+---------------+------------------------------------+ -3 rows in set (0.00 sec) - -tidb> insert into mysql.expr_pushdown_blacklist values('date_format()', 'tikv',''), ('>','tikv',''), ('bit','tikv',''); -Query OK, 2 rows affected (0.01 sec) -Records: 2 Duplicates: 0 Warnings: 0 - -tidb> admin reload expr_pushdown_blacklist; -Query OK, 0 rows affected (0.00 sec) - -tidb> explain select * from t where a < 2 and a > 2; -+-------------------------+----------+-----------+---------------+------------------------------------+ -| id | estRows | task | access object | operator info | -+-------------------------+----------+-----------+---------------+------------------------------------+ -| Selection_7 | 10000.00 | root | | gt(ssb_1.t.a, 2), lt(ssb_1.t.a, 2) | -| └─TableReader_6 | 10000.00 | root | | data:TableFullScan_5 | -| └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | -+-------------------------+----------+-----------+---------------+------------------------------------+ -3 rows in set (0.00 sec) - -tidb> delete from mysql.expr_pushdown_blacklist where name = '>'; -Query OK, 1 row affected (0.01 sec) - -tidb> admin reload expr_pushdown_blacklist; -Query OK, 0 rows affected (0.00 sec) - -tidb> explain select * from t where a < 2 and a > 2; -+---------------------------+----------+-----------+---------------+--------------------------------+ -| id | estRows | task | access object | operator info | -+---------------------------+----------+-----------+---------------+--------------------------------+ -| Selection_8 | 0.00 | root | | lt(ssb_1.t.a, 2) | -| └─TableReader_7 | 0.00 | root | | data:Selection_6 | -| └─Selection_6 | 0.00 | cop[tikv] | | gt(ssb_1.t.a, 2) | -| └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | -+---------------------------+----------+-----------+---------------+--------------------------------+ -4 rows in set (0.00 sec) -``` - -> **注意:** -> -> - `admin reload expr_pushdown_blacklist` 只对执行该 SQL 语句的 TiDB server 生效。若需要集群中所有 TiDB server 生效,需要在每台 TiDB server 上执行该 SQL 语句。 -> - 表达式黑名单功能在 v3.0.0 及以上版本中支持。 -> - 在 v3.0.3 及以下版本中,不支持将某些运算符的原始名称文本(如 ">"、"+" 和 "is null")加入黑名单中,部分运算符在黑名单中需使用别名。已支持下推的表达式中,别名与原始名不同的运算符见下表(区分大小写)。 - -| 运算符原始名称 | 运算符别名 | -| :-------- | :---------- | -| < | lt | -| > | gt | -| <= | le | -| >= | ge | -| = | eq | -| != | ne | -| `<>` | ne | -| `<=>` | nulleq | -| | | bitor | -| && | bitand| -| || | or | -| ! | not | -| in | in | -| + | plus| -| - | minus | -| * | mul | -| / | div | -| DIV | intdiv| -| IS NULL | isnull | -| IS TRUE | istrue | -| IS FALSE | isfalse | +[function_acos]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_acos -[json_extract]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-extract +[function_ascii]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_ascii -[json_short_extract]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#operator_json-column-path +[function_asin]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_asin -[json_short_extract_unquote]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#operator_json-inline-path +[function_atan]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_atan -[json_unquote]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-unquote +[function_atan2]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_atan2 -[json_type]: https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-type +[function_avg]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_avg -[json_set]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-set +[function_bit-length]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_bit-length -[json_insert]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-insert +[function_cast]: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast -[json_replace]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-replace +[function_ceil]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceil -[json_remove]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-remove +[function_ceiling]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceiling -[json_merge]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge +[function_char-length]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_char-length -[json_merge_preserve]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge-preserve +[function_char]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_char -[json_object]: https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-object +[function_coalesce]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce + +[function_concat-ws]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_concat-ws + +[function_concat]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_concat + +[function_conv]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_conv + +[function_convert]: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert + +[function_cos]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_cos + +[function_cot]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_cot + +[function_count-distinct]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_count-distinct + +[function_count]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_count + +[function_crc32]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_crc32 + +[function_date-format]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format + +[function_date]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date + +[function_datediff]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff + +[function_dayofmonth]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofmonth + +[function_dayofweek]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofweek + +[function_dayofyear]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofyear + +[function_degrees]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_degrees + +[function_elt]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_elt + +[function_exp]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_exp + +[function_field]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_field + +[function_floor]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor + +[function_from-days]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_from-days + +[function_hex]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_hex + +[function_hour]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_hour + +[function_if]: https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_if + +[function_ifnull]: https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#function_ifnull + +[function_interval]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_interval + +[function_isnull]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_isnull + +[function_json-objectagg]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-objectagg + +[function_length]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_length + +[function_ln]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_ln + +[function_log]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_log + +[function_log10]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_log10 + +[function_log2]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_log2 + +[function_ltrim]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_ltrim + +[function_makedate]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_makedate + +[function_maketime]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_maketime + +[function_max]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_max + +[function_md5]: https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_md5 + +[function_microsecond]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_microsecond + +[function_mid]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_mid + +[function_min]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_min + +[function_minute]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_minute + +[function_mod]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_mod + +[function_month]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_month + +[function_monthname]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_monthname + +[function_period-add]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_period-add + +[function_period-diff]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_period-diff + +[function_pi]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_pi + +[function_pow]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_pow + +[function_power]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_power + +[function_radians]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_radians + +[function_rand]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_rand + +[function_replace]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_replace + +[function_reverse]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_reverse + +[function_right]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_right + +[function_round]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_round + +[function_rtrim]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_rtrim + +[function_sec-to-time]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sec-to-time + +[function_second]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_second + +[function_sha1]: https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_sha1 + +[function_sign]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_sign + +[function_sin]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_sin + +[function_space]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_space + +[function_sqrt]: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_sqrt + +[function_std]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_std + +[function_stddev-pop]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_stddev-pop + +[function_stddev-samp]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_stddev-samp + +[function_stddev]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_stddev + +[function_strcmp]: https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#function_strcmp + +[function_substr]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substr + +[function_substring]: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring + +[function_sum]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_sum + +[function_sysdate]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sysdate + +[function_time-to-sec]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time-to-sec + +[function_timediff]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff + +[function_uncompressed-length]: https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompressed-length + +[function_uuid]: https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_uuid + +[function_var-pop]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_var-pop + +[function_var-samp]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_var-samp + +[function_variance]: https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_variance + +[function_week]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_week + +[function_weekofyear]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_weekofyear + +[function_year]: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_year [json_array]: https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-array -[json_keys]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-keys +[json_arrayagg]:https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-arrayagg + +[json_contains]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-contains + +[json_extract]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-extract + +[json_insert]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-insert [json_length]: https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-length +[json_merge]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge + +[json_object]: https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-object + +[json_remove]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-remove + +[json_replace]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-replace + +[json_set]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-set + +[json_type]: https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-type + +[json_unquote]: https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-unquote + [json_valid]: https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-valid -[json_quote]: https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-quote +[operator_between]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between -[json_contains]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-contains +[operator_bitwise-and]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_bitwise-and -[json_contains_path]: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-contains-path +[operator_bitwise-invert]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_bitwise-invert -[json_arrayagg]:https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-arrayagg +[operator_bitwise-or]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_bitwise-or + +[operator_bitwise-xor]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_bitwise-xor + +[operator_case]: https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html#operator_case + +[operator_div]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_div + +[operator_divide]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_divide + +[operator_equal-to]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to + +[operator_equal]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal + +[operator_greater-than-or-equal]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_greater-than-or-equal + +[operator_greater-than]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_greater-than + +[operator_in]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_in + +[operator_is-not-null]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is-not-null + +[operator_is-not]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is-not + +[operator_is-null]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is-null + +[operator_is]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is + +[operator_left-shift]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_left-shift + +[operator_less-than-or-equal]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_less-than-or-equal + +[operator_less-than]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_less-than + +[operator_like]: https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_like + +[operator_minus]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_minus + +[operator_mod]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_mod + +[operator_not-between]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-between + +[operator_not-equal]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-equal + +[operator_not-in]: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-in + +[operator_not-like]: https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_not-like + +[operator_not-regexp]: https://dev.mysql.com/doc/refman/5.7/en/regexp.html#operator_not-regexp + +[operator_plus]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_plus + +[operator_regexp]: https://dev.mysql.com/doc/refman/5.7/en/regexp.html#operator_regexp + +[operator_right-shift]: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html#operator_right-shift + +[operator_times]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_times -[json_depth]: https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-depth +[operator_unary-minus]: https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_unary-minus diff --git a/functions-and-operators/information-functions.md b/functions-and-operators/information-functions.md index c7839eb17ceb..580d2e79715d 100644 --- a/functions-and-operators/information-functions.md +++ b/functions-and-operators/information-functions.md @@ -13,6 +13,7 @@ TiDB 支持使用 MySQL 5.7 中提供的大部分[信息函数](https://dev.mysq | ------ | ---------------------------------------- | | [`BENCHMARK()`](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_benchmark) | 循环执行一个表达式 | | [`CONNECTION_ID()`](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_connection-id) | 返回当前连接的连接 ID (线程 ID) | +| `CURRENT_RESOURCE_GROUP()` | 返回当前连接的资源组名 | | [`CURRENT_USER()`, `CURRENT_USER`](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user) | 返回当前用户的用户名和主机名 | | [`DATABASE()`](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_database) | 返回默认(当前)的数据库名 | | [`FOUND_ROWS()`](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_found-rows) | 该函数返回对于一个包含 LIMIT 的 SELECT 查询语句,在不包含 LIMIT 的情况下回返回的记录数 | diff --git a/functions-and-operators/operators.md b/functions-and-operators/operators.md index c45ede34842c..daf25a5f5876 100644 --- a/functions-and-operators/operators.md +++ b/functions-and-operators/operators.md @@ -47,6 +47,10 @@ aliases: ['/docs-cn/dev/functions-and-operators/operators/','/docs-cn/dev/refere | [`-`](https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_unary-minus) | 取反符号 | | [`XOR`](https://dev.mysql.com/doc/refman/5.7/en/logical-operators.html#operator_xor) | 逻辑亦或 | +## 不支持的操作符 + +* [`SOUNDS LIKE`](https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#operator_sounds-like) + ## 操作符优先级 操作符优先级显示在以下列表中,从最高优先级到最低优先级。同一行显示的操作符具有相同的优先级。 @@ -84,7 +88,7 @@ OR, || | [`>`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_greater-than) | 大于 | | [`>=`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_greater-than-or-equal) | 大于或等于 | | [`GREATEST()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest) | 返回最大值 | -| [`IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_in) | 判断值是否在一个值的集合内 | +| [`IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_in) | 判断值是否在一个值的集合内 | | [`INTERVAL()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_interval) | 返回一个小于第一个参数的参数的下标 | | [`IS`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is) | 判断是否等于一个布尔值 | | [`IS NOT`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is-not) | 判断是否不等于一个布尔值 | @@ -97,7 +101,7 @@ OR, || | [`LIKE`](https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_like) | 简单模式匹配 | | [`NOT BETWEEN ... AND ...`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-between) | 判断值是否不在范围内 | | [`!=`, `<>`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-equal) | 不等于 | -| [`NOT IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_not-in) | 判断值是否不在一个值的集合内 | +| [`NOT IN()`](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_not-in) | 判断值是否不在一个值的集合内 | | [`NOT LIKE`](https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_not-like) | 不满足简单模式匹配 | | [`STRCMP()`](https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#function_strcmp) | 比较两个字符串 | diff --git a/functions-and-operators/string-functions.md b/functions-and-operators/string-functions.md index 8a82559971e5..cae401a00f78 100644 --- a/functions-and-operators/string-functions.md +++ b/functions-and-operators/string-functions.md @@ -75,9 +75,8 @@ TiDB 支持使用大部分 MySQL 5.7 中提供的[字符串函数](https://dev.m ## 不支持的函数 * `LOAD_FILE()` -* `MATCH` +* `MATCH()` * `SOUNDEX()` -* `SOUNDS LIKE` ## 正则函数与 MySQL 的兼容性 diff --git a/grafana-resource-control-dashboard.md b/grafana-resource-control-dashboard.md index eb1e6e15fda1..d209d02d474b 100644 --- a/grafana-resource-control-dashboard.md +++ b/grafana-resource-control-dashboard.md @@ -11,26 +11,36 @@ summary: 了解资源管控 (Resource Control) 的 Grafana Dashboard 中所展 如果你的集群配置了 [Resource Control](/tidb-resource-control.md) ,通过观察 Resource Control 面板上的 Metrics,你可以了解当前集群整体的资源消耗状态。 +TiDB 使用[令牌桶算法](https://en.wikipedia.org/wiki/Token_bucket) 做流控,正如资源管控实现机制 ([RFC: Global Resource Control in TiDB](https://github.com/pingcap/tidb/blob/master/docs/design/2022-11-25-global-resource-control.md#distributed-token-buckets)) 中所描述:一个 TiDB 节点可能存在多个 Resource Group(资源组),将在 PD 端的 GAC(Global Admission Control)进行流控。每个 TiDB 节点中的本地令牌桶(Local Token Buckets)将定期(默认 5 秒)与 PD 端的 GAC 进行通信,以重新配置本地令牌。其中的本地令牌桶(Local Token Buckets)具体实现为 Resource Controller Client。 + 以下为 **Resource Control** 关键监控指标的说明。 ## Request Unit 相关指标 -- RU:以 Resource Group 为单位进行实时统计的 [Request Unit (RU)](/tidb-resource-control.md#什么是-request-unit-ru) 消耗信息。`total` 为当前所有 Resource Group 消耗的 Request Unit 之和。每个 Resource Group 的 Request Unit 消耗等于其读消耗 (Read Request Unit) 和写消耗 (Write Request Unit) 之和。 +- RU:以 Resource Group(资源组)为单位进行实时统计的 [Request Unit (RU)](/tidb-resource-control.md#什么是-request-unit-ru) 消耗信息。`total` 为当前所有 Resource Group 消耗的 Request Unit 之和。每个 Resource Group 的 Request Unit 消耗等于其读消耗 (Read Request Unit) 和写消耗 (Write Request Unit) 之和。 - RU Per Query:平均每个 SQL 语句消耗的 Request Unit 数量。计算方法是将前述 Request Unit 监控指标除以当前每秒执行的 SQL 语句数量。 - RRU:以 Resource Group 为单位进行实时统计的读请求 Read Request Unit 消耗信息。`total` 为当前所有 Resource Group 消耗的 Read Request Unit 之和。 - RRU Per Query:平均每个 SQL 语句消耗的 Read Request Unit 数量。计算方法是将前述 Read Request Unit 监控指标除以当前每秒执行的 SQL 语句数量。 - WRU:以 Resource Group 为单位进行实时统计的写请求 Write Request Unit 消耗信息。`total` 为当前所有 Resource Group 消耗的 Write Request Unit 之和。 - WRU Per Query:平均每个 SQL 语句消耗的 Write Request Unit 数量。计算方法是将前述 Write Request Unit 监控指标除以当前每秒执行的 SQL 语句数量。 -## 资源相关指标 +## Resource 相关指标 -- KV Request Count:以 Resource Group 为单位进行实时统计的 KV 请求数量,区分了读和写两种类型。`total` 为当前所有 Resource Group 涉及的 KV 请求数量之和。 +- KV Request Count:以 Resource Group(资源组)为单位进行实时统计的 KV 请求数量,区分了读和写两种类型。`total` 为当前所有 Resource Group 涉及的 KV 请求数量之和。 - KV Request Count Per Query:平均每个 SQL 语句涉及的读写 KV 请求数量。计算方法是将前述 KV Request Count 监控指标除以当前每秒执行的 SQL 语句数量。 - Bytes Read:以 Resource Group 为单位进行实时统计的读取数据量。`total` 为当前所有 Resource Group 读取数据量之和。 - Bytes Read Per Query:平均每个 SQL 语句的读取数据量。将前述 Bytes Read 监控指标除以当前每秒执行的 SQL 语句数量。 - Bytes Written:以 Resource Group 为单位进行实时统计的写入数据量。`total` 为当前所有 Resource Group 写入数据量之和。 - Bytes Written Per Query:平均每个 SQL 语句的写入数据量。计算方法是将前述 Bytes Written 监控指标除以当前每秒执行的 SQL 语句数量。 - KV CPU Time:以 Resource Group 为单位进行实时统计的 KV 层 CPU 时间消耗。`total` 为当前所有 Resource Group 消耗 KV 层 CPU 时间之和。 -- KV CPU Time Per Query:平均每个 SQL 语句的 KV 层 CPU 时间消耗之和。计算方法是将前述 KV CPU Time 监控指标除以当前每秒执行的 SQL 语句数量。 - SQL CPU Time:以 Resource Group 为单位进行实时统计的 SQL 层 CPU 时间消耗。`total` 为当前所有 Resource Group 消耗 SQL 层 CPU 时间之和。 -- SQL CPU Time Per Query:平均每个 SQL 语句的 SQL 层 CPU 时间消耗之和。计算方法是将前述 SQL CPU Time 监控除以当前每秒执行的 SQL 语句数量。 + +## Resource Controller Client 相关指标 + +- Active Resource Groups:实时统计各个 Resource Controller Client 的 Resource Groups 数量。 +- Total KV Request Count:以 Resource Group 为单位,实时统计各个 Resource Controller Client 的 KV 请求数量。`total` 为 Resource Controller Client 下 KV 请求数量之和。 +- Failed KV Request Count:以 Resource Group 为单位,实时统计各个 Resource Controller Client 的 KV 失败请求数量。`total` 为 Resource Controller Client 下 KV 失败请求数量之和。 +- Successful KV Request Count:以 Resource Group 为单位,实时统计各个 Resource Controller Client 的 KV 成功请求数量。`total` 为 Resource Controller Client 下 KV 成功请求数量之和。 +- Successful KV Request Wait Duration (99/90):以 Resource Group 为单位,实时统计各个 Resource Controller Client 成功 KV 请求的等待时间(不同百分位)。 +- Token Request Handle Duration (999/99):以 Resource Group 为单位,实时统计各个 Resource Controller Client 向 Server 端申请 Token 等待的响应时间(不同百分位)。 +- Token Request Count:以 Resource Group 为单位,实时统计各个 Resource Controller Client 向 Server 端申请 Token 的次数。`successful` 和 `failed` 分别为 Resource Controller Client 下申请 Token 成功和失败数量之和。 diff --git a/information-schema/client-errors-summary-by-host.md b/information-schema/client-errors-summary-by-host.md index 42cb5b1a3f01..dfe64264f925 100644 --- a/information-schema/client-errors-summary-by-host.md +++ b/information-schema/client-errors-summary-by-host.md @@ -1,6 +1,6 @@ --- title: CLIENT_ERRORS_SUMMARY_BY_HOST -summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_HOST`。 +summary: 了解 INFORMATION_SCHEMA 表 `CLIENT_ERRORS_SUMMARY_BY_HOST`。 --- # CLIENT_ERRORS_SUMMARY_BY_HOST @@ -13,7 +13,7 @@ summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_HOST`。 * 权限错误。 * 表不存在。 -以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`information_schema`.`CLIENT_ERRORS_SUMMARY_BY_HOST` 表提供了一种有效方法,能够在应用程序没有正确处理(或记录)TiDB 服务器返回的错误的情况下检查错误。 +以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_HOST` 表提供了一种有效方法,能够在应用程序没有正确处理(或记录)TiDB 服务器返回的错误的情况下检查错误。 由于 `CLIENT_ERRORS_SUMMARY_BY_HOST` 会基于每个远程主机汇总错误,在诊断其中一台应用程序服务器比其他服务器生成更多错误的情况时很有用。可能的情况包括: @@ -24,13 +24,13 @@ summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_HOST`。 可以使用 `FLUSH CLIENT_ERRORS_SUMMARY` 语句重置汇总的计数。所汇总的是每个 TiDB 服务器的本地数据,并且只保留在内存中。如果 TiDB 服务器重新启动,会丢失汇总信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; +USE INFORMATION_SCHEMA; DESC CLIENT_ERRORS_SUMMARY_BY_HOST; ``` +输出结果如下: + ```sql +---------------+---------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -58,8 +58,6 @@ DESC CLIENT_ERRORS_SUMMARY_BY_HOST; 以下示例显示了客户端连接到本地 TiDB 服务器时生成的警告。执行 `FLUSH CLIENT_ERRORS_SUMMARY` 语句后,会重置汇总。 -{{< copyable "sql" >}} - ```sql SELECT 0/0; SELECT * FROM CLIENT_ERRORS_SUMMARY_BY_HOST; @@ -67,6 +65,8 @@ FLUSH CLIENT_ERRORS_SUMMARY; SELECT * FROM CLIENT_ERRORS_SUMMARY_BY_HOST; ``` +输出结果如下: + ```sql +-----+ | 0/0 | diff --git a/information-schema/client-errors-summary-by-user.md b/information-schema/client-errors-summary-by-user.md index f296103e0292..13233b023d72 100644 --- a/information-schema/client-errors-summary-by-user.md +++ b/information-schema/client-errors-summary-by-user.md @@ -1,6 +1,6 @@ --- title: CLIENT_ERRORS_SUMMARY_BY_USER -summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_USER`。 +summary: 了解 INFORMATION_SCHEMA 表 `CLIENT_ERRORS_SUMMARY_BY_USER`。 --- # CLIENT_ERRORS_SUMMARY_BY_USER @@ -13,7 +13,7 @@ summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_USER`。 * 权限错误。 * 表不存在。 -以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`information_schema`.`CLIENT_ERRORS_SUMMARY_BY_USER` 表提供了一种有效方法,能够在应用程序没有正确处理(或记录)TiDB 服务器返回的错误的情况下检查错误。 +以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER` 表提供了一种有效方法,能够在应用程序没有正确处理(或记录)TiDB 服务器返回的错误的情况下检查错误。 因为 `CLIENT_ERRORS_SUMMARY_BY_USER` 会基于每个用户汇总错误,所以在诊断一个用户服务器比其他服务器产生更多错误的方案时很有用。可能的情况包括: @@ -23,10 +23,8 @@ summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_BY_USER`。 可以使用 `FLUSH CLIENT_ERRORS_SUMMARY` 语句重置汇总的计数。所汇总的是每个 TiDB 服务器的本地数据,并且只保留在内存中。如果 TiDB 服务器重新启动,会丢失汇总信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; +USE INFORMATION_SCHEMA; DESC CLIENT_ERRORS_SUMMARY_BY_USER; ``` @@ -57,8 +55,6 @@ DESC CLIENT_ERRORS_SUMMARY_BY_USER; 以下示例显示了客户端连接到本地 TiDB 服务器时生成的警告。执行 `FLUSH CLIENT_ERRORS_SUMMARY` 语句后,会重置汇总。 -{{< copyable "sql" >}} - ```sql SELECT 0/0; SELECT * FROM CLIENT_ERRORS_SUMMARY_BY_USER; @@ -66,6 +62,8 @@ FLUSH CLIENT_ERRORS_SUMMARY; SELECT * FROM CLIENT_ERRORS_SUMMARY_BY_USER; ``` +输出结果如下: + ```sql +-----+ | 0/0 | diff --git a/information-schema/client-errors-summary-global.md b/information-schema/client-errors-summary-global.md index dd8d3c9d5a95..a48385c3ce38 100644 --- a/information-schema/client-errors-summary-global.md +++ b/information-schema/client-errors-summary-global.md @@ -13,17 +13,17 @@ summary: 了解 information_schema 表 `CLIENT_ERRORS_SUMMARY_GLOBAL`。 * 权限错误。 * 表不存在。 -以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`information_schema`.`CLIENT_ERRORS_SUMMARY_BY_GLOBAL` 表提供了高级概述,在应用程序无法正确处理(或记录)TiDB 服务器返回的错误的情况下很有用。 +以上错误通过 MySQL 服务器协议返回给客户端,此时应用程序应在客户端采取适当操作。`information_schema.CLIENT_ERRORS_SUMMARY_BY_GLOBAL` 表提供了高级概述,在应用程序无法正确处理(或记录)TiDB 服务器返回的错误的情况下很有用。 可以使用 `FLUSH CLIENT_ERRORS_SUMMARY` 语句重置汇总的计数。所汇总的是每个 TiDB 服务器的本地数据,并且只保留在内存中。如果 TiDB 服务器重新启动,会丢失汇总信息。 -{{< copyable "sql" >}} - ```sql USE information_schema; DESC CLIENT_ERRORS_SUMMARY_GLOBAL; ``` +输出结果如下: + ```sql +---------------+---------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -49,8 +49,6 @@ DESC CLIENT_ERRORS_SUMMARY_GLOBAL; 以下示例显示了客户端连接到本地 TiDB 服务器时生成的警告。执行 `FLUSH CLIENT_ERRORS_SUMMARY` 语句后,会重置汇总。 -{{< copyable "sql" >}} - ```sql SELECT 0/0; SELECT * FROM CLIENT_ERRORS_SUMMARY_GLOBAL; @@ -58,6 +56,8 @@ FLUSH CLIENT_ERRORS_SUMMARY; SELECT * FROM CLIENT_ERRORS_SUMMARY_GLOBAL; ``` +输出结果如下: + ```sql +-----+ | 0/0 | diff --git a/information-schema/information-schema-character-sets.md b/information-schema/information-schema-character-sets.md index 2a278829664b..336f15540b6f 100644 --- a/information-schema/information-schema-character-sets.md +++ b/information-schema/information-schema-character-sets.md @@ -1,19 +1,19 @@ --- title: CHARACTER_SETS -summary: 了解 information_schema 表 `CHARACTER_SETS`。 +summary: 了解 INFORMATION_SCHEMA 表 `CHARACTER_SETS`。 --- # CHARACTER_SETS `CHARACTER_SETS` 表提供[字符集](/character-set-and-collation.md)相关的信息。TiDB 目前仅支持部分字符集。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC character_sets; +USE INFORMATION_SCHEMA; +DESC CHARACTER_SETS; ``` +输出结果如下: + ```sql +----------------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -26,23 +26,26 @@ DESC character_sets; 4 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +查看 `CHARACTER_SETS` 表的信息: ```sql -SELECT * FROM `character_sets`; +SELECT * FROM `CHARACTER_SETS`; ``` +输出结果如下: + ```sql -+--------------------+----------------------+---------------+--------+ -| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION | MAXLEN | -+--------------------+----------------------+---------------+--------+ -| utf8 | utf8_bin | UTF-8 Unicode | 3 | -| utf8mb4 | utf8mb4_bin | UTF-8 Unicode | 4 | -| ascii | ascii_bin | US ASCII | 1 | -| latin1 | latin1_bin | Latin1 | 1 | -| binary | binary | binary | 1 | -+--------------------+----------------------+---------------+--------+ -5 rows in set (0.00 sec) ++--------------------+----------------------+-------------------------------------+--------+ +| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION | MAXLEN | ++--------------------+----------------------+-------------------------------------+--------+ +| ascii | ascii_bin | US ASCII | 1 | +| binary | binary | binary | 1 | +| gbk | gbk_chinese_ci | Chinese Internal Code Specification | 2 | +| latin1 | latin1_bin | Latin1 | 1 | +| utf8 | utf8_bin | UTF-8 Unicode | 3 | +| utf8mb4 | utf8mb4_bin | UTF-8 Unicode | 4 | ++--------------------+----------------------+-------------------------------------+--------+ +6 rows in set (0.00 sec) ``` `CHARACTER_SETS` 表中列的含义如下: diff --git a/information-schema/information-schema-cluster-info.md b/information-schema/information-schema-cluster-info.md index ac573a539c2c..74d5b0983d6c 100644 --- a/information-schema/information-schema-cluster-info.md +++ b/information-schema/information-schema-cluster-info.md @@ -26,8 +26,9 @@ desc cluster_info; | GIT_HASH | varchar(64) | YES | | NULL | | | START_TIME | varchar(32) | YES | | NULL | | | UPTIME | varchar(32) | YES | | NULL | | +| SERVER_ID | bigint(21) | YES | | NULL | | +----------------+-------------+------+------+---------+-------+ -7 rows in set (0.00 sec) +8 rows in set (0.01 sec) ``` 字段解释: @@ -39,6 +40,7 @@ desc cluster_info; * `GIT_HASH`:编译节点版本时的 Git Commit Hash,用于识别两个节点是否是绝对一致的版本。 * `START_TIME`:对应节点的启动时间。 * `UPTIME`:对应节点已经运行的时间。 +* `SERVER_ID`:对应节点的服务器 ID。 {{< copyable "sql" >}} diff --git a/information-schema/information-schema-collation-character-set-applicability.md b/information-schema/information-schema-collation-character-set-applicability.md index 96a2110bee93..0bc65e477b4f 100644 --- a/information-schema/information-schema-collation-character-set-applicability.md +++ b/information-schema/information-schema-collation-character-set-applicability.md @@ -1,19 +1,19 @@ --- title: COLLATION_CHARACTER_SET_APPLICABILITY -summary: 了解 information_schema 表 `COLLATION_CHARACTER_SET_APPLICABILITY`。 +summary: 了解 INFORMATION_SCHEMA 表 `COLLATION_CHARACTER_SET_APPLICABILITY`。 --- # COLLATION_CHARACTER_SET_APPLICABILITY `COLLATION_CHARACTER_SET_APPLICABILITY` 表将排序规则映射至适用的字符集名称。和 `COLLATIONS` 表一样,包含此表只是为了兼容 MySQL。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC collation_character_set_applicability; +USE INFORMATION_SCHEMA; +DESC COLLATION_CHARACTER_SET_APPLICABILITY; ``` +输出结果如下: + ```sql +--------------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -24,19 +24,23 @@ DESC collation_character_set_applicability; 2 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +查看 `COLLATION_CHARACTER_SET_APPLICABILITY` 表中 `utf8mb4` 字符集的排序规则映射: ```sql -SELECT * FROM collation_character_set_applicability WHERE character_set_name='utf8mb4'; +SELECT * FROM COLLATION_CHARACTER_SET_APPLICABILITY WHERE character_set_name='utf8mb4'; ``` +输出结果如下: + ```sql -+----------------+--------------------+ -| COLLATION_NAME | CHARACTER_SET_NAME | -+----------------+--------------------+ -| utf8mb4_bin | utf8mb4 | -+----------------+--------------------+ -1 row in set (0.00 sec) ++--------------------+--------------------+ +| COLLATION_NAME | CHARACTER_SET_NAME | ++--------------------+--------------------+ +| utf8mb4_bin | utf8mb4 | +| utf8mb4_general_ci | utf8mb4 | +| utf8mb4_unicode_ci | utf8mb4 | ++--------------------+--------------------+ +3 rows in set (0.00 sec) ``` `COLLATION_CHARACTER_SET_APPLICABILITY` 表中列的含义如下: diff --git a/information-schema/information-schema-columns.md b/information-schema/information-schema-columns.md index 122279a3b8c1..f5b9dafafccb 100644 --- a/information-schema/information-schema-columns.md +++ b/information-schema/information-schema-columns.md @@ -1,19 +1,19 @@ --- title: COLUMNS -summary: 了解 information_schema 表 `COLUMNS`。 +summary: 了解 INFORMATION_SCHEMA 表 `COLUMNS`。 --- # COLUMNS `COLUMNS` 表提供了表的所有列的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC columns; +USE INFORMATION_SCHEMA; +DESC COLUMNS; ``` +输出结果如下: + ```sql +--------------------------+---------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -43,13 +43,15 @@ DESC columns; 21 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +创建表 `test.t1`,并查询 `COLUMNS` 表的信息: ```sql CREATE TABLE test.t1 (a int); -SELECT * FROM columns WHERE table_schema='test' AND TABLE_NAME='t1'\G +SELECT * FROM COLUMNS WHERE table_schema='test' AND TABLE_NAME='t1'\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** TABLE_CATALOG: def @@ -68,11 +70,11 @@ CHARACTER_MAXIMUM_LENGTH: NULL CHARACTER_SET_NAME: NULL COLLATION_NAME: NULL COLUMN_TYPE: int(11) - COLUMN_KEY: - EXTRA: + COLUMN_KEY: + EXTRA: PRIVILEGES: select,insert,update,references - COLUMN_COMMENT: - GENERATION_EXPRESSION: + COLUMN_COMMENT: + GENERATION_EXPRESSION: 1 row in set (0.02 sec) ``` @@ -106,12 +108,12 @@ CHARACTER_MAXIMUM_LENGTH: NULL 对应的 `SHOW` 语句如下: -{{< copyable "sql" >}} - ```sql SHOW COLUMNS FROM t1 FROM test; ``` +输出结果如下: + ```sql +-------+---------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | diff --git a/information-schema/information-schema-deadlocks.md b/information-schema/information-schema-deadlocks.md index c3458e5da157..fda0330cb31e 100644 --- a/information-schema/information-schema-deadlocks.md +++ b/information-schema/information-schema-deadlocks.md @@ -1,19 +1,19 @@ --- title: DEADLOCKS -summary: 了解 information_schema 表 `DEADLOCKS`。 +summary: 了解 INFORMATION_SCHEMA 表 `DEADLOCKS`。 --- # DEADLOCKS `DEADLOCKS` 表提供当前 TiDB 节点上最近发生的若干次死锁错误的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC deadlocks; +USE INFORMATION_SCHEMA; +DESC DEADLOCKS; ``` +输出结果如下: + ```sql +-------------------------+---------------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -41,7 +41,7 @@ DESC deadlocks; * `CURRENT_SQL_DIGEST`:试图上锁的事务中当前正在执行的 SQL 语句的 Digest。 * `CURRENT_SQL_DIGEST_TEXT`:试图上锁的事务中当前正在执行的 SQL 语句的归一化形式。 * `KEY`:该事务试图上锁、但是被阻塞的 key,以十六进制编码的形式显示。 -* `KEY_INFO`:对 `KEY` 进行解读得出的一些详细信息,详见 [KEY_INFO](#key_info)。 +* `KEY_INFO`:对 `KEY` 进行解读得出的一些详细信息,详见 [`KEY_INFO`](#key_info)。 * `TRX_HOLDING_LOCK`:该 key 上当前持锁并导致阻塞的事务 ID,即事务的 `start_ts`。 要调整 `DEADLOCKS` 表中可以容纳的死锁事件数量,可通过 TiDB 配置文件中的 [`pessimistic-txn.deadlock-history-capacity`](/tidb-configuration-file.md#deadlock-history-capacity) 配置项进行调整,默认容纳最近 10 次死锁错误的信息。 @@ -49,24 +49,24 @@ DESC deadlocks; > **注意:** > > * 仅拥有 [PROCESS](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_process) 权限的用户可以查询该表。 -> * `CURRENT_SQL_DIGEST` 列中的信息(SQL Digest)为 SQL 语句进行归一化后计算得到的哈希值。`CURRENT_SQL_DIGEST_TEXT` 列中的信息为内部从 Statements Summary 系列表中查询得到,因而存在内部查询不到对应语句的可能性。关于 SQL Digest 和 Statements Summary 相关表的详细说明,请参阅[Statement Summary Tables](/statement-summary-tables.md)。 +> * `CURRENT_SQL_DIGEST` 列中的信息 (SQL Digest) 为 SQL 语句进行归一化后计算得到的哈希值。`CURRENT_SQL_DIGEST_TEXT` 列中的信息为内部从 Statements Summary 系列表中查询得到,因而存在内部查询不到对应语句的可能性。关于 SQL Digest 和 Statements Summary 相关表的详细说明,请参阅[Statement Summary Tables](/statement-summary-tables.md)。 ## `KEY_INFO` `KEY_INFO` 列中展示了对 `KEY` 列中所给出的 key 的详细信息,以 JSON 格式给出。其包含的信息如下: -* `"db_id"`:该 key 所属的数据库(schema)的 ID。 -* `"db_name"`:该 key 所属的数据库(schema)的名称。 +* `"db_id"`:该 key 所属的数据库 (schema) 的 ID。 +* `"db_name"`:该 key 所属的数据库 (schema) 的名称。 * `"table_id"`:该 key 所属的表的 ID。 * `"table_name"`:该 key 所属的表的名称。 -* `"partition_id"`:该 key 所在的分区(partition)的 ID。 -* `"partition_name"`:该 key 所在的分区(partition)的名称。 -* `"handle_type"`:该 row key (即储存一行数据的 key)的 handle 类型,其可能的值有: +* `"partition_id"`:该 key 所在的分区 (partition) 的 ID。 +* `"partition_name"`:该 key 所在的分区 (partition) 的名称。 +* `"handle_type"`:该 row key(即储存一行数据的 key)的 handle 类型,其可能的值有: * `"int"`:handle 为 int 类型,即 handle 为 row ID * `"common"`:非 int64 类型的 handle,在启用 clustered index 时非 int 类型的主键会显示为此类型 * `"unknown"`:当前暂不支持的 handle 类型 * `"handle_value"`:handle 的值。 -* `"index_id"`:该 index key (即储存索引的 key)所属的 index ID。 +* `"index_id"`:该 index key(即储存索引的 key)所属的 index ID。 * `"index_name"`:该 index key 所属的 index 名称。 * `"index_values"`:该 index key 中的 index value。 @@ -89,19 +89,15 @@ DESC deadlocks; 对于情况一,TiDB 将会向事务 A 的客户端报告死锁错误,并终止该事务;而对于情况二,事务 A 当前正在执行的语句将在 TiDB 内部被自动重试。例如,假设事务 A 执行了如下语句: -{{< copyable "sql" >}} - ```sql -update t set v = v + 1 where id = 1 or id = 2; +UPDATE t SET v = v + 1 WHERE id = 1 OR id = 2; ``` 事务 B 则先后执行如下两条语句: -{{< copyable "sql" >}} - ```sql -update t set v = 4 where id = 2; -update t set v = 2 where id = 1; +UPDATE t SET v = 4 WHERE id = 2; +UPDATE t SET v = 2 WHERE id = 1; ``` 那么如果事务 A 先后对 `id = 1` 和 `id = 2` 的两行分别上锁,且两个事务以如下时序运行: @@ -119,30 +115,28 @@ update t set v = 2 where id = 1; 假设有如下表定义和初始数据: -{{< copyable "sql" >}} - ```sql -create table t (id int primary key, v int); -insert into t values (1, 10), (2, 20); +CREATE TABLE t (id int primary key, v int); +INSERT INTO t VALUES (1, 10), (2, 20); ``` 使两个事务按如下顺序执行: | 事务 1 | 事务 2 | 说明 | |--------------------------------------|--------------------------------------|----------------------| -| `update t set v = 11 where id = 1;` | | | -| | `update t set v = 21 where id = 2;` | | -| `update t set v = 12 where id = 2;` | | 事务 1 阻塞 | -| | `update t set v = 22 where id = 1;` | 事务 2 报出死锁错误 | - -接下来,事务 2 将报出死锁错误。此时,查询 `DEADLOCKS` 表,将得到如下结果: +| `UPDATE t SET v = 11 WHERE id = 1;` | | | +| | `UPDATE t SET v = 21 WHERE id = 2;` | | +| `UPDATE t SET v = 12 WHERE id = 2;` | | 事务 1 阻塞 | +| | `UPDATE t SET v = 22 WHERE id = 1;` | 事务 2 报出死锁错误 | -{{< copyable "sql" >}} +接下来,事务 2 将报出死锁错误。此时,查询 `DEADLOCKS` 表: ```sql -select * from information_schema.deadlocks; +SELECT * FROM INFORMATION_SCHEMA.DEADLOCKS; ``` +输出结果如下: + ```sql +-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+-----------------------------------------+----------------------------------------+----------------------------------------------------------------------------------------------------+--------------------+ | DEADLOCK_ID | OCCUR_TIME | RETRYABLE | TRY_LOCK_TRX_ID | CURRENT_SQL_DIGEST | CURRENT_SQL_DIGEST_TEXT | KEY | KEY_INFO | TRX_HOLDING_LOCK | @@ -178,11 +172,9 @@ select * from information_schema.deadlocks; 需要注意的是,由于 `DEADLOCK_ID` 并不保证全局唯一,所以在 `CLUSTER_DEADLOCKS` 表的查询结果中,需要 `INSTANCE` 和 `DEADLOCK_ID` 两个字段共同区分结果集中的不同死锁错误的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC cluster_deadlocks; +USE INFORMATION_SCHEMA; +DESC CLUSTER_DEADLOCKS; ``` ```sql diff --git a/information-schema/information-schema-metrics-tables.md b/information-schema/information-schema-metrics-tables.md index 644c10a32670..e184927f84ed 100644 --- a/information-schema/information-schema-metrics-tables.md +++ b/information-schema/information-schema-metrics-tables.md @@ -6,15 +6,15 @@ aliases: ['/docs-cn/dev/reference/system-databases/metrics-tables/','/zh/tidb/de # METRICS_TABLES -`METRICS_TABLES` 表为 [metrics_schema](/metrics-schema.md) 数据库中的每个视图提供 PromQL(Prometheus 查询语言)定义。 - -{{< copyable "sql" >}} +`METRICS_TABLES` 表为 [`METRICS_SCHEMA`](/metrics-schema.md) 数据库中的每个视图提供 PromQL(Prometheus 查询语言)定义。 ```sql -USE information_schema; -DESC metrics_tables; +USE INFORMATION_SCHEMA; +DESC METRICS_TABLES; ``` +输出结果如下: + ```sql +------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -27,27 +27,27 @@ DESC metrics_tables; +------------+--------------+------+------+---------+-------+ ``` -表 `metrics_tables` 的字段解释: +表 `METRICS_TABLES` 的字段解释: -* `TABLE_NAME`:对应于 `metrics_schema` 中的表名。 -* `PROMQL`:监控表的主要原理是将 SQL 映射成 `PromQL`,并将 Prometheus 结果转换成 SQL 查询结果。这个字段是 `PromQL` 的表达式模板,查询监控表数据时使用查询条件改写模板中的变量,生成最终的查询表达式。 -* `LABELS`:监控定义的 label,每一个 label 对应监控表中的一列。SQL 中如果包含对应列的过滤,对应的 `PromQL` 也会改变。 +* `TABLE_NAME`:对应于 `METRICS_SCHEMA` 中的表名。 +* `PROMQL`:监控表的主要原理是将 SQL 映射成 PromQL,并将 Prometheus 结果转换成 SQL 查询结果。这个字段是 PromQL 的表达式模板,查询监控表数据时使用查询条件改写模板中的变量,生成最终的查询表达式。 +* `LABELS`:监控定义的 label,每一个 label 对应监控表中的一列。SQL 中如果包含对应列的过滤,对应的 PromQL 也会改变。 * `QUANTILE`:百分位。对于直方图类型的监控数据,指定一个默认百分位。如果值为 `0`,表示该监控表对应的监控不是直方图。 * `COMMENT`:对这个监控表的注释。 -{{< copyable "sql" >}} - ```sql -SELECT * FROM metrics_tables LIMIT 5\G +SELECT * FROM METRICS_TABLES LIMIT 5\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** TABLE_NAME: abnormal_stores PROMQL: sum(pd_cluster_status{ type=~"store_disconnected_count|store_unhealth_count|store_low_space_count|store_down_count|store_offline_count|store_tombstone_count"}) LABELS: instance,type QUANTILE: 0 - COMMENT: + COMMENT: *************************** 2. row *************************** TABLE_NAME: etcd_disk_wal_fsync_rate PROMQL: delta(etcd_disk_wal_fsync_duration_seconds_count{$LABEL_CONDITIONS}[$RANGE_DURATION]) diff --git a/information-schema/information-schema-partitions.md b/information-schema/information-schema-partitions.md index 29af83145158..6878aea234a8 100644 --- a/information-schema/information-schema-partitions.md +++ b/information-schema/information-schema-partitions.md @@ -1,19 +1,19 @@ --- title: PARTITIONS -summary: 了解 information_schema 表 `PARTITIONS`。 +summary: 了解 INFORMATION_SCHEMA 表 `PARTITIONS`。 --- # PARTITIONS `PARTITIONS` 表提供有关分区表的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC partitions; +USE INFORMATION_SCHEMA; +DESC PARTITIONS; ``` +输出结果如下: + ```sql +-------------------------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -27,9 +27,9 @@ DESC partitions; | SUBPARTITION_ORDINAL_POSITION | bigint(21) | YES | | NULL | | | PARTITION_METHOD | varchar(18) | YES | | NULL | | | SUBPARTITION_METHOD | varchar(12) | YES | | NULL | | -| PARTITION_EXPRESSION | longblob | YES | | NULL | | -| SUBPARTITION_EXPRESSION | longblob | YES | | NULL | | -| PARTITION_DESCRIPTION | longblob | YES | | NULL | | +| PARTITION_EXPRESSION | longtext | YES | | NULL | | +| SUBPARTITION_EXPRESSION | longtext | YES | | NULL | | +| PARTITION_DESCRIPTION | longtext | YES | | NULL | | | TABLE_ROWS | bigint(21) | YES | | NULL | | | AVG_ROW_LENGTH | bigint(21) | YES | | NULL | | | DATA_LENGTH | bigint(21) | YES | | NULL | | @@ -43,17 +43,19 @@ DESC partitions; | PARTITION_COMMENT | varchar(80) | YES | | NULL | | | NODEGROUP | varchar(12) | YES | | NULL | | | TABLESPACE_NAME | varchar(64) | YES | | NULL | | +| TIDB_PARTITION_ID | bigint(21) | YES | | NULL | | +| TIDB_PLACEMENT_POLICY_NAME | varchar(64) | YES | | NULL | | +-------------------------------+--------------+------+------+---------+-------+ -25 rows in set (0.00 sec) +27 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} - ```sql CREATE TABLE test.t1 (id INT NOT NULL PRIMARY KEY) PARTITION BY HASH (id) PARTITIONS 2; -SELECT * FROM partitions WHERE table_schema='test' AND table_name='t1'\G +SELECT * FROM PARTITIONS WHERE table_schema='test' AND table_name='t1'\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** TABLE_CATALOG: def @@ -67,20 +69,22 @@ SUBPARTITION_ORDINAL_POSITION: NULL SUBPARTITION_METHOD: NULL PARTITION_EXPRESSION: `id` SUBPARTITION_EXPRESSION: NULL - PARTITION_DESCRIPTION: + PARTITION_DESCRIPTION: TABLE_ROWS: 0 AVG_ROW_LENGTH: 0 DATA_LENGTH: 0 MAX_DATA_LENGTH: 0 INDEX_LENGTH: 0 DATA_FREE: 0 - CREATE_TIME: 2020-07-06 16:35:28 + CREATE_TIME: 2022-12-14 06:09:33 UPDATE_TIME: NULL CHECK_TIME: NULL CHECKSUM: NULL - PARTITION_COMMENT: + PARTITION_COMMENT: NODEGROUP: NULL TABLESPACE_NAME: NULL + TIDB_PARTITION_ID: 89 + TIDB_PLACEMENT_POLICY_NAME: NULL *************************** 2. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: test @@ -93,19 +97,21 @@ SUBPARTITION_ORDINAL_POSITION: NULL SUBPARTITION_METHOD: NULL PARTITION_EXPRESSION: `id` SUBPARTITION_EXPRESSION: NULL - PARTITION_DESCRIPTION: + PARTITION_DESCRIPTION: TABLE_ROWS: 0 AVG_ROW_LENGTH: 0 DATA_LENGTH: 0 MAX_DATA_LENGTH: 0 INDEX_LENGTH: 0 DATA_FREE: 0 - CREATE_TIME: 2020-07-06 16:35:28 + CREATE_TIME: 2022-12-14 06:09:33 UPDATE_TIME: NULL CHECK_TIME: NULL CHECKSUM: NULL - PARTITION_COMMENT: + PARTITION_COMMENT: NODEGROUP: NULL TABLESPACE_NAME: NULL + TIDB_PARTITION_ID: 90 + TIDB_PLACEMENT_POLICY_NAME: NULL 2 rows in set (0.00 sec) ``` diff --git a/information-schema/information-schema-referential-constraints.md b/information-schema/information-schema-referential-constraints.md index c474450343a4..8e962fe64513 100644 --- a/information-schema/information-schema-referential-constraints.md +++ b/information-schema/information-schema-referential-constraints.md @@ -1,19 +1,19 @@ --- title: REFERENTIAL_CONSTRAINTS -summary: 了解 information_schema 表 `REFERENTIAL_CONSTRAINTS`。 +summary: 了解 INFORMATION_SCHEMA 表 `REFERENTIAL_CONSTRAINTS`。 --- # REFERENTIAL_CONSTRAINTS `REFERENTIAL_CONSTRAINTS` 表提供 TiDB 表之间 `FOREIGN KEY` 关系的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC referential_constraints; +USE INFORMATION_SCHEMA; +DESC REFERENTIAL_CONSTRAINTS; ``` +输出结果如下: + ```sql +---------------------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -33,26 +33,26 @@ DESC referential_constraints; 11 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} - ```sql CREATE TABLE test.parent ( - id INT NOT NULL AUTO_INCREMENT, - PRIMARY KEY (id) + id INT NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id) ); CREATE TABLE test.child ( - id INT NOT NULL AUTO_INCREMENT, - name varchar(255) NOT NULL, - parent_id INT DEFAULT NULL, - PRIMARY KEY (id), - CONSTRAINT fk_parent FOREIGN KEY (parent_id) REFERENCES parent (id) ON UPDATE CASCADE ON DELETE RESTRICT + id INT NOT NULL AUTO_INCREMENT, + name varchar(255) NOT NULL, + parent_id INT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT fk_parent FOREIGN KEY (parent_id) REFERENCES parent (id) ON UPDATE CASCADE ON DELETE RESTRICT ); -SELECT * FROM referential_constraints\G +SELECT * FROM REFERENTIAL_CONSTRAINTS\G ``` -``` +输出结果如下: + +```sql *************************** 1. row *************************** CONSTRAINT_CATALOG: def CONSTRAINT_SCHEMA: test @@ -66,4 +66,4 @@ UNIQUE_CONSTRAINT_CATALOG: def TABLE_NAME: child REFERENCED_TABLE_NAME: parent 1 row in set (0.00 sec) -``` \ No newline at end of file +``` diff --git a/information-schema/information-schema-resource-groups.md b/information-schema/information-schema-resource-groups.md index bbc9bb94cb16..08c2b4df0100 100644 --- a/information-schema/information-schema-resource-groups.md +++ b/information-schema/information-schema-resource-groups.md @@ -22,6 +22,7 @@ DESC resource_groups; +------------+-------------+------+------+---------+-------+ | NAME | varchar(32) | NO | | NULL | | | RU_PER_SEC | bigint(21) | YES | | NULL | | +| PRIORITY | varchar(6) | YES | | NULL | | | BURSTABLE | varchar(3) | YES | | NULL | | +------------+-------------+------+------+---------+-------+ 3 rows in set (0.00 sec) @@ -30,21 +31,48 @@ DESC resource_groups; ## 示例 ```sql -mysql> CREATE RESOURCE GROUP rg1 RU_PER_SEC=1000; -- 创建资源组 rg1 +SELECT * FROM information_schema.resource_groups; -- 查看资源组,TiDB 默认预置 `default` 资源组 +``` + +```sql ++---------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++---------+------------+----------+-----------+ +| default | UNLIMITED | MEDIUM | YES | ++---------+------------+----------+-----------+ +``` + +```sql +CREATE RESOURCE GROUP rg1 RU_PER_SEC=1000; -- 创建资源组 `rg1` +``` + +```sql Query OK, 0 rows affected (0.34 sec) -mysql> SHOW CREATE RESOURCE GROUP rg1; -- 显示 rg1 资源组的定义 -+----------------+---------------------------------------------+ -| Resource_Group | Create Resource Group | -+----------------+---------------------------------------------+ -| rg1 | CREATE RESOURCE GROUP `rg1` RU_PER_SEC=1000 | -+----------------+---------------------------------------------+ +``` + +```sql +SHOW CREATE RESOURCE GROUP rg1; -- 显示 `rg1` 资源组的定义 +``` + +```sql ++----------------+---------------------------------------------------------------+ +| Resource_Group | Create Resource Group | ++----------------+---------------------------------------------------------------+ +| rg1 | CREATE RESOURCE GROUP `rg1` RU_PER_SEC=1000 PRIORITY="MEDIUM" | ++----------------+---------------------------------------------------------------+ 1 row in set (0.00 sec) -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME = 'rg1'; -+------+------------+-----------+ -| NAME | RU_PER_SEC | BURSTABLE | -+------+------------+-----------+ -| rg1 | 1000 | NO | -+------+------------+-----------+ +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME = 'rg1'; -- 查看资源组 `rg1` +``` + +```sql ++------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++------+------------+----------+-----------+ +| rg1 | 1000 | MEDIUM | NO | ++------+------------+----------+-----------+ 1 row in set (0.00 sec) ``` @@ -52,4 +80,9 @@ mysql> SELECT * FROM information_schema.resource_groups WHERE NAME = 'rg1'; * `NAME`:资源组名称。 * `RU_PER_SEC`:资源组的回填速度,单位为每秒回填的 [Request Unit (RU)](/tidb-resource-control.md#什么是-request-unit-ru) 数量。 +* `PRIORITY`:任务在 TiKV 上处理的绝对优先级。不同的资源按照 `PRIORITY` 的设置进行调度,`PRIORITY` 高的任务会被优先调度。如果资源组的 `PRIORITY` 相同,则会根据 `RU_PER_SEC` 的配置按比例调度。如果不指定 `PRIORITY`,资源组的默认优先级为 `MEDIUM`。 * `BURSTABLE`:是否允许此资源组超额使用剩余的系统资源。 + +> **注意:** +> +> TiDB 集群在初始化时会自动创建 `default` 资源组,其 `RU_PER_SEC` 的默认值为 `UNLIMITED` (等同于 `INT` 类型最大值,即 `2147483647`),且为 `BURSTABLE` 模式。所有未绑定资源组的请求都将自动绑定至此资源组。在新建配置其他资源组时,建议根据实际情况修改 `default` 资源组的配置。 diff --git a/information-schema/information-schema-sequences.md b/information-schema/information-schema-sequences.md index 3d0e1d7e2911..09ea3833a688 100644 --- a/information-schema/information-schema-sequences.md +++ b/information-schema/information-schema-sequences.md @@ -1,19 +1,19 @@ --- title: SEQUENCES -summary: 了解 information_schema 表 `SEQUENCES`。 +summary: 了解 INFORMATION_SCHEMA 表 `SEQUENCES`。 --- # SEQUENCES `SEQUENCES` 表提供了有关序列的信息。TiDB 中[序列](/sql-statements/sql-statement-create-sequence.md)的功能是参照 MariaDB 中的类似功能来实现的。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC sequences; +USE INFORMATION_SCHEMA; +DESC SEQUENCES; ``` +输出结果如下: + ```sql +-----------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -21,9 +21,9 @@ DESC sequences; | TABLE_CATALOG | varchar(512) | NO | | NULL | | | SEQUENCE_SCHEMA | varchar(64) | NO | | NULL | | | SEQUENCE_NAME | varchar(64) | NO | | NULL | | -| CACHE | tinyint(4) | NO | | NULL | | +| CACHE | tinyint(0) | NO | | NULL | | | CACHE_VALUE | bigint(21) | YES | | NULL | | -| CYCLE | tinyint(4) | NO | | NULL | | +| CYCLE | tinyint(0) | NO | | NULL | | | INCREMENT | bigint(21) | NO | | NULL | | | MAX_VALUE | bigint(21) | YES | | NULL | | | MIN_VALUE | bigint(21) | YES | | NULL | | @@ -33,14 +33,15 @@ DESC sequences; 11 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +创建一个名为 `test.seq` 的序列,并查询这个序列的下一个值: ```sql CREATE SEQUENCE test.seq; SELECT nextval(test.seq); -SELECT * FROM sequences\G ``` +输出结果如下: + ```sql +-------------------+ | nextval(test.seq) | @@ -48,6 +49,17 @@ SELECT * FROM sequences\G | 1 | +-------------------+ 1 row in set (0.01 sec) +``` + +查询数据库中的所有序列: + +```sql +SELECT * FROM SEQUENCES\G +``` + +输出结果如下: + +```sql *************************** 1. row *************************** TABLE_CATALOG: def SEQUENCE_SCHEMA: test @@ -59,6 +71,6 @@ SEQUENCE_SCHEMA: test MAX_VALUE: 9223372036854775806 MIN_VALUE: 1 START: 1 - COMMENT: + COMMENT: 1 row in set (0.00 sec) ``` diff --git a/information-schema/information-schema-session-variables.md b/information-schema/information-schema-session-variables.md index 364aa790cadc..3cf4e621a048 100644 --- a/information-schema/information-schema-session-variables.md +++ b/information-schema/information-schema-session-variables.md @@ -1,19 +1,19 @@ --- title: SESSION_VARIABLES -summary: 了解 information_schema 表 `SESSION_VARIABLES`。 +summary: 了解 INFORMATION_SCHEMA 表 `SESSION_VARIABLES`。 --- # SESSION_VARIABLES `SESSION_VARIABLES` 表提供了关于 session 变量的信息。表中的数据跟 `SHOW SESSION VARIABLES` 语句执行结果类似。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC session_variables; +USE INFORMATION_SCHEMA; +DESC SESSION_VARIABLES; ``` +输出结果如下: + ```sql +----------------+---------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -24,25 +24,27 @@ DESC session_variables; 2 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +查看 `SESSION_VARIABLES` 表的前 10 条信息: ```sql -SELECT * FROM session_variables ORDER BY variable_name LIMIT 10; +SELECT * FROM SESSION_VARIABLES ORDER BY variable_name LIMIT 10; ``` +输出结果如下: + ```sql +-----------------------------------+------------------+ | VARIABLE_NAME | VARIABLE_VALUE | +-----------------------------------+------------------+ -| allow_auto_random_explicit_insert | off | +| allow_auto_random_explicit_insert | OFF | | auto_increment_increment | 1 | | auto_increment_offset | 1 | -| autocommit | 1 | +| autocommit | ON | | automatic_sp_privileges | 1 | -| avoid_temporal_upgrade | 0 | +| avoid_temporal_upgrade | OFF | | back_log | 80 | | basedir | /usr/local/mysql | -| big_tables | 0 | +| big_tables | OFF | | bind_address | * | +-----------------------------------+------------------+ 10 rows in set (0.00 sec) diff --git a/information-schema/information-schema-slow-query.md b/information-schema/information-schema-slow-query.md index 5f01d9178d1d..67b9fc500df8 100644 --- a/information-schema/information-schema-slow-query.md +++ b/information-schema/information-schema-slow-query.md @@ -1,19 +1,19 @@ --- title: SLOW_QUERY -summary: 了解 information_schema 表 `SLOW_QUERY`。 +summary: 了解 INFORMATION_SCHEMA 表 `SLOW_QUERY`。 --- # SLOW_QUERY `SLOW_QUERY` 表中提供了当前节点的慢查询相关的信息,其内容通过解析当前节点的 TiDB 慢查询日志而来,列名和慢日志中的字段名是一一对应。关于如何使用该表调查和改善慢查询,请参考[慢查询日志文档](/identify-slow-queries.md)。 -{{< copyable "sql" >}} - ```sql -USE information_schema; +USE INFORMATION_SCHEMA; DESC slow_query; ``` +输出结果示例如下: + ```sql +-------------------------------+---------------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -100,12 +100,12 @@ DESC slow_query; `CLUSTER_SLOW_QUERY` 表中提供了集群所有节点的慢查询相关的信息,其内容通过解析 TiDB 慢查询日志而来,该表使用上和 `SLOW_QUERY` 表一样。`CLUSTER_SLOW_QUERY` 表结构上比 `SLOW_QUERY` 多一列 `INSTANCE`,表示该行慢查询信息来自的 TiDB 节点地址。关于如何使用该表调查和改善慢查询,请参考[慢查询日志文档](/identify-slow-queries.md)。 -{{< copyable "sql" >}} - ```sql -desc cluster_slow_query; +DESC CLUSTER_SLOW_QUERY; ``` +输出结果示例如下: + ```sql +-------------------------------+---------------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -191,30 +191,28 @@ desc cluster_slow_query; 查询集群系统表时,TiDB 也会将相关计算下推给其他节点执行,而不是把所有节点的数据都取回来,可以查看执行计划,如下: -{{< copyable "sql" >}} - ```sql -desc SELECT count(*) FROM cluster_slow_query WHERE user = 'u1'; +DESC SELECT COUNT(*) FROM CLUSTER_SLOW_QUERY WHERE user = 'u1'; ``` +输出结果示例如下: + ```sql -+--------------------------+----------+-----------+--------------------------+------------------------------------------------------+ -| id | estRows | task | access object | operator info | -+--------------------------+----------+-----------+--------------------------+------------------------------------------------------+ -| StreamAgg_20 | 1.00 | root | | funcs:count(Column#53)->Column#51 | -| └─TableReader_21 | 1.00 | root | | data:StreamAgg_9 | -| └─StreamAgg_9 | 1.00 | cop[tidb] | | funcs:count(1)->Column#53 | -| └─Selection_19 | 10.00 | cop[tidb] | | eq(information_schema.cluster_slow_query.user, "u1") | -| └─TableFullScan_18 | 10000.00 | cop[tidb] | table:CLUSTER_SLOW_QUERY | keep order:false, stats:pseudo | -+--------------------------+----------+-----------+--------------------------+------------------------------------------------------+ ++----------------------------+----------+-----------+--------------------------+------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------+----------+-----------+--------------------------+------------------------------------------------------+ +| StreamAgg_7 | 1.00 | root | | funcs:count(1)->Column#75 | +| └─TableReader_13 | 10.00 | root | | data:Selection_12 | +| └─Selection_12 | 10.00 | cop[tidb] | | eq(INFORMATION_SCHEMA.cluster_slow_query.user, "u1") | +| └─TableFullScan_11 | 10000.00 | cop[tidb] | table:CLUSTER_SLOW_QUERY | keep order:false, stats:pseudo | ++----------------------------+----------+-----------+--------------------------+------------------------------------------------------+ +4 rows in set (0.00 sec) ``` -上面执行计划表示,会将 `user = u1` 条件下推给其他的 (`cop`) TiDB 节点执行,也会把聚合算子(即图中的 `StreamAgg` 算子)下推。 +上面执行计划表示,会将 `user = u1` 条件下推给其他的 (`cop`) TiDB 节点执行,也会把聚合算子(即上面输出结果中的 `StreamAgg` 算子)下推。 目前由于没有对系统表收集统计信息,所以有时会导致某些聚合算子不能下推,导致执行较慢,用户可以通过手动指定聚合下推的 SQL HINT 来将聚合算子下推,示例如下: -{{< copyable "sql" >}} - ```sql -SELECT /*+ AGG_TO_COP() */ count(*) FROM cluster_slow_query GROUP BY user; +SELECT /*+ AGG_TO_COP() */ COUNT(*) FROM CLUSTER_SLOW_QUERY GROUP BY user; ``` diff --git a/information-schema/information-schema-table-storage-stats.md b/information-schema/information-schema-table-storage-stats.md index 4f65ff94356d..0fb9e5910bae 100644 --- a/information-schema/information-schema-table-storage-stats.md +++ b/information-schema/information-schema-table-storage-stats.md @@ -1,19 +1,19 @@ --- title: TABLE_STORAGE_STATS -summary: 了解 information_schema 表 `TABLE_STORAGE_STATS`。 +summary: 了解 INFORMATION_SCHEMA 表 `TABLE_STORAGE_STATS`。 --- # TABLE_STORAGE_STATS `TABLE_STORAGE_STATS` 表提供有关由存储引擎 (TiKV) 存储的表大小的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC table_storage_stats; +USE INFORMATION_SCHEMA; +DESC TABLE_STORAGE_STATS; ``` +输出结果如下: + ```sql +--------------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -30,14 +30,14 @@ DESC table_storage_stats; 8 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} - ```sql CREATE TABLE test.t1 (id INT); INSERT INTO test.t1 VALUES (1); -SELECT * FROM table_storage_stats WHERE table_schema = 'test' AND table_name = 't1'\G +SELECT * FROM TABLE_STORAGE_STATS WHERE table_schema = 'test' AND table_name = 't1'\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** TABLE_SCHEMA: test @@ -50,3 +50,14 @@ EMPTY_REGION_COUNT: 1 TABLE_KEYS: 0 1 row in set (0.00 sec) ``` + +`TABLE_STORAGE_STATS` 表各列字段含义如下: + +* `TABLE_SCHEMA`:表所在 schema 名字 +* `TABLE_NAME`:表名 +* `TABLE_ID`:表 ID +* `PEER_COUNT`:副本个数 +* `REGION_COUNT`:表所在的 Region 个数 +* `EMPTY_REGION_COUNT`:没有该表数据的 Region 个数 +* `TABLE_SIZE`:数据量大小,单位 MiB +* `TABLE_KEYS`:表记录个数 diff --git a/information-schema/information-schema-tidb-servers-info.md b/information-schema/information-schema-tidb-servers-info.md index 27240a6a67c7..5e20c88f7e62 100644 --- a/information-schema/information-schema-tidb-servers-info.md +++ b/information-schema/information-schema-tidb-servers-info.md @@ -1,41 +1,44 @@ --- title: TIDB_SERVERS_INFO -summary: 了解 information_schema 表 `TIDB_SERVERS_INFO`。 +summary: 了解 INFORMATION_SCHEMA 表 `TIDB_SERVERS_INFO`。 --- # TIDB_SERVERS_INFO `TIDB_SERVERS_INFO` 表提供了 TiDB 集群中 TiDB 服务器的信息(即 tidb-server 进程)。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC tidb_servers_info; +USE INFORMATION_SCHEMA; +DESC TIDB_SERVERS_INFO; ``` +输出结果如下: + ```sql -+---------------+-------------+------+------+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+---------------+-------------+------+------+---------+-------+ -| DDL_ID | varchar(64) | YES | | NULL | | -| IP | varchar(64) | YES | | NULL | | -| PORT | bigint(21) | YES | | NULL | | -| STATUS_PORT | bigint(21) | YES | | NULL | | -| LEASE | varchar(64) | YES | | NULL | | -| VERSION | varchar(64) | YES | | NULL | | -| GIT_HASH | varchar(64) | YES | | NULL | | -| BINLOG_STATUS | varchar(64) | YES | | NULL | | -+---------------+-------------+------+------+---------+-------+ -8 rows in set (0.00 sec) ++---------------+--------------+------+------+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++---------------+--------------+------+------+---------+-------+ +| DDL_ID | varchar(64) | YES | | NULL | | +| IP | varchar(64) | YES | | NULL | | +| PORT | bigint(21) | YES | | NULL | | +| STATUS_PORT | bigint(21) | YES | | NULL | | +| LEASE | varchar(64) | YES | | NULL | | +| VERSION | varchar(64) | YES | | NULL | | +| GIT_HASH | varchar(64) | YES | | NULL | | +| BINLOG_STATUS | varchar(64) | YES | | NULL | | +| LABELS | varchar(128) | YES | | NULL | | ++---------------+--------------+------+------+---------+-------+ +9 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +查看 `TIDB_SERVERS_INFO` 表的信息: ```sql -SELECT * FROM tidb_servers_info\G +SELECT * FROM TIDB_SERVERS_INFO\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** DDL_ID: 771c169d-0a3a-48ea-a93c-a4d6751d3674 @@ -43,8 +46,9 @@ SELECT * FROM tidb_servers_info\G PORT: 4000 STATUS_PORT: 10080 LEASE: 45s - VERSION: 5.7.25-TiDB-v4.0.0-beta.2-720-g0df3b74f5 - GIT_HASH: 0df3b74f55f8f8fbde39bbd5d471783f49dc10f7 + VERSION: 5.7.25-TiDB-v6.5.0 + GIT_HASH: 827d8ff2d22ac4c93ae1b841b79d468211e1d393 BINLOG_STATUS: Off -1 row in set (0.00 sec) + LABELS: +1 row in set (0.006 sec) ``` diff --git a/information-schema/information-schema-tidb-trx.md b/information-schema/information-schema-tidb-trx.md index c16985c6d910..6d2ac381ef38 100644 --- a/information-schema/information-schema-tidb-trx.md +++ b/information-schema/information-schema-tidb-trx.md @@ -1,19 +1,19 @@ --- title: TIDB_TRX -summary: 了解 information_schema 表 `TIDB_TRX`。 +summary: 了解 INFORMATION_SCHEMA 表 `TIDB_TRX`。 --- # TIDB_TRX `TIDB_TRX` 表提供了当前 TiDB 节点上正在执行的事务的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC tidb_trx; +USE INFORMATION_SCHEMA; +DESC TIDB_TRX; ``` +输出结果如下: + ```sql +-------------------------+-----------------------------------------------------------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -30,6 +30,7 @@ DESC tidb_trx; | USER | varchar(16) | YES | | NULL | | | DB | varchar(64) | YES | | NULL | | | ALL_SQL_DIGESTS | text | YES | | NULL | | +| RELATED_TABLE_IDS | text | YES | | NULL | | +-------------------------+-----------------------------------------------------------------+------+------+---------+-------+ ``` @@ -39,7 +40,7 @@ DESC tidb_trx; * `START_TIME`:事务的开始时间,即事务的 `start_ts` 所对应的物理时间。 * `CURRENT_SQL_DIGEST`:该事务当前正在执行的 SQL 语句的 Digest。 * `CURRENT_SQL_DIGEST_TEXT`:该事务当前正在执行的 SQL 语句的归一化形式,即去除了参数和格式的 SQL 语句。与 `CURRENT_SQL_DIGEST` 对应。 -* `STATE`:该事务当前所处的状态。其可能的值包括: +* `STATE`:该事务当前所处的状态。其可能的值包括: * `Idle`:事务处于闲置状态,即正在等待用户输入查询。 * `Running`:事务正在正常执行一个查询。 * `LockWaiting`:事务处于正在等待悲观锁上锁完成的状态。需要注意的是,事务刚开始进行悲观锁上锁操作时即进入该状态,无论是否有被其它事务阻塞。 @@ -52,22 +53,25 @@ DESC tidb_trx; * `USER`:执行该事务的用户名。 * `DB`:执行该事务的 session 当前的默认数据库名。 * `ALL_SQL_DIGESTS`:该事务已经执行过的语句的 Digest 的列表,表示为一个 JSON 格式的字符串数组。每个事务最多记录前 50 条语句。通过 [`TIDB_DECODE_SQL_DIGESTS`](/functions-and-operators/tidb-functions.md#tidb_decode_sql_digests) 函数可以将该列的信息变换为对应的归一化 SQL 语句的列表。 +* `RELATED_TABLE_IDS`:该事务访问的表、视图等对象的 ID。 > **注意:** > > * 仅拥有 [PROCESS](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_process) 权限的用户可以获取该表中的完整信息。没有 PROCESS 权限的用户则只能查询到当前用户所执行的事务的信息。 -> * `CURRENT_SQL_DIGEST` 和 `ALL_SQL_DIGESTS` 列中的信息(SQL Digest)为 SQL 语句进行归一化后计算得到的哈希值。`CURRENT_SQL_DIGEST_TEXT` 列中的信息和函数 `TIDB_DECODE_SQL_DIGESTS` 所得到的结果均为内部从 Statements Summary 系列表中查询得到,因而存在内部查询不到对应语句的可能性。关于 SQL Digest 和 Statements Summary 相关表的详细说明,请参阅[Statement Summary Tables](/statement-summary-tables.md)。 -> * [`TIDB_DECODE_SQL_DIGESTS`](/functions-and-operators/tidb-functions.md#tidb_decode_sql_digests) 函数调用开销较大,如果对大量事务的信息调用该函数查询历史 SQL,可能查询耗时较长。如果集群规模较大、同一时刻并发运行的事务较多,请避免直接在查询 `TIDB_TRX` 全表的同时直接将该函数用于 `ALL_SQL_DIGEST` 列(即尽量避免 ``select *, tidb_decode_sql_digests(all_sql_digests) from tidb_trx`` 这样的用法)。 +> * `CURRENT_SQL_DIGEST` 和 `ALL_SQL_DIGESTS` 列中的信息 (SQL Digest) 为 SQL 语句进行归一化后计算得到的哈希值。`CURRENT_SQL_DIGEST_TEXT` 列中的信息和函数 `TIDB_DECODE_SQL_DIGESTS` 所得到的结果均为内部从 Statements Summary 系列表中查询得到,因而存在内部查询不到对应语句的可能性。关于 SQL Digest 和 Statements Summary 相关表的详细说明,请参阅[Statement Summary Tables](/statement-summary-tables.md)。 +> * [`TIDB_DECODE_SQL_DIGESTS`](/functions-and-operators/tidb-functions.md#tidb_decode_sql_digests) 函数调用开销较大,如果对大量事务的信息调用该函数查询历史 SQL,可能查询耗时较长。如果集群规模较大、同一时刻并发运行的事务较多,请避免直接在查询 `TIDB_TRX` 全表的同时直接将该函数用于 `ALL_SQL_DIGEST` 列(即尽量避免 ``SELECT *, tidb_decode_sql_digests(all_sql_digests) FROM TIDB_TRX`` 这样的用法)。 > * 目前 `TIDB_TRX` 表暂不支持显示 TiDB 内部事务相关的信息。 ## 示例 -{{< copyable "sql" >}} +查看 `TIDB_TRX` 表中的信息: ```sql -select * from information_schema.tidb_trx\G +SELECT * FROM INFORMATION_SCHEMA.TIDB_TRX\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** ID: 426789913200689153 @@ -100,12 +104,12 @@ CURRENT_SQL_DIGEST_TEXT: update `t` set `v` = `v` + ? where `id` = ? 此示例的查询结果表示:当前节点有两个运行中的事务,第一个事务正在闲置状态(`STATE` 为 `Idle`,`CURRENT_SQL_DIGEST` 为 `NULL`),该事务已经执行过 3 条语句(`ALL_SQL_DIGESTS` 列表中有三条记录,分别为执行过的 3 条语句的 Digest);第二个事务正在执行一条语句并正在等锁(`STATE` 为 `LockWaiting`,`WAITING_START_TIME` 显示了等锁开始的时间),该事务已经执行过两条语句,当前正在执行的语句形如 ``"update `t` set `v` = `v` + ? where `id` = ?"``。 -{{< copyable "sql" >}} - ```sql -select id, all_sql_digests, tidb_decode_sql_digests(all_sql_digests) as all_sqls from information_schema.tidb_trx\G +SELECT id, all_sql_digests, tidb_decode_sql_digests(all_sql_digests) AS all_sqls FROM INFORMATION_SCHEMA.TIDB_TRX\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** id: 426789913200689153 @@ -123,15 +127,14 @@ all_sql_digests: ["e6f07d43b5c21db0fbb9a31feac2dc599787763393dd5acbfad80e247eb02 `TIDB_TRX` 表仅提供单个 TiDB 节点中正在执行的事务信息。如果要查看整个集群上所有 TiDB 节点中正在执行的事务信息,需要查询 `CLUSTER_TIDB_TRX` 表。与 `TIDB_TRX` 表的查询结果相比,`CLUSTER_TIDB_TRX` 表的查询结果额外包含了 `INSTANCE` 字段。`INSTANCE` 字段展示了集群中各节点的 IP 地址和端口,用于区分事务所在的 TiDB 节点。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC cluster_tidb_trx; +USE INFORMATION_SCHEMA; +DESC CLUSTER_TIDB_TRX; ``` +输出结果如下: + ```sql -mysql> desc cluster_tidb_trx; +-------------------------+-----------------------------------------------------------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------------+-----------------------------------------------------------------+------+------+---------+-------+ @@ -148,5 +151,7 @@ mysql> desc cluster_tidb_trx; | USER | varchar(16) | YES | | NULL | | | DB | varchar(64) | YES | | NULL | | | ALL_SQL_DIGESTS | text | YES | | NULL | | +| RELATED_TABLE_IDS | text | YES | | NULL | | +-------------------------+-----------------------------------------------------------------+------+------+---------+-------+ +14 rows in set (0.00 sec) ``` diff --git a/information-schema/information-schema-tiflash-replica.md b/information-schema/information-schema-tiflash-replica.md index 52fa12ad9523..ab8cdc4c14a9 100644 --- a/information-schema/information-schema-tiflash-replica.md +++ b/information-schema/information-schema-tiflash-replica.md @@ -1,19 +1,19 @@ --- title: TIFLASH_REPLICA -summary: 了解 information_schema 表 `TIFLASH_REPLICA`。 +summary: 了解 INFORMATION_SCHEMA 表 `TIFLASH_REPLICA`。 --- # TIFLASH_REPLICA `TIFLASH_REPLICA` 表提供了有关可用的 TiFlash 副本的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC tiflash_replica; +USE INFORMATION_SCHEMA; +DESC TIFLASH_REPLICA; ``` +输出结果如下: + ```sql +-----------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -36,5 +36,5 @@ DESC tiflash_replica; - `TABLE_ID`:表的内部 ID,该 ID 在一个 TiDB 集群内部唯一。 - `REPLICA_COUNT`:TiFlash 副本数。 - `LOCATION_LABELS`:设置 TiFlash 副本时设置的 LocationLabelList。 -- `AVAILABLE`:表的 TiFlash 副本是否可用。1 代表可用,TiDB 优化器将依据查询代价智能选择下推查询到 TiKV 或 TiFlash;0 代表不可用,TiDB 将不会下推查询到 TiFlash。副本状态变为可用之后就不再改变。 +- `AVAILABLE`:表的 TiFlash 副本是否可用。`1` 代表可用,TiDB 优化器将依据查询代价智能选择下推查询到 TiKV 或 TiFlash;`0` 代表不可用,TiDB 将不会下推查询到 TiFlash。副本状态变为可用之后就不再改变。 - `PROGRESS`:TiFlash 副本同步进度,范围是 `[0, 1]`,精确到小数点后两位,刷新的精度为分钟级。当 `AVAILABLE` 字段为 1 时,如果 `PROGRESS` 小于 1,表示 TiFlash 副本落后 TiKV 较多,下推到 TiFlash 的查询很可能会因为等待数据同步超时而失败。 diff --git a/information-schema/information-schema-tikv-region-peers.md b/information-schema/information-schema-tikv-region-peers.md index 487086413d75..25e0cd41adfc 100644 --- a/information-schema/information-schema-tikv-region-peers.md +++ b/information-schema/information-schema-tikv-region-peers.md @@ -1,19 +1,19 @@ --- title: TIKV_REGION_PEERS -summary: 了解 information_schema 表 `TIKV_REGION_PEERS`。 +summary: 了解 INFORMATION_SCHEMA 表 `TIKV_REGION_PEERS`。 --- # TIKV_REGION_PEERS `TIKV_REGION_PEERS` 表提供了 TiKV 中单个 Region 节点的详细信息,比如它是一个 learner 还是一个 leader。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC tikv_region_peers; +USE INFORMATION_SCHEMA; +DESC TIKV_REGION_PEERS; ``` +输出结果如下: + ```sql +--------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -33,28 +33,28 @@ DESC tikv_region_peers; ```sql SELECT - address, - tikv.address, - region.region_id + address, + tikv.address, + region.region_id FROM - tikv_store_status tikv, - tikv_region_peers peer, - (SELECT * FROM tikv_region_status ORDER BY written_bytes DESC LIMIT 3) region + TIKV_STORE_STATUS tikv, + TIKV_REGION_PEERS peer, + (SELECT * FROM tikv_region_status ORDER BY written_bytes DESC LIMIT 3) region WHERE region.region_id = peer.region_id - AND peer.is_leader = 1 - AND peer.store_id = tikv.store_id; + AND peer.is_leader = 1 + AND peer.store_id = tikv.store_id; ``` `TIKV_REGION_PEERS` 表各列含义如下: -* REGION_ID:REGION 的 ID。 -* PEER_ID:REGION 中对应的副本 PEER 的 ID。 -* STORE_ID:REGION 所在 TiKV Store 的 ID。 -* IS_LEARNER:PEER 是否是 LEARNER。 -* IS_LEADER:PEER 是否是 LEADER。 -* STATUS:PEER 的状态,一共有 3 种状态: - * PENDING:暂时不可用状态。 - * DOWN:下线转态,该 PEER 不再提供服务。 - * NORMAL: 正常状态。 -* DOWN_SECONDS:处于下线状态的时间,单位是秒。 +* `REGION_ID`:REGION 的 ID。 +* `PEER_ID`:REGION 中对应的副本 Peer 的 ID。 +* `STORE_ID`:REGION 所在 TiKV Store 的 ID。 +* `IS_LEARNER`:Peer 是否是 LEARNER。 +* `IS_LEADER`:Peer 是否是 LEADER。 +* `STATUS`:Peer 的状态,一共有 3 种状态: + * `PENDING`:暂时不可用状态。 + * `DOWN`:下线转态,该 Peer 不再提供服务。 + * `NORMAL`:正常状态。 +* `DOWN_SECONDS`:处于下线状态的时间,单位是秒。 diff --git a/information-schema/information-schema-tikv-store-status.md b/information-schema/information-schema-tikv-store-status.md index 4cccba6a26a6..4477c64d69ad 100644 --- a/information-schema/information-schema-tikv-store-status.md +++ b/information-schema/information-schema-tikv-store-status.md @@ -1,19 +1,19 @@ --- title: TIKV_STORE_STATUS -summary: 了解 information_schema 表 `TIKV_STORE_STATUS`。 +summary: 了解 INFORMATION_SCHEMA 表 `TIKV_STORE_STATUS`。 --- # TIKV_STORE_STATUS -`TIKV_STORE_STATUS` 表通过 PD 的 API 显示了 TiKV 节点的一些基本信息,例如在集群中分配的 ID,地址和端口,状态,容量以及当前节点的 Region leader 的数量。 - -{{< copyable "sql" >}} +`TIKV_STORE_STATUS` 表通过 PD 的 API 显示了 TiKV 节点的一些基本信息,例如在集群中分配的 ID、地址和端口、状态、容量以及当前节点的 Region leader 的数量。 ```sql -USE information_schema; -DESC tikv_store_status; +USE INFORMATION_SCHEMA; +DESC TIKV_STORE_STATUS; ``` +输出结果如下: + ```sql +-------------------+-------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -46,7 +46,7 @@ DESC tikv_store_status; * `STORE_ID`:Store 的 ID。 * `ADDRESS`:Store 的地址。 * `STORE_STATE`:Store 状态的标识符,与 `STORE_STATE_NAME` 相对应。 -* `STORE_STATE_NAME`:Store 状态的名字,为 `Up` / `Offline` / `Tombstone` 中的一种。 +* `STORE_STATE_NAME`:Store 状态的名字,为 `Up`、`Offline`、`Tombstone` 中的一种。 * `LABEL`:给 Store 设置的标签。 * `VERSION`:Store 的版本号。 * `CAPACITY`:Store 的存储容量。 diff --git a/information-schema/information-schema-user-privileges.md b/information-schema/information-schema-user-privileges.md index b419b478e510..9827c18293b0 100644 --- a/information-schema/information-schema-user-privileges.md +++ b/information-schema/information-schema-user-privileges.md @@ -1,19 +1,19 @@ --- title: USER_PRIVILEGES -summary: 了解 information_schema 表 `USER_PRIVILEGES`。 +summary: 了解 INFORMATION_SCHEMA 表 `USER_PRIVILEGES`。 --- # USER_PRIVILEGES `USER_PRIVILEGES` 表提供了关于全局权限的信息。该表的数据根据 `mysql.user` 系统表生成。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC user_privileges; +USE INFORMATION_SCHEMA; +DESC USER_PRIVILEGES; ``` +输出结果如下: + ```sql +----------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -26,35 +26,38 @@ DESC user_privileges; 4 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +查看 `USER_PRIVILEGES` 表的信息: ```sql -SELECT * FROM user_privileges; +SELECT * FROM USER_PRIVILEGES; ``` +输出结果如下: + ```sql +------------+---------------+-------------------------+--------------+ | GRANTEE | TABLE_CATALOG | PRIVILEGE_TYPE | IS_GRANTABLE | +------------+---------------+-------------------------+--------------+ -| 'root'@'%' | def | Select | YES | -| 'root'@'%' | def | Insert | YES | -| 'root'@'%' | def | Update | YES | -| 'root'@'%' | def | Delete | YES | -| 'root'@'%' | def | Create | YES | -| 'root'@'%' | def | Drop | YES | -| 'root'@'%' | def | Process | YES | -| 'root'@'%' | def | References | YES | -| 'root'@'%' | def | Alter | YES | -| 'root'@'%' | def | Show Databases | YES | -| 'root'@'%' | def | Super | YES | -| 'root'@'%' | def | Execute | YES | -| 'root'@'%' | def | Index | YES | -| 'root'@'%' | def | Create User | YES | -| 'root'@'%' | def | Trigger | YES | -| 'root'@'%' | def | Create View | YES | -| 'root'@'%' | def | Show View | YES | -| 'root'@'%' | def | Create Role | YES | -| 'root'@'%' | def | Drop Role | YES | +| 'root'@'%' | def | SELECT | YES | +| 'root'@'%' | def | INSERT | YES | +| 'root'@'%' | def | UPDATE | YES | +| 'root'@'%' | def | DELETE | YES | +| 'root'@'%' | def | CREATE | YES | +| 'root'@'%' | def | DROP | YES | +| 'root'@'%' | def | PROCESS | YES | +| 'root'@'%' | def | REFERENCES | YES | +| 'root'@'%' | def | ALTER | YES | +| 'root'@'%' | def | SHOW DATABASES | YES | +| 'root'@'%' | def | SUPER | YES | +| 'root'@'%' | def | EXECUTE | YES | +| 'root'@'%' | def | INDEX | YES | +| 'root'@'%' | def | CREATE USER | YES | +| 'root'@'%' | def | CREATE TABLESPACE | YES | +| 'root'@'%' | def | TRIGGER | YES | +| 'root'@'%' | def | CREATE VIEW | YES | +| 'root'@'%' | def | SHOW VIEW | YES | +| 'root'@'%' | def | CREATE ROLE | YES | +| 'root'@'%' | def | DROP ROLE | YES | | 'root'@'%' | def | CREATE TEMPORARY TABLES | YES | | 'root'@'%' | def | LOCK TABLES | YES | | 'root'@'%' | def | CREATE ROUTINE | YES | @@ -64,8 +67,10 @@ SELECT * FROM user_privileges; | 'root'@'%' | def | RELOAD | YES | | 'root'@'%' | def | FILE | YES | | 'root'@'%' | def | CONFIG | YES | +| 'root'@'%' | def | REPLICATION CLIENT | YES | +| 'root'@'%' | def | REPLICATION SLAVE | YES | +------------+---------------+-------------------------+--------------+ -28 rows in set (0.00 sec) +31 rows in set (0.00 sec) ``` `USER_PRIVILEGES` 表中列的含义如下: diff --git a/information-schema/information-schema-views.md b/information-schema/information-schema-views.md index d26a08b1155a..06e9737db3d6 100644 --- a/information-schema/information-schema-views.md +++ b/information-schema/information-schema-views.md @@ -1,19 +1,19 @@ --- title: VIEWS -summary: 了解 information_schema 表 `VIEWS`。 +summary: 了解 INFORMATION_SCHEMA 表 `VIEWS`。 --- # VIEWS `VIEWS` 表提供了关于 SQL 视图的信息。 -{{< copyable "sql" >}} - ```sql -USE information_schema; -DESC views; +USE INFORMATION_SCHEMA; +DESC VIEWS; ``` +输出结果如下: + ```sql +----------------------+--------------+------+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -21,7 +21,7 @@ DESC views; | TABLE_CATALOG | varchar(512) | NO | | NULL | | | TABLE_SCHEMA | varchar(64) | NO | | NULL | | | TABLE_NAME | varchar(64) | NO | | NULL | | -| VIEW_DEFINITION | longblob | NO | | NULL | | +| VIEW_DEFINITION | longtext | NO | | NULL | | | CHECK_OPTION | varchar(8) | NO | | NULL | | | IS_UPDATABLE | varchar(3) | NO | | NULL | | | DEFINER | varchar(77) | NO | | NULL | | @@ -32,13 +32,15 @@ DESC views; 10 rows in set (0.00 sec) ``` -{{< copyable "sql" >}} +创建视图并查询 `VIEWS` 表信息: ```sql CREATE VIEW test.v1 AS SELECT 1; -SELECT * FROM views\G +SELECT * FROM VIEWS\G ``` +输出结果如下: + ```sql *************************** 1. row *************************** TABLE_CATALOG: def @@ -60,7 +62,7 @@ COLLATION_CONNECTION: utf8mb4_0900_ai_ci * `TABLE_SCHEMA`:视图所属的数据库的名称。 * `TABLE_NAME`:视图名称。 * `VIEW_DEFINITION`:视图的定义,由创建视图时 `SELECT` 部分的语句组成。 -* `CHECK_OPTION`:`CHECK_OPTION` 的值。取值为 `NONE`、 `CASCADE` 或 `LOCAL`。 +* `CHECK_OPTION`:`CHECK_OPTION` 的值。取值为 `NONE`、`CASCADE` 或 `LOCAL`。 * `IS_UPDATABLE`:`UPDATE`/`INSERT`/`DELETE` 是否对该视图可用。在 TiDB,始终为 `NO`。 * `DEFINER`:视图的创建者用户名称,格式为 `'user_name'@'host_name'`。 * `SECURITY_TYPE`:`SQL SECURITY` 的值,取值为 `DEFINER` 或 `INVOKER`。 diff --git a/media/dashboard/dashboard-statement-other-row.png b/media/dashboard/dashboard-statement-other-row.png new file mode 100644 index 000000000000..d52ee2d1d849 Binary files /dev/null and b/media/dashboard/dashboard-statement-other-row.png differ diff --git a/media/performance/cdc/cdc-fast-1.png b/media/performance/cdc/cdc-fast-1.png new file mode 100644 index 000000000000..9d4b02c48928 Binary files /dev/null and b/media/performance/cdc/cdc-fast-1.png differ diff --git a/media/performance/cdc/cdc-fast-2.png b/media/performance/cdc/cdc-fast-2.png new file mode 100644 index 000000000000..4a623a9bfdae Binary files /dev/null and b/media/performance/cdc/cdc-fast-2.png differ diff --git a/media/performance/cdc/cdc-slow.png b/media/performance/cdc/cdc-slow.png new file mode 100644 index 000000000000..2e92adb07360 Binary files /dev/null and b/media/performance/cdc/cdc-slow.png differ diff --git a/media/performance/tiflash/ch-1tiflash-raft-io-flow-cloud.png b/media/performance/tiflash/ch-1tiflash-raft-io-flow-cloud.png new file mode 100644 index 000000000000..bb660f0f93fd Binary files /dev/null and b/media/performance/tiflash/ch-1tiflash-raft-io-flow-cloud.png differ diff --git a/media/performance/tiflash/ch-2tiflash-op.png b/media/performance/tiflash/ch-2tiflash-op.png new file mode 100644 index 000000000000..8f0d07c16b7f Binary files /dev/null and b/media/performance/tiflash/ch-2tiflash-op.png differ diff --git a/media/performance/tiflash/ch-2tiflash-raft-io-flow.png b/media/performance/tiflash/ch-2tiflash-raft-io-flow.png new file mode 100644 index 000000000000..92d2f54f53cd Binary files /dev/null and b/media/performance/tiflash/ch-2tiflash-raft-io-flow.png differ diff --git a/media/performance/tiflash/tiflash-resource-usage.png b/media/performance/tiflash/tiflash-resource-usage.png new file mode 100644 index 000000000000..19d505f7d817 Binary files /dev/null and b/media/performance/tiflash/tiflash-resource-usage.png differ diff --git a/media/performance/tiflash/tiflash_request_duration_by_type.png b/media/performance/tiflash/tiflash_request_duration_by_type.png new file mode 100644 index 000000000000..be666b5dc9e7 Binary files /dev/null and b/media/performance/tiflash/tiflash_request_duration_by_type.png differ diff --git a/media/tidb-non-prepared-plan-cache-metrics.png b/media/tidb-non-prepared-plan-cache-metrics.png new file mode 100644 index 000000000000..42c62bfdc6e8 Binary files /dev/null and b/media/tidb-non-prepared-plan-cache-metrics.png differ diff --git a/media/tiflash/tiflash-s3.png b/media/tiflash/tiflash-s3.png new file mode 100644 index 000000000000..2c17acf34975 Binary files /dev/null and b/media/tiflash/tiflash-s3.png differ diff --git a/mysql-compatibility.md b/mysql-compatibility.md index 7513dba24c08..dc257606101b 100644 --- a/mysql-compatibility.md +++ b/mysql-compatibility.md @@ -57,6 +57,8 @@ TiDB 高度兼容 MySQL 5.7 协议、MySQL 5.7 常用的功能及语法。MySQL - TiDB 不支持添加列的 `AUTO_INCREMENT` 属性,移除该属性后不可恢复。 +- 对于 v6.6.0 及更早的 TiDB 版本,TiDB 的行为与 MySQL InnoDB 保持一致,要求自增列必须为主键或者索引前缀。从 v7.0.0 开始,TiDB 移除自增列必须是索引或索引前缀的限制,允许用户更灵活地定义表的主键。关于此更改的详细信息,请参阅 [#40580](https://github.com/pingcap/tidb/issues/40580) + 自增 ID 详情可参阅 [AUTO_INCREMENT](/auto-increment.md)。 > **注意:** @@ -67,21 +69,28 @@ TiDB 高度兼容 MySQL 5.7 协议、MySQL 5.7 常用的功能及语法。MySQL mysql> CREATE TABLE t(id INT UNIQUE KEY AUTO_INCREMENT); Query OK, 0 rows affected (0.05 sec) -mysql> INSERT INTO t VALUES(),(),(); -Query OK, 3 rows affected (0.00 sec) -Records: 3 Duplicates: 0 Warnings: 0 +mysql> INSERT INTO t VALUES(); +Query OK, 1 rows affected (0.00 sec) + +mysql> INSERT INTO t VALUES(); +Query OK, 1 rows affected (0.00 sec) + +mysql> INSERT INTO t VALUES(); +Query OK, 1 rows affected (0.00 sec) mysql> SELECT _tidb_rowid, id FROM t; +-------------+------+ | _tidb_rowid | id | +-------------+------+ -| 4 | 1 | -| 5 | 2 | -| 6 | 3 | +| 2 | 1 | +| 4 | 3 | +| 6 | 5 | +-------------+------+ 3 rows in set (0.01 sec) ``` +可以看到,由于共用分配器,id 每次自增步长是 2。在 [MySQL 兼容模式](/auto-increment.md#mysql-兼容模式)中改掉了该行为,没有共用分配器,因此不会跳号。 + > **注意:** > > 使用 `AUTO_INCREMENT` 可能会给生产环境带热点问题,因此推荐使用 [`AUTO_RANDOM`](/auto-random.md) 代替。详情请参考 [TiDB 热点问题处理](/troubleshoot-hot-spot-issues.md#tidb-热点问题处理)。 @@ -112,12 +121,10 @@ TiDB 中,所有支持的 DDL 变更操作都是在线执行的。与 MySQL 相 * TiDB 中,`ALGORITHM={INSTANT,INPLACE,COPY}` 语法只作为一种指定,并不更改 `ALTER` 算法,详情参阅 [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md)。 * 不支持添加或删除 `CLUSTERED` 类型的主键。要了解关于 `CLUSTERED` 主键的详细信息,请参考[聚簇索引](/clustered-indexes.md)。 * 不支持指定不同类型的索引 (`HASH|BTREE|RTREE|FULLTEXT`)。若指定了不同类型的索引,TiDB 会解析并忽略这些索引。 -* 分区表支持 `HASH`、`RANGE` 和 `LIST` 分区类型。对于不支持的分区类型,TiDB 可能会报 `Warning: Unsupported partition type %s, treat as normal table` 错误,其中 `%s` 为不支持的具体分区类型。 -* 分区表还支持 `ADD`、`DROP`、`TRUNCATE` 操作。其他分区操作会被忽略。TiDB 不支持以下分区表语法: - + `PARTITION BY KEY` - + `PARTITION BY LINEAR KEY` +* 分区表支持 `HASH`、`RANGE`、`LIST` 和 `KEY` 分区类型。`KEY` 分区类型暂不支持分区字段列表为空的语句。对于不支持的分区类型,TiDB 会报 `Warning: Unsupported partition type %s, treat as normal table` 错误,其中 `%s` 为不支持的具体分区类型。 +* 分区表还支持 `ADD`、`DROP`、`TRUNCATE`、`REORGANIZE` 操作,其他分区操作会被忽略。TiDB 不支持以下分区表语法: + `SUBPARTITION` - + `{CHECK|TRUNCATE|OPTIMIZE|REPAIR|IMPORT|DISCARD|REBUILD|REORGANIZE|COALESCE} PARTITION` + + `{CHECK|TRUNCATE|OPTIMIZE|REPAIR|IMPORT|DISCARD|REBUILD|COALESCE} PARTITION` 更多详情,请参考[分区表文档](/partitioned-table.md)。 diff --git a/mysql-schema.md b/mysql-schema.md index 8308405e00ba..c21f5d58047f 100644 --- a/mysql-schema.md +++ b/mysql-schema.md @@ -39,6 +39,7 @@ aliases: ['/docs-cn/dev/system-tables/system-table-overview/','/docs-cn/dev/refe * `column_stats_usage` 列统计信息的使用情况 * `schema_index_usage` 索引的使用情况 * `analyze_jobs` 正在执行的统计信息收集任务以及过去 7 天内的历史任务记录 +* `load_data_jobs` 正在执行或历史执行的 `LOAD DATA` 任务 ## 执行计划相关系统表 diff --git a/optimizer-hints.md b/optimizer-hints.md index 9e99e666c873..5ae0740bef1d 100644 --- a/optimizer-hints.md +++ b/optimizer-hints.md @@ -217,6 +217,32 @@ EXPLAIN SELECT * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t 在上述例子中可以看到,在使用了 Hint 之后,TiDB 可以选择由表 `t1` 作为驱动表的 IndexJoin 的执行方式。 +### SHUFFLE_JOIN(t1_name [, tl_name ...]) + +`SHUFFLE_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表使用 Shuffle Join 算法,该 Hint 只在 MPP 模式下生效。例如: + +```sql +SELECT /*+ SHUFFLE_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id; +``` + +> **注意:** +> +> - 使用该 Hint 前,需要保证当前 TiDB 集群能够支持在查询中使用 TiFlash MPP 模式,具体细节见文档[使用 TiFlash MPP 模式](/tiflash/use-tiflash-mpp-mode.md)。 +> - 该 Hint 能与 [`HASH_JOIN_BUILD` Hint](#hash_join_buildt1_name--tl_name-) 和 [`HASH_JOIN_PROBE` Hint](#hash_join_probet1_name--tl_name-) 组合使用,达到控制 Shuffle Join 算法的 Build 端和 Probe 端的作用。 + +### BROADCAST_JOIN(t1_name [, tl_name ...]) + +`BROADCAST_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表使用 Broadcast Join 算法,该 Hint 只在 MPP 模式下生效。例如: + +```sql +SELECT /*+ BROADCAST_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id; +``` + +> **注意:** +> +> - 使用该 Hint 前,需要保证当前 TiDB 集群能够支持在查询中使用 TiFlash MPP 模式,具体细节见文档[使用 TiFlash MPP 模式](/tiflash/use-tiflash-mpp-mode.md)。 +> - 该 Hint 能与 [`HASH_JOIN_BUILD` Hint](#hash_join_buildt1_name--tl_name-) 和 [`HASH_JOIN_PROBE` Hint](#hash_join_probet1_name--tl_name-) 组合使用,达到控制 Broadcast Join 算法的 Build 端和 Probe 端的作用。 + ### NO_DECORRELATE() `NO_DECORRELATE()` 提示优化器不要尝试解除指定查询块中对应子查询的关联。该 Hint 适用于包含关联列的 `EXISTS`、`IN`、`ANY`、`ALL`、`SOME` 和标量子查询,即关联子查询。 @@ -303,6 +329,30 @@ SELECT /*+ HASH_AGG() */ count(*) FROM t1, t2 WHERE t1.a > 10 GROUP BY t1.id; SELECT /*+ STREAM_AGG() */ count(*) FROM t1, t2 WHERE t1.a > 10 GROUP BY t1.id; ``` +### MPP_1PHASE_AGG() + +`MPP_1PHASE_AGG()` 提示优化器对指定查询块中所有聚合函数使用一阶段聚合算法,该 Hint 只在 MPP 模式下生效。例如: + +```sql +SELECT /*+ MPP_1PHASE_AGG() */ COUNT(*) FROM t1, t2 WHERE t1.a > 10 GROUP BY t1.id; +``` + +> **注意:** +> +> 使用该 Hint 前,需要保证当前 TiDB 集群能够支持在查询中使用 TiFlash MPP 模式,具体细节见文档[使用 TiFlash MPP 模式](/tiflash/use-tiflash-mpp-mode.md)。 + +### MPP_2PHASE_AGG() + +`MPP_2PHASE_AGG()` 提示优化器对指定查询块中所有聚合函数使用二阶段聚合算法,该 Hint 只在 MPP 模式下生效。例如: + +```sql +SELECT /*+ MPP_2PHASE_AGG() */ COUNT(*) FROM t1, t2 WHERE t1.a > 10 GROUP BY t1.id; +``` + +> **注意:** +> +> 使用该 Hint 前,需要保证当前 TiDB 集群能够支持在查询中使用 TiFlash MPP 模式,具体细节见文档[使用 TiFlash MPP 模式](/tiflash/use-tiflash-mpp-mode.md)。 + ### USE_INDEX(t1_name, idx1_name [, idx2_name ...]) `USE_INDEX(t1_name, idx1_name [, idx2_name ...])` 提示优化器对指定表仅使用给出的索引。 @@ -754,3 +804,13 @@ SELECT /*+ NTH_PLAN(3) */ count(*) from t where a > 5; > **注意:** > > `NTH_PLAN(N)` 主要用于测试用途,并且在未来不保证其兼容性,请谨慎使用。 + +### RESOURCE_GROUP(resource_group_name) + +`RESOURCE_GROUP(resource_group_name)` 用于[使用资源管控 (Resource Control) 实现资源隔离](/tidb-resource-control.md)。此 Hint 将临时使用指定的资源组执行当前的语句。如果指定的资源组不存在,则该 Hint 将被忽略。 + +示例: + +```sql +SELECT /*+ RESOURCE_GROUP(rg1) */ * FROM t limit 10; +``` diff --git a/partition-pruning.md b/partition-pruning.md index a757ae9a925c..6e869a25dc4a 100644 --- a/partition-pruning.md +++ b/partition-pruning.md @@ -230,10 +230,8 @@ explain select * from t where x between 7 and 14; 关于 `fn` 函数,对于任意 `x` `y`,如果 `x > y`,则 `fn(x) > fn(y)`,那么这种是严格递增的单调函数。非严格递增的单调函数也可以符合分区裁剪要求,只要函数 `fn` 满足:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) >= fn(y)`。理论上,所有满足单调条件(严格或者非严格)的函数都支持分区裁剪。目前,TiDB 支持的单调函数如下: -```sql -unix_timestamp -to_days -``` +* [`UNIX_TIMESTAMP()`](/functions-and-operators/date-and-time-functions.md) +* [`TO_DAYS()`](/functions-and-operators/date-and-time-functions.md) 例如,分区表达式是 `fn(col)` 形式,`fn` 为我们支持的单调函数 `to_days`,就可以使用分区裁剪: diff --git a/partitioned-table.md b/partitioned-table.md index f434ae2b66d2..2e2e290d2eaa 100644 --- a/partitioned-table.md +++ b/partitioned-table.md @@ -9,7 +9,10 @@ aliases: ['/docs-cn/dev/partitioned-table/','/docs-cn/dev/reference/sql/partitio ## 分区类型 -本节介绍 TiDB 中的分区类型。当前支持的类型包括 [Range 分区](#range-分区)、[Range COLUMNS 分区](#range-columns-分区)、[Range INTERVAL 分区](#range-interval-分区)、[List 分区](#list-分区)、[List COLUMNS 分区](#list-columns-分区)和 [Hash 分区](#hash-分区)。Range 分区、Range COLUMNS 分区、List 分区和 List COLUMNS 分区可以用于解决业务中大量删除带来的性能问题,支持快速删除分区。Hash 分区则可以用于大量写入场景下的数据打散。 +本节介绍 TiDB 中的分区类型。当前支持的类型包括 [Range 分区](#range-分区)、[Range COLUMNS 分区](#range-columns-分区)、[Range INTERVAL 分区](#range-interval-分区)、[List 分区](#list-分区)、[List COLUMNS 分区](#list-columns-分区)、[Hash 分区](#hash-分区)和 [Key 分区](#key-分区)。 + +- Range 分区、Range COLUMNS 分区、List 分区和 List COLUMNS 分区可以用于解决业务中大量删除带来的性能问题,支持快速删除分区。 +- Hash 分区和 Key 分区可以用于大量写入场景下的数据打散。与 Hash 分区相比,Key 分区支持多列打散和非整数类型字段的打散。 ### Range 分区 @@ -266,7 +269,7 @@ PARTITION BY RANGE COLUMNS(`report_date`) 可选参数 `NULL PARTITION` 会创建一个分区,其中分区表达式推导出的值为 `NULL` 的数据会放到该分区。在分区表达式中,`NULL` 会被认为是小于任何其他值。参见[分区对 NULL 值的处理](#range-分区对-null-的处理)。 -可选参数 `MAXVALUE PARTITION` 会创建一个最后的分区,其值为 `PARTITION P_MAXVALUE VALUES LESS THAN (MAXVALUE)`。 +可选参数 `MAXVALUE PARTITION` 会创建一个最后的分区,其值为 `PARTITION P_MAXVALUE VALUES LESS THAN (MAXVALUE)`。 #### ALTER INTERVAL 分区 @@ -475,7 +478,7 @@ PARTITION BY LIST COLUMNS(id,name) ( Hash 分区主要用于保证数据均匀地分散到一定数量的分区里面。在 Range 分区中你必须为每个分区指定值的范围;在 Hash 分区中,你只需要指定分区的数量。 -使用 Hash 分区时,需要在 `CREATE TABLE` 后面添加 `PARTITION BY HASH (expr)`,其中 `expr` 是一个返回整数的表达式。当这一列的类型是整数类型时,它可以是一个列名。此外,你很可能还需要加上 `PARTITIONS num`,其中 `num` 是一个正整数,表示将表划分多少分区。 +创建 Hash 分区表时,需要在 `CREATE TABLE` 后面添加 `PARTITION BY HASH (expr)`,其中 `expr` 是一个返回整数的表达式。当这一列的类型是整数类型时,它可以是一个列名。此外,你很可能还需要加上 `PARTITIONS num`,其中 `num` 是一个正整数,表示将表划分多少分区。 下面的语句将创建一个 Hash 分区表,按 `store_id` 分成 4 个分区: @@ -545,6 +548,84 @@ MOD(YEAR('2005-09-01'),4) = 1 ``` +### Key 分区 + +TiDB 从 v7.0.0 开始支持 Key 分区。在 v7.0.0 之前的版本中,创建 Key 分区表时,TiDB 会将其创建为非分区表并给出告警。 + +Key 分区与 Hash 分区都可以保证将数据均匀地分散到一定数量的分区里面,区别是 Hash 分区只能根据一个指定的整数表达式或字段进行分区,而 Key 分区可以根据字段列表进行分区,且 Key 分区的分区字段不局限于整数类型。TiDB Key 分区表的 Hash 算法与 MySQL 不一样,因此表的数据分布也不一样。 + +创建 Key 分区表时,你需要在 `CREATE TABLE` 后面添加 `PARTITION BY KEY (columList)`,其中 `columnList` 是字段列表,可以包含一个或多个字段。每个字段的类型可以是除 `BLOB`、`JSON`、`GEOMETRY` 之外的任意类型(请注意 TiDB 不支持 `GEOMETRY` 类型)。此外,你很可能还需要加上 `PARTITIONS num`,其中 `num` 是一个正整数,表示将表划分多少个分区;或者加上分区名的定义,例如,加上 `(PARTITION p0, PARTITION p1)` 代表将表划分为两个分区,分区名为 `p0` 和 `p1`。 + +下面的语句将创建一个 Key 分区表,按 `store_id` 分成 4 个分区: + +```sql +CREATE TABLE employees ( + id INT NOT NULL, + fname VARCHAR(30), + lname VARCHAR(30), + hired DATE NOT NULL DEFAULT '1970-01-01', + separated DATE DEFAULT '9999-12-31', + job_code INT, + store_id INT +) + +PARTITION BY KEY(store_id) +PARTITIONS 4; +``` + +如果不指定 `PARTITIONS num`,默认的分区数量为 1。 + +你也可以根据 VARCHAR 等非整数字段创建 Key 分区表。下面的语句按 `fname` 将表分成 4 个分区: + +```sql +CREATE TABLE employees ( + id INT NOT NULL, + fname VARCHAR(30), + lname VARCHAR(30), + hired DATE NOT NULL DEFAULT '1970-01-01', + separated DATE DEFAULT '9999-12-31', + job_code INT, + store_id INT +) + +PARTITION BY KEY(fname) +PARTITIONS 4; +``` + +你还可以根据多列字段创建 Key 分区表。下面的语句按 `fname`、`store_id` 将表分成 4 个分区: + +```sql +CREATE TABLE employees ( + id INT NOT NULL, + fname VARCHAR(30), + lname VARCHAR(30), + hired DATE NOT NULL DEFAULT '1970-01-01', + separated DATE DEFAULT '9999-12-31', + job_code INT, + store_id INT +) + +PARTITION BY KEY(fname, store_id) +PARTITIONS 4; +``` + +目前,TiDB 不支持分区字段列表 `PARTITION BY KEY` 为空的 Key 分区表。下面的语句将创建一个非分区表,并向客户端返回 `Unsupported partition type KEY, treat as normal table` 警告。 + +```sql +CREATE TABLE employees ( + id INT NOT NULL, + fname VARCHAR(30), + lname VARCHAR(30), + hired DATE NOT NULL DEFAULT '1970-01-01', + separated DATE DEFAULT '9999-12-31', + job_code INT, + store_id INT +) + +PARTITION BY KEY() +PARTITIONS 4; +``` + ### TiDB 对 Linear Hash 分区的处理 在 v6.4.0 之前,如果在 TiDB 上执行 [MySQL Linear Hash 分区](https://dev.mysql.com/doc/refman/5.7/en/partitioning-linear-hash.html) 的 DDL 语句,TiDB 只能创建非分区表。在这种情况下,如果你仍然想要在 TiDB 中创建分区表,你需要修改这些 DDL 语句。 @@ -555,6 +636,12 @@ MOD(YEAR('2005-09-01'),4) - 对于 MySQL Linear Hash 分区的其他 SQL 语句,TiDB 将正常返回对应的 Hash 分区的查询结果。但当分区数不是 2 的幂(意味着分区表中行的分布情况与 MySQL 不同)时,[分区选择](#分区选择)、`TRUNCATE PARTITION`、`EXCHANGE PARTITION` 返回的结果将和 MySQL 有所差异。 +### TiDB 对 Linear Key 分区的处理 + +TiDB 从 v7.0.0 开始支持 Key 分区,并支持解析 MySQL 的 `PARTITION BY LINEAR KEY` 语法,但会忽略其中的 `LINEAR` 关键字,只采用非线性 Hash 算法。 + +在 v7.0.0 之前的版本中,创建 Key 分区表时,TiDB 会将其创建为非分区表并给出告警。 + ### 分区对 NULL 值的处理 TiDB 允许计算结果为 NULL 的分区表达式。注意,NULL 不是一个整数类型,NULL 小于所有的整数类型值,正如 `ORDER BY` 的规则一样。 @@ -703,13 +790,22 @@ Empty set (0.00 sec) > > TiDB 的最终行为以本文档描述为准。 +#### Key 分区对 NULL 的处理 + +在 Key 分区中 NULL 值的处理与 Hash 分区一致:如果分区字段的值为 NULL,它会被当作 0 值处理。 + ## 分区管理 -对于 `LIST` 和 `RANGE` 分区表,通过 `ALTER TABLE <表名> ADD PARTITION (<分区说明>)` 或 `ALTER TABLE <表名> DROP PARTITION <分区列表>` 语句,可以执行添加和删除分区的操作。 +对于 `RANGE`、`RANGE COLUMNS`、`LIST`、`LIST COLUMNS` 分区表,你可以进行以下分区管理操作: + +- 使用 `ALTER TABLE <表名> ADD PARTITION (<分区说明>)` 语句添加分区。 +- 使用 `ALTER TABLE <表名> DROP PARTITION <分区列表>` 删除分区。 +- 使用 `ALTER TABLE <表名> TRUNCATE PARTITION <分区列表>` 语句清空分区里的数据。`TRUNCATE PARTITION` 的逻辑与 [`TRUNCATE TABLE`](/sql-statements/sql-statement-truncate.md) 相似,但它的操作对象为分区。 +- 使用 `ALTER TABLE <表名> REORGANIZE PARTITION <分区列表> INTO (<新的分区说明>)`语句对分区进行合并、拆分、或者其他修改。 对于 `LIST` 和 `RANGE` 分区表,暂不支持 `REORGANIZE PARTITION` 语句。 -对于 `HASH` 分区表,暂不支持 `COALESCE PARTITION` 和 `ADD PARTITION` 语句。 +对于 `HASH` 和 `KEY` 分区表,目前只支持 `ALTER TABLE ... TRUNCATE PARTITION` 分区管理语句,不支持 `COALESCE PARTITION` 和 `ADD PARTITION` 语句。 `EXCHANGE PARTITION` 语句用来交换分区和非分区表,类似于重命名表如 `RENAME TABLE t1 TO t1_tmp, t2 TO t1, t1_tmp TO t2` 的操作。 @@ -729,88 +825,178 @@ Empty set (0.00 sec) - TiCDC:分区表和非分区表都有主键或者唯一键时,TiCDC 同步 `EXCHANGE PARTITION` 操作;反之 TiCDC 将不会同步。 - TiDB Lightning 和 BR:使用 TiDB Lightning 导入或使用 BR 恢复的过程中,不要执行 `EXCHANGE PARTITION` 操作。 -### Range 分区管理 +### 管理 List 分区、List COLUMNS 分区、Range 分区、Range COLUMNS 分区 -创建分区表: - -{{< copyable "sql" >}} +本小节将以如下 SQL 语句创建的分区表为例,介绍如何管理 Range 分区和 List 分区。 ```sql CREATE TABLE members ( - id INT, - fname VARCHAR(25), - lname VARCHAR(25), - dob DATE + id int, + fname varchar(255), + lname varchar(255), + dob date, + data json ) +PARTITION BY RANGE (YEAR(dob)) ( + PARTITION pBefore1950 VALUES LESS THAN (1950), + PARTITION p1950 VALUES LESS THAN (1960), + PARTITION p1960 VALUES LESS THAN (1970), + PARTITION p1970 VALUES LESS THAN (1980), + PARTITION p1980 VALUES LESS THAN (1990), + PARTITION p1990 VALUES LESS THAN (2000)); + +CREATE TABLE member_level ( + id int, + level int, + achievements json +) +PARTITION BY LIST (level) ( + PARTITION l1 VALUES IN (1), + PARTITION l2 VALUES IN (2), + PARTITION l3 VALUES IN (3), + PARTITION l4 VALUES IN (4), + PARTITION l5 VALUES IN (5)); +``` -PARTITION BY RANGE( YEAR(dob) ) ( - PARTITION p0 VALUES LESS THAN (1980), - PARTITION p1 VALUES LESS THAN (1990), - PARTITION p2 VALUES LESS THAN (2000) -); +### 删除分区 + +```sql +ALTER TABLE members DROP PARTITION p1990; + +ALTER TABLE member_level DROP PARTITION l5; ``` -删除分区: +### 清空分区 -{{< copyable "sql" >}} +```sql +ALTER TABLE members TRUNCATE PARTITION p1980; + +ALTER TABLE member_level TRUNCATE PARTITION l4; +``` + +### 添加分区 ```sql -ALTER TABLE members DROP PARTITION p2; +ALTER TABLE members ADD PARTITION (PARTITION `p1990to2010` VALUES LESS THAN (2010)); + +ALTER TABLE member_level ADD PARTITION (PARTITION l5_6 VALUES IN (5,6)); ``` +对于 Range 分区表,`ADD PARTITION` 只能在分区列表的最后添加新的分区。与分区列表中已有的分区相比,你需要将新分区的 `VALUES LESS THAN` 定义为更大的值。否则,执行该语句时将会报错。 + +```sql +ALTER TABLE members ADD PARTITION (PARTITION p1990 VALUES LESS THAN (2000)); ``` -Query OK, 0 rows affected (0.03 sec) + +``` +ERROR 1493 (HY000): VALUES LESS THAN value must be strictly increasing for each partition ``` -清空分区: +### 重组分区 -{{< copyable "sql" >}} +拆分分区: ```sql -ALTER TABLE members TRUNCATE PARTITION p1; -``` +ALTER TABLE members REORGANIZE PARTITION `p1990to2010` INTO +(PARTITION p1990 VALUES LESS THAN (2000), + PARTITION p2000 VALUES LESS THAN (2010), + PARTITION p2010 VALUES LESS THAN (2020), + PARTITION p2020 VALUES LESS THAN (2030), + PARTITION pMax VALUES LESS THAN (MAXVALUE)); -``` -Query OK, 0 rows affected (0.03 sec) +ALTER TABLE member_level REORGANIZE PARTITION l5_6 INTO +(PARTITION l5 VALUES IN (5), + PARTITION l6 VALUES IN (6)); ``` -> **注意:** -> -> `ALTER TABLE ... REORGANIZE PARTITION` 在 TiDB 中暂不支持。 +合并分区: -添加分区: +```sql +ALTER TABLE members REORGANIZE PARTITION pBefore1950,p1950 INTO (PARTITION pBefore1960 VALUES LESS THAN (1960)); -{{< copyable "sql" >}} +ALTER TABLE member_level REORGANIZE PARTITION l1,l2 INTO (PARTITION l1_2 VALUES IN (1,2)); +``` + +修改分区表定义: ```sql -ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2010)); +ALTER TABLE members REORGANIZE PARTITION pBefore1960,p1960,p1970,p1980,p1990,p2000,p2010,p2020,pMax INTO +(PARTITION p1800 VALUES LESS THAN (1900), + PARTITION p1900 VALUES LESS THAN (2000), + PARTITION p2000 VALUES LESS THAN (2100)); + +ALTER TABLE member_level REORGANIZE PARTITION l1_2,l3,l4,l5,l6 INTO +(PARTITION lOdd VALUES IN (1,3,5), + PARTITION lEven VALUES IN (2,4,6)); ``` -Range 分区中,`ADD PARTITION` 只能在分区列表的最后面添加,如果是添加到已存在的分区范围则会报错: +在重组分区时,需要注意以下关键点: -{{< copyable "sql" >}} +- 重组分区(包括合并或拆分分区)只能修改分区定义,无法修改分区表类型。例如,无法将 List 类型修改为 Range 类型,或将 Range COLUMNS 类型修改为 Range 类型。 + +- 对于 Range 分区表,你只能对表中相邻的分区进行重组: + + ```sql + ALTER TABLE members REORGANIZE PARTITION p1800,p2000 INTO (PARTITION p2000 VALUES LESS THAN (2100)); + ``` + + ``` + ERROR 8200 (HY000): Unsupported REORGANIZE PARTITION of RANGE; not adjacent partitions + ``` + +- 对于 Range 分区表,如需修改 Range 定义中的最大值,必须保证 `VALUES LESS THAN` 中新定义的值大于现有分区中的所有值。否则,TiDB 将报错,提示现有的行值对应不到分区。 + + ```sql + INSERT INTO members VALUES (313, "John", "Doe", "2022-11-22", NULL); + ALTER TABLE members REORGANIZE PARTITION p2000 INTO (PARTITION p2000 VALUES LESS THAN (2050)); -- 执行成功,因为 2050 包含了现有的所有行 + ALTER TABLE members REORGANIZE PARTITION p2000 INTO (PARTITION p2000 VALUES LESS THAN (2020)); -- 执行失败,因为 2022 将对应不到分区 + ``` + + ``` + ERROR 1526 (HY000): Table has no partition for value 2022 + ``` + +- 对于 List 分区表,如需修改分区定义中的数据集合,必须保证新的数据集合能覆盖到该分区中现有的所有值,否则 TiDB 将报错。 + + ```sql + INSERT INTO member_level (id, level) values (313, 6); + ALTER TABLE member_level REORGANIZE PARTITION lEven INTO (PARTITION lEven VALUES IN (2,4)); + ``` + + ``` + ERROR 1526 (HY000): Table has no partition for value 6 + ``` + +### 管理 Hash 分区 + +跟 Range 分区不同,Hash 分区不支持 `DROP PARTITION`。 + +目前 TiDB 的实现暂时不支持 `ALTER TABLE ... COALESCE PARTITION`。对于暂不支持的分区管理语句,TiDB 会返回错误。 ```sql -ALTER TABLE members - ADD PARTITION ( - PARTITION n VALUES LESS THAN (1970)); +ALTER TABLE MEMBERS OPTIMIZE PARTITION p0; ``` -``` -ERROR 1463 (HY000): VALUES LESS THAN value must be strictly » - increasing for each partition +```sql +ERROR 8200 (HY000): Unsupported optimize partition ``` -### Hash 分区管理 +### Key 分区管理 -跟 Range 分区不同,Hash 分区不能够 `DROP PARTITION`。 +目前 TiDB 中 Key 分区支持的分区管理语句只有 `ALTER TABLE ... TRUNCATE PARTITION`。 -目前 TiDB 的实现暂时不支持 `ALTER TABLE ... COALESCE PARTITION`。对于暂不支持的分区管理语句,TiDB 会返回错误。 +```sql +ALTER TABLE members TRUNCATE PARTITION p0; +``` -{{< copyable "sql" >}} +``` +Query OK, 0 rows affected (0.03 sec) +``` + +对于暂不支持的分区管理语句,TiDB 会返回错误。 ```sql -alter table members optimize partition p0; +ALTER TABLE members OPTIMIZE PARTITION p0; ``` ```sql @@ -917,7 +1103,7 @@ SELECT fname, lname, region_code, dob 如果 TiKV 不支持 `fn`,则优化阶段不会把 `fn(col)` 推到叶子节点,而是在叶子上面连接一个 Selection 节点,分区裁剪的实现没有处理这种父节点的 Selection 中的条件,因此对不能下推到 TiKV 的表达式不支持分区裁剪。 -4. 对于 Hash 分区类型,只有等值比较的查询条件能够支持分区裁剪。 +4. 对于 Hash 和 Key 分区类型,只有等值比较的查询条件能够支持分区裁剪。 5. 对于 Range 分区类型,分区表达式必须是 `col` 或者 `fn(col)` 的简单形式,查询条件是 `>`、`<`、`=`、`>=`、`<=` 时才能支持分区裁剪。如果分区表达式是 `fn(col)` 形式,还要求 `fn` 必须是单调函数,才有可能分区裁剪。 @@ -927,10 +1113,8 @@ SELECT fname, lname, region_code, dob 理论上所有满足单调条件(严格或者非严格)的函数都是可以支持分区裁剪。实际上,目前 TiDB 已经支持的单调函数只有: - ``` - unix_timestamp - to_days - ``` + * [`UNIX_TIMESTAMP()`](/functions-and-operators/date-and-time-functions.md) + * [`TO_DAYS()`](/functions-and-operators/date-and-time-functions.md) 例如,分区表达式是简单列的情况: @@ -1338,11 +1522,11 @@ YEARWEEK() ### 兼容性 -目前 TiDB 支持 Range 分区、List 分区、List COLUMNS 分区和 Hash 分区,其它的 MySQL 分区类型(例如 Key 分区)尚不支持。 +目前 TiDB 支持 Range 分区、Range Columns 分区、List 分区、List COLUMNS 分区、Hash 分区和 Key 分区,其它的 MySQL 分区类型尚不支持。 -对于 Range Columns 类型的分区表,目前只支持单列的场景。 +对于 Key 分区,目前不支持分区字段为空的场景。 -分区管理方面,只要底层实现可能会涉及数据挪动的操作,目前都暂不支持。包括且不限于:调整 Hash 分区表的分区数量,修改 Range 分区表的范围,合并分区,交换分区等。 +分区管理方面,只要底层实现可能会涉及数据挪动的操作,目前都暂不支持。包括且不限于:调整 Hash 分区表的分区数量,修改 Range 分区表的范围,合并分区等。 对于暂不支持的分区类型,在 TiDB 中建表时会忽略分区信息,以普通表的形式创建,并且会报 Warning。 @@ -1654,9 +1838,10 @@ mysql> explain select /*+ TIDB_INLJ(t1, t2) */ t1.* from t1, t2 where t2.code = {{< copyable "sql" >}} ```sql - select distinct concat(TABLE_SCHEMA,'.',TABLE_NAME) - from information_schema.PARTITIONS - where TABLE_SCHEMA not in ('INFORMATION_SCHEMA','mysql','sys','PERFORMANCE_SCHEMA','METRICS_SCHEMA'); + SELECT DISTINCT CONCAT(TABLE_SCHEMA,'.', TABLE_NAME) + FROM information_schema.PARTITIONS + WHERE TIDB_PARTITION_ID IS NOT NULL + AND TABLE_SCHEMA NOT IN ('INFORMATION_SCHEMA', 'mysql', 'sys', 'PERFORMANCE_SCHEMA', 'METRICS_SCHEMA'); ``` ``` @@ -1690,7 +1875,7 @@ mysql> explain select /*+ TIDB_INLJ(t1, t2) */ t1.* from t1, t2 where t2.code = 可以按需将 `ALL COLUMNS` 改为实际需要的列。 3. 将批量更新语句导出到文件: - + {{< copyable "sql" >}} ```sql diff --git a/pd-configuration-file.md b/pd-configuration-file.md index afb7378af7c9..060deaeddf05 100644 --- a/pd-configuration-file.md +++ b/pd-configuration-file.md @@ -447,3 +447,49 @@ PD 中内置的 [TiDB Dashboard](/dashboard/dashboard-intro.md) 相关配置项 + 是否启用 TiDB Dashboard 遥测功能。 + 默认值:false + 参阅[遥测](/telemetry.md)了解该功能详情。 + +## `replication-mode` + +Region 同步模式相关的配置项。更多详情,请参阅[启用自适应同步模式](/two-data-centers-in-one-city-deployment.md#启用自适应同步模式)。 + +## Controllor + +PD 中内置的 [Resource Control](/tidb-resource-control.md) 相关的配置项。 + +### `degraded-mode-wait-duration` + ++ 触发降级模式需要等待的时间。降级模式是指在 Local Token Bucket (LTB) 和 Global Token Bucket (GTB) 失联的情况下,LTB 将回退到默认的资源组配置,不再有 GTB 授权 token,从而保证在网络隔离或者异常情况下,服务不受影响。 ++ 默认值: 0s ++ 默认为不开启降级模式 + +### `request-unit` + +下面是 [Request Unit (RU)](/tidb-resource-control.md#什么是-request-unit-ru) 相关的配置项。 + +#### `read-base-cost` + ++ 每次读请求转换成 RU 的基准系数 ++ 默认值: 0.25 + +#### `write-base-cost` + ++ 每次写请求转换成 RU 的基准系数 ++ 默认值: 1 + +#### `read-cost-per-byte` + ++ 读流量转换成 RU 的基准系数 ++ 默认值: 1/(64 * 1024) ++ 1 RU = 64 KiB 读取字节 + +#### `write-cost-per-byte` + ++ 写流量转换成 RU 的基准系数 ++ 默认值: 1/1024 ++ 1 RU = 1 KiB 写入字节 + +#### `read-cpu-ms-cost` + ++ CPU 转换成 RU 的基准系数 ++ 默认值: 1/3 ++ 1 RU = 3 毫秒 CPU 时间 diff --git a/pd-control.md b/pd-control.md index ad964d3ec5f8..40fa02815359 100644 --- a/pd-control.md +++ b/pd-control.md @@ -1065,9 +1065,11 @@ region topsize } ``` -### `region check [miss-peer | extra-peer | down-peer | pending-peer | offline-peer | empty-region | hist-size | hist-keys]` +### `region check [miss-peer | extra-peer | down-peer | pending-peer | offline-peer | empty-region | hist-size | hist-keys] [--jq=""]` -用于查询处于异常状态的 Region,各类型的意义如下 +用于查询处于异常状态的 Region,使用 jq 格式化输出请参考 [jq 格式化 JSON 输出示例](#jq-格式化-json-输出示例)。 + +各类型的意义如下: - miss-peer:缺副本的 Region - extra-peer:多副本的 Region @@ -1257,6 +1259,23 @@ scheduler config balance-hot-region-scheduler // 显示 balance-hot-region 调 scheduler config balance-hot-region-scheduler set enable-for-tiflash true ``` +### `service-gc-safepoint` + +用于查询当前的 GC safepoint 与 service GC safepoint,输出结果示例如下: + +```bash +{ + "service_gc_safe_points": [ + { + "service_id": "gc_worker", + "expired_at": 9223372036854775807, + "safe_point": 439923410637160448 + } + ], + "gc_safe_point": 0 +} +``` + ### `store [delete | cancel-delete | label | weight | remove-tombstone | limit ] [--jq=""]` 使用 jq 格式化输出请参考 [jq 格式化 json 输出示例](#jq-格式化-json-输出示例)。 diff --git a/releases/release-6.0.0-dmr.md b/releases/release-6.0.0-dmr.md index 11c3bc19c4c5..52f4058da5f4 100644 --- a/releases/release-6.0.0-dmr.md +++ b/releases/release-6.0.0-dmr.md @@ -113,7 +113,7 @@ v6.0.0 是 DMR 版本,版本名称为 6.0.0-DMR。 TiDB 是原生计算存储分离架构,算子下推可以在存储层过滤无效数据,大大减少 TiDB 与 TiKV 的数据传输,提升查询效率。TiDB 在 v6.0.0 支持更多的表达式和 `BIT` 数据类型下推至 TiKV,以提升运算该类内容时的查询效率。 - [用户文档](/functions-and-operators/expressions-pushed-down.md#加入黑名单),[#30738](https://github.com/pingcap/tidb/issues/30738) + [用户文档](/functions-and-operators/expressions-pushed-down.md),[#30738](https://github.com/pingcap/tidb/issues/30738) - 热点索引优化 diff --git a/releases/release-6.2.0.md b/releases/release-6.2.0.md index c325c58b8ff2..6b21b908d734 100644 --- a/releases/release-6.2.0.md +++ b/releases/release-6.2.0.md @@ -131,7 +131,7 @@ TiDB 版本:6.2.0-DMR 从更低的版本升级到 v6.2.0 版本时,所有的表默认不开启 FastScan 功能,而是保持一致性的数据扫描功能。你可以为每一张表独立开启 FastScan 功能。如果在 v6.2.0 版本设定表开启 FastScan 功能后,当降级到更低版本时 FastScan 功能设置将失效,但不影响数据的正常读取。这种情况等同于强一致性的数据扫描功能。 - [用户文档](/develop/dev-guide-use-fastscan.md) [#5252](https://github.com/pingcap/tiflash/issues/5252) @[hongyunyan](https://github.com/hongyunyan) + [用户文档](/tiflash/use-fastscan.md) [#5252](https://github.com/pingcap/tiflash/issues/5252) @[hongyunyan](https://github.com/hongyunyan) ### 稳定性 diff --git a/releases/release-6.3.0.md b/releases/release-6.3.0.md index 9558f7e9953e..82e079ed5a09 100644 --- a/releases/release-6.3.0.md +++ b/releases/release-6.3.0.md @@ -82,7 +82,7 @@ TiDB 版本:6.3.0-DMR * TiFlash 调整 FastScan 功能使用方式(实验特性)[#5252](https://github.com/pingcap/tiflash/issues/5252) @[hongyunyan](https://github.com/hongyunyan) - TiFlash 从 v6.2.0 版本开始引入的快速扫描功能 (FastScan),性能上符合预期,但是使用方式上不够灵活。因此,TiFlash 在 v6.3.0 版本[调整 FastScan 功能的使用方式](/develop/dev-guide-use-fastscan.md):废弃了 `ALTER TABLE ...SET TiFLASH MODE ...` 语法启用方式,改为使用系统变量 [`tiflash_fastscan`](/system-variables.md#tiflash_fastscan-从-v630-版本开始引入) 进行控制。 + TiFlash 从 v6.2.0 版本开始引入的快速扫描功能 (FastScan),性能上符合预期,但是使用方式上不够灵活。因此,TiFlash 在 v6.3.0 版本[调整 FastScan 功能的使用方式](/tiflash/use-fastscan.md):废弃了 `ALTER TABLE ...SET TiFLASH MODE ...` 语法启用方式,改为使用系统变量 [`tiflash_fastscan`](/system-variables.md#tiflash_fastscan-从-v630-版本开始引入) 进行控制。 从 v6.2.0 版本升级到 v6.3.0 版本时,在 v6.2.0 版本的 FastScan 设置将失效,但不影响数据的正常读取。你需要重新使用变量方式设置 FastScan。从 v6.2.0 及更早版本升级到 v6.3.0 时,所有会话默认不开启 FastScan 功能,而是保持一致性的数据扫描功能。 @@ -253,7 +253,7 @@ TiDB 版本:6.3.0-DMR * 日志备份支持 GCS 和 Azure Blob Storage 作为备份存储。 * 日志备份功能兼容分区交换 (Exchange Partition) DDL。 -* 不再支持通过 `ALTER TABLE ...SET TiFLASH MODE ...` 语法启用或禁用 [FastScan](/develop/dev-guide-use-fastscan.md) 功能。从 v6.2.0 版本升级到 v6.3.0 版本时,在 v6.2.0 版本的 FastScan 设置将失效,但不影响数据的正常读取。你需要重新使用变量方式设置 FastScan。从 v6.2.0 及更早版本升级到 v6.3.0 时,所有会话默认不开启 FastScan 功能,而是保持一致性的数据扫描功能。 +* 不再支持通过 `ALTER TABLE ...SET TiFLASH MODE ...` 语法启用或禁用 [FastScan](/tiflash/use-fastscan.md) 功能。从 v6.2.0 版本升级到 v6.3.0 版本时,在 v6.2.0 版本的 FastScan 设置将失效,但不影响数据的正常读取。你需要重新使用变量方式设置 FastScan。从 v6.2.0 及更早版本升级到 v6.3.0 时,所有会话默认不开启 FastScan 功能,而是保持一致性的数据扫描功能。 * 在 Linux AMD64 架构的硬件平台部署 TiFlash 时,CPU 必须支持 AVX2 指令集。确保命令 `cat /proc/cpuinfo | grep avx2` 有输出。而在 Linux ARM64 架构的硬件平台部署 TiFlash 时,CPU 必须支持 ARMv8 架构。确保命令 `cat /proc/cpuinfo | grep 'crc32' | grep 'asimd'` 有输出。通过使用向量扩展指令集,TiFlash 的向量化引擎能提供更好的性能。 * TiDB 支持的最小 HAProxy 版本为 v1.5。使用 v1.5 到 v2.1 之间的 HAProxy 时,需要在 `mysql-check` 中配置 `post-41`。建议使用 HAProxy v2.2 或更高版本。 diff --git a/releases/release-6.5.1.md b/releases/release-6.5.1.md new file mode 100644 index 000000000000..e36dabb022a3 --- /dev/null +++ b/releases/release-6.5.1.md @@ -0,0 +1,187 @@ +--- +title: TiDB 6.5.1 Release Notes +summary: 了解 TiDB 6.5.1 版本的兼容性变更、改进提升,以及错误修复。 +--- + +# TiDB 6.5.1 Release Notes + +发版日期:2023 年 3 月 10 日 + +TiDB 版本:6.5.1 + +试用链接:[快速体验](https://docs.pingcap.com/zh/tidb/v6.5/quick-start-with-tidb) | [生产部署](https://docs.pingcap.com/zh/tidb/v6.5/production-deployment-using-tiup) | [下载离线包](https://cn.pingcap.com/product-community/?version=v6.5.1#version-list) + +## 兼容性变更 + +- 自 2023 年 2 月 20 日起,新发布的 TiDB 和 TiDB Dashboard 版本(包含 6.5.1),默认关闭[遥测功能](/telemetry.md),即默认不再收集使用情况信息分享给 PingCAP。如果升级至这些版本前使用默认的遥测配置,则升级后遥测功能处于关闭状态。具体的版本可参考 [TiDB 版本发布时间线](/releases/release-timeline.md)。 + + - 系统变量 [`tidb_enable_telemetry`](/system-variables.md#tidb_enable_telemetry-从-v402-版本开始引入) 默认值由 `ON` 修改为 `OFF`。 + - TiDB 配置项 [`enable-telemetry`](/tidb-configuration-file.md#enable-telemetry-从-v402-版本开始引入) 默认值由 `true` 改为 `false`。 + - PD 配置项 [`enable-telemetry`](/pd-configuration-file.md#enable-telemetry) 默认值由 `true` 改为 `false`。 + +- 从 v1.11.3 起,新部署的 TiUP 默认关闭遥测功能,即默认不再收集使用情况信息。如果从 v1.11.3 之前的 TiUP 版本升级至 v1.11.3 或更高 TiUP 版本,遥测保持升级前的开启或关闭状态。 + +- 由于可能存在正确性问题,分区表目前不再支持修改列类型 [#40620](https://github.com/pingcap/tidb/issues/40620) @[mjonss](https://github.com/mjonss) + +- TiKV 配置项 [`advance-ts-interval`](/tikv-configuration-file.md#advance-ts-interval) 默认值由 `1s` 修改为 `20s`。你可以通过调整该配置项提高 Stale Read 数据的时效性(即减少延时),详情参见[减少 Stale Read 延时](/stale-read.md#减少-stale-read-延时)。 + +## 改进提升 + ++ TiDB + + - 从 v6.5.1 起,由 **v1.4.3 或以上版本的 TiDB Operator** 部署的 TiDB 全栈支持 IPv6 地址,这意味着 TiDB 可以支持更大的地址空间,并提供更好的安全性和网络性能。 + + - 完全支持 IPv6 寻址:TiDB 支持使用 IPv6 地址进行所有网络连接,包括客户端连接、节点之间的内部通信以及与外部系统的通信。 + - 双栈支持:如果你尚未准备好完全切换到 IPv6,TiDB 也支持双栈网络。这意味着你可以在同一个 TiDB 集群中使用 IPv4 和 IPv6 地址,可以通过配置 IPv6 优先的方式来选择网络部署模式。 + + IPv6 部署相关信息,请参考 [TiDB on Kubernetes 用户文档](https://docs.pingcap.com/zh/tidb-in-kubernetes/stable/configure-a-tidb-cluster#ipv6-支持)。 + + - 支持指定集群初次启动时的初始化 SQL 脚本 [#35624](https://github.com/pingcap/tidb/issues/35624) @[morgo](https://github.com/morgo) + + TiDB v6.5.1 新增 [`initialize-sql-file`](https://docs.pingcap.com/zh/tidb/v6.5/tidb-configuration-file#initialize-sql-file-从-v651-版本开始引入) 配置项。集群初次启动时,你可通过命令行参数 `--initialize-sql-file` 指定执行的 SQL 脚本。该功能可用于修改系统变量的值、创建用户或分配权限等。更多信息,请参考[用户文档](https://docs.pingcap.com/zh/tidb/v6.5/tidb-configuration-file#initialize-sql-file-从-v651-版本开始引入)。 + + - 定期清理过期的 Region 缓存,避免内存泄漏和性能下降问题 [#40461](https://github.com/pingcap/tidb/issues/40461) @[sticnarf](https://github.com/sticnarf) + - 新增 `--proxy-protocol-fallbackable` 配置项,控制是否启用 PROXY 协议回退模式。如果设置为 `true`,TiDB 可以接受非 PROXY 协议规范或者没有发送 PROXY 协议头的客户端连接 [#41409](https://github.com/pingcap/tidb/issues/41409) @[blacktear23](https://github.com/blacktear23) + - 提升了 Memory Tracker 的准确度 [#40900](https://github.com/pingcap/tidb/issues/40900) [#40500](https://github.com/pingcap/tidb/issues/40500) @[wshwsh12](https://github.com/wshwsh12) + - 当执行计划缓存无法生效时,系统会通过 Warning 返回原因 [#40210](https://github.com/pingcap/tidb/pull/40210) @[qw4990](https://github.com/qw4990) + - 改进了条件优化器在进行越界估算时的策略 [#39008](https://github.com/pingcap/tidb/issues/39008) @[time-and-fate](https://github.com/time-and-fate) + ++ TiKV + + - 支持在小于 1 core 的 CPU 下启动 TiKV [#13586](https://github.com/tikv/tikv/issues/13586) [#13752](https://github.com/tikv/tikv/issues/13752) [#14017](https://github.com/tikv/tikv/issues/14017) @[andreid-db](https://github.com/andreid-db) + - 将 Unified Read Pool 的线程上限 (`readpool.unified.max-thread-count`) 提高至 CPU 配额的 10 倍 [#13690](https://github.com/tikv/tikv/issues/13690) @[v01dstar](https://github.com/v01dstar) + - 为了节省跨域流量,`resolved-ts.advance-ts-interval` 的默认值从 `"1s"` 修改为 `"20s"` [#14100](https://github.com/tikv/tikv/issues/14100) @[overvenus](https://github.com/overvenus) + ++ TiFlash + + - 显著提升 TiFlash 在大数据量下的启动速度 [#6395](https://github.com/pingcap/tiflash/issues/6395) @[hehechen](https://github.com/hehechen) + ++ Tools + + + Backup & Restore (BR) + + - 优化 TiKV 端下载日志备份文件的并发度,提升常规场景下 PITR 恢复的性能 [#14206](https://github.com/tikv/tikv/issues/14206) @[YuJuncen](https://github.com/YuJuncen) + + + TiCDC + + - 默认打开 pull-based sink 功能提升系统的吞吐 [#8232](https://github.com/pingcap/tiflow/issues/8232) @[hi-rustin](https://github.com/hi-rustin) + - 支持将 redo log 存储至兼容 GCS 或 Azure 协议的对象存储 [#7987](https://github.com/pingcap/tiflow/issues/7987) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 采用异步模式实现 MQ sink 和 MySQL sink,提升 sink 的吞吐能力 [#5928](https://github.com/pingcap/tiflow/issues/5928) @[amyangfei](https://github.com/amyangfei) @[CharlesCheung96](https://github.com/CharlesCheung96) + +## 错误修复 + ++ TiDB + + - 修复 [`pessimistic-auto-commit`](/tidb-configuration-file.md#pessimistic-auto-commit) 配置项对 "Point Get" 查询不生效的问题 [#39928](https://github.com/pingcap/tidb/issues/39928) @[zyguan](https://github.com/zyguan) + - 修复 `INSERT` 或 `REPLACE` 语句在长会话连接中执行可能造成 Panic 的问题 [#40351](https://github.com/pingcap/tidb/issues/40351) @[fanrenhoo](https://github.com/fanrenhoo) + - 修复了 `auto analyze` 导致 graceful shutdown 耗时长的问题 [#40038](https://github.com/pingcap/tidb/issues/40038) @[xuyifangreeneyes](https://github.com/xuyifangreeneyes) + - 修复了 DDL 在 ingest 过程中可能会发生数据竞争的问题 [#40970](https://github.com/pingcap/tidb/issues/40970) @[tangenta](https://github.com/tangenta) + - 修复了添加索引时可能导致数据竞争的问题 [#40879](https://github.com/pingcap/tidb/issues/40879) @[tangenta](https://github.com/tangenta) + - 修复了表 Region 比较多时因 Region 缓存失效导致加索引效率低下的问题 [#38436](https://github.com/pingcap/tidb/issues/38436) @[tangenta](https://github.com/tangenta) + - 修复了 TiDB 在初始化时有可能死锁的问题 [#40408](https://github.com/pingcap/tidb/issues/40408) @[Defined2014](https://github.com/Defined2014) + - 修复了 TiDB 构造 key 范围时对 `NULL` 值处理不当,导致读取非预期数据的问题 [#40158](https://github.com/pingcap/tidb/issues/40158) @[tiancaiamao](https://github.com/tiancaiamao) + - 修复了内存重用导致的在某些情况下系统变量的值会被错误修改的问题 [#40979](https://github.com/pingcap/tidb/issues/40979) @[lcwangchao](https://github.com/lcwangchao) + - 修复了在执行 TTL 任务时,如果表的主键包含 `ENUM` 类型的列任务会失败的问题 [#40456](https://github.com/pingcap/tidb/issues/40456) @[lcwangchao](https://github.com/lcwangchao) + - 修复了在添加唯一索引时有可能会 panic 的问题 [#40592](https://github.com/pingcap/tidb/issues/40592) @[tangenta](https://github.com/tangenta) + - 修复了并发 truncate 同一张表时,部分 truncate 操作无法被 MDL 阻塞的问题 [#40484](https://github.com/pingcap/tidb/issues/40484) @[wjhuang2016](https://github.com/wjhuang2016) + - 修复了当动态裁剪模式下的分区表有 global binding 时,TiDB 重启失败的问题 [#40368](https://github.com/pingcap/tidb/issues/40368) @[Yisaer](https://github.com/Yisaer) + - 修复使用 "Cursor Read" 方式读取数据时可能因为 GC 而报错的问题 [#39447](https://github.com/pingcap/tidb/issues/39447) @[zyguan](https://github.com/zyguan) + - 修复 `SHOW PROCESSLIST` 信息中未显示 `EXECUTE` 语句的问题 [#41156](https://github.com/pingcap/tidb/issues/41156) @[YangKeao](https://github.com/YangKeao) + - 修复了 `globalMemoryControl` 在终止查询时可能会遇上 `KILL` 不结束的问题 [#41057](https://github.com/pingcap/tidb/issues/41057) @[wshwsh12](https://github.com/wshwsh12) + - 修复了 `indexMerge` 遇到错误后可能会导致 TiDB 崩溃的问题 [#41047](https://github.com/pingcap/tidb/issues/41047) [#40877](https://github.com/pingcap/tidb/issues/40877) @[guo-shaoge](https://github.com/guo-shaoge) @[windtalker](https://github.com/windtalker) + - 修复 `ANALYZE` 语句可能会被 `KILL` 终止的问题 [#41825](https://github.com/pingcap/tidb/issues/41825) @[XuHuaiyu](https://github.com/XuHuaiyu) + - 修复了 `indexMerge` 中可能会出现 goroutine 泄露的问题 [#41545](https://github.com/pingcap/tidb/issues/41545) [#41605](https://github.com/pingcap/tidb/issues/41605) @[guo-shaoge](https://github.com/guo-shaoge) + - 修复了无符号的 `TINYINT`/`SMALLINT`/`INT` 和小于 `0` 的 `DECIMAL`/`FLOAT`/`DOUBLE` 类型比较时,结果可能出错的问题 [#41736](https://github.com/pingcap/tidb/issues/41736) @[LittleFall](https://github.com/LittleFall) + - 修复了开启系统变量 `tidb_enable_reuse_chunk` 后可能会出现内存泄露的问题 [#40987](https://github.com/pingcap/tidb/issues/40987) @[guo-shaoge](https://github.com/guo-shaoge) + - 修复了时区中的数据争用可能导致数据和索引不一致问题 [#40710](https://github.com/pingcap/tidb/issues/40710) @[wjhuang2016](https://github.com/wjhuang2016) + - 修复了 `batch cop` 在执行过程中的 scan detail 信息不准确的问题 [#41582](https://github.com/pingcap/tidb/issues/41582) @[you06](https://github.com/you06) + - 修复 `cop` 并发度上限不受限制的问题 [#41134](https://github.com/pingcap/tidb/issues/41134) @[you06](https://github.com/you06) + - 修复 `cursor read` 中 `statement context` 被错误缓存的问题 [#39998](https://github.com/pingcap/tidb/issues/39998) @[zyguan](https://github.com/zyguan) + - 周期性清理过时的 Region 缓存以避免内存泄露和性能倒退 [#40355](https://github.com/pingcap/tidb/issues/40355) @[sticnarf](https://github.com/sticnarf) + - 修复对包含 `year const` 的查询使用 Plan Cache 时结果可能出错的问题 [#41628](https://github.com/pingcap/tidb/issues/41628) @[qw4990](https://github.com/qw4990) + - 修复查询区间太多且数据改动量大时估算误差可能较大的问题 [#39593](https://github.com/pingcap/tidb/issues/39593) @[time-and-fate](https://github.com/time-and-fate) + - 修复使用 Plan Cache 时部分条件无法被下推通过 Join 算子的问题 [#40093](https://github.com/pingcap/tidb/issues/40093) [#38205](https://github.com/pingcap/tidb/issues/38205) @[qw4990](https://github.com/qw4990) + - 修复 IndexMerge 计划在 SET 类型列上可能生成错误区间的问题 [#41273](https://github.com/pingcap/tidb/issues/41273) [#41293](https://github.com/pingcap/tidb/issues/41293) @[time-and-fate](https://github.com/time-and-fate) + - 修复 Plan Cache 处理 `int_col decimal` 条件时可能缓存 FullScan 计划的问题 [#40679](https://github.com/pingcap/tidb/issues/40679) [#41032](https://github.com/pingcap/tidb/issues/41032) @[qw4990](https://github.com/qw4990) + - 修复 Plan Cache 处理 `int_col in (decimal...)` 条件时可能缓存 FullScan 计划的问题 [#40224](https://github.com/pingcap/tidb/issues/40224) @[qw4990](https://github.com/qw4990) + - 修复 `ignore_plan_cache` hint 对 INSERT 语句可能不生效的问题 [#40079](https://github.com/pingcap/tidb/issues/40079) [#39717](https://github.com/pingcap/tidb/issues/39717) @[qw4990](https://github.com/qw4990) + - 修复 Auto Analyze 可能阻碍 TiDB 退出的问题 [#40038](https://github.com/pingcap/tidb/issues/40038) @[xuyifangreeneyes](https://github.com/xuyifangreeneyes) + - 修复在分区表的 Unsigned Primary Key 上可能构造错误访问区间的问题 [#40309](https://github.com/pingcap/tidb/issues/40309) @[winoros](https://github.com/winoros) + - 修复 Plan Cache 可能缓存 Shuffle 算子导致返回错误结果的问题 [#38335](https://github.com/pingcap/tidb/issues/38335) @[qw4990](https://github.com/qw4990) + - 修复在分区表上创建 Global Binding 后可能导致 TiDB 启动错误的问题 [#40368](https://github.com/pingcap/tidb/issues/40368) @[Yisaer](https://github.com/Yisaer) + - 修复慢日志中查询计划算子可能缺失的问题 [#41458](https://github.com/pingcap/tidb/issues/41458) @[time-and-fate](https://github.com/time-and-fate) + - 修复错误下推包含虚拟列的 TopN 算子到 TiKV 或 TiFlash 导致结果错误的问题 [#41355](https://github.com/pingcap/tidb/issues/41355) @[Dousir9](https://github.com/Dousir9) + - 修复添加索引时数据不一致的问题 [#40698](https://github.com/pingcap/tidb/issues/40698) [#40730](https://github.com/pingcap/tidb/issues/40730) [#41459](https://github.com/pingcap/tidb/issues/41459) [#40464](https://github.com/pingcap/tidb/issues/40464) [#40217](https://github.com/pingcap/tidb/issues/40217) @[tangenta](https://github.com/tangenta) + - 修复添加索引时出现 "Pessimistic lock not found" 的报错问题 [#41515](https://github.com/pingcap/tidb/issues/41515) @[tangenta](https://github.com/tangenta) + - 修复添加唯一索引时误报重复键的问题 [#41630](https://github.com/pingcap/tidb/issues/41630) @[tangenta](https://github.com/tangenta) + - 修复 TiDB 使用 `paging` 时性能下降的问题 [#40741](https://github.com/pingcap/tidb/issues/40741) @[solotzg](https://github.com/solotzg) + ++ TiKV + + - 修复 Resolved TS 导致网络流量升高的问题 [#14092](https://github.com/tikv/tikv/issues/14092) @[overvenus](https://github.com/overvenus) + - 修复 TiDB 中事务在执行悲观 DML 失败后,再执行其他 DML 时,如果 TiDB 和 TiKV 之间存在网络故障,可能会造成数据不一致的问题 [#14038](https://github.com/tikv/tikv/issues/14038) @[MyonKeminta](https://github.com/MyonKeminta) + - 修复转换 `const Enum` 类型到其他类型时报错的问题 [#14156](https://github.com/tikv/tikv/issues/14156) @[wshwsh12](https://github.com/wshwsh12) + - 修复 cop task 分页计算错误的问题 [#14254](https://github.com/tikv/tikv/issues/14254) @[you06](https://github.com/you06) + - 修复 `batch cop` 模式下 `scan_detail` 不准确问题 [#14109](https://github.com/tikv/tikv/issues/14109) @[you06](https://github.com/you06) + - 修复 Raft Engine 中的一个潜在错误,该错误可能导致 TiKV 检测到 Raft 数据损坏而无法重启 [#14338](https://github.com/tikv/tikv/issues/14338) @[tonyxuqqi](https://github.com/tonyxuqqi) + ++ PD + + - 修复 `replace-down-peer` 在特定条件下执行变慢的问题 [#5788](https://github.com/tikv/pd/issues/5788) @[HundunDM](https://github.com/HunDunDM) + - 修复 PD 可能会非预期地向 Region 添加多个 Learner 的问题 [#5786](https://github.com/tikv/pd/issues/5786) @[HunDunDM](https://github.com/HunDunDM) + - 修复 Region Scatter 任务会生成非预期的多余副本的问题 [#5909](https://github.com/tikv/pd/issues/5909) @[HundunDM](https://github.com/HunDunDM) + - 修复调用 `ReportMinResolvedTS` 过于频繁导致 PD OOM 的问题 [#5965](https://github.com/tikv/pd/issues/5965) @[HundunDM](https://github.com/HunDunDM) + - 修复 Region Scatter 接口可能导致 leader 分布不均匀的问题 [#6017](https://github.com/tikv/pd/issues/6017) @[HunDunDM](https://github.com/HunDunDM) + ++ TiFlash + + - 修复半连接在计算笛卡尔积时,使用内存过量的问题 [#6730](https://github.com/pingcap/tiflash/issues/6730) @[gengliqi](https://github.com/gengliqi) + - 修复 TiFlash 日志搜索过慢的问题 [#6829](https://github.com/pingcap/tiflash/issues/6829) @[hehechen](https://github.com/hehechen) + - 修复 TiFlash 在反复重启后由于误删文件而无法启动的问题 [#6486](https://github.com/pingcap/tiflash/issues/6486) @[JaySon-Huang](https://github.com/JaySon-Huang) + - 修复 TiFlash 在添加新列后查询可能报错的问题 [#6726](https://github.com/pingcap/tiflash/issues/6726) @[JaySon-Huang](https://github.com/JaySon-Huang) + - 修复 TiFlash 配置不支持 IPv6 的问题 [#6734](https://github.com/pingcap/tiflash/issues/6734) @[ywqzzy](https://github.com/ywqzzy) + ++ Tools + + + Backup & Restore (BR) + + - 修复 PD 与 TiDB server 的连接故障导致 PITR 备份进度不推进的问题 [#41082](https://github.com/pingcap/tidb/issues/41082) @[YuJuncen](https://github.com/YuJuncen) + - 修复 PD 与 TiKV 的连接故障导致 TiKV 不能监听 PITR 任务的问题 [#14159](https://github.com/tikv/tikv/issues/14159) @[YuJuncen](https://github.com/YuJuncen) + - 修复 PITR 不支持 PD 集群配置变更的问题 [#14165](https://github.com/tikv/tikv/issues/14165) @[YuJuncen](https://github.com/YuJuncen) + - 修复 PITR 功能不支持 CA-bundle 认证的问题 [#38775](https://github.com/pingcap/tidb/issues/38775) @[3pointer](https://github.com/3pointer) + - 修复 PITR 备份任务被删除时,存在备份信息残留导致新任务出现数据不一致的问题 [#40403](https://github.com/pingcap/tidb/issues/40403) @[joccau](https://github.com/joccau) + - 修复使用 `br debug` 命令解析 backupmeta 文件导致的 panic 的问题 [#40878](https://github.com/pingcap/tidb/issues/40878) @[MoCuishle28](https://github.com/MoCuishle28) + - 修复在某些情况下因无法获取 Region 大小导致恢复失败的问题 [#36053](https://github.com/pingcap/tidb/issues/36053) @[YuJuncen](https://github.com/YuJuncen) + - 修复当 TiDB 集群不存在 PITR 备份任务时,`resolve lock` 频率过高的问题 [#40759](https://github.com/pingcap/tidb/issues/40759) @[joccau](https://github.com/joccau) + - 修复恢复数据到正在运行日志备份的集群,导致日志备份文件无法恢复的问题 [#40797](https://github.com/pingcap/tidb/issues/40797) @[Leavrth](https://github.com/Leavrth) + - 修复全量备份失败后,从断点重启备份时 BR 会 panic 的问题 [#40704](https://github.com/pingcap/tidb/issues/40704) @[Leavrth](https://github.com/Leavrth) + - 修复 PITR 错误被覆盖的问题 [#40576](https://github.com/pingcap/tidb/issues/40576)@[Leavrth](https://github.com/Leavrth) + - 修复 PITR 备份任务在 advance owner 与 gc owner 不同时 checkpoint 不推进的问题 [#41806](https://github.com/pingcap/tidb/issues/41806) @[joccau](https://github.com/joccau) + + + TiCDC + + - 修复 changefeed 在 TiKV、TiCDC 节点扩缩容等特殊场景下卡住的问题 [#8174](https://github.com/pingcap/tiflow/issues/8174) @[hicqu](https://github.com/hicqu) + - 修复 redo log 存储路径没做权限预检查的问题 [#6335](https://github.com/pingcap/tiflow/issues/6335) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 修复 redo log 容忍 S3 存储故障的时间过短的问题 [#8089](https://github.com/pingcap/tiflow/issues/8089) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 修复不能通过配置文件修改 `transaction_atomicity` 和 `protocol` 参数的问题 [#7935](https://github.com/pingcap/tiflow/issues/7935) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 修复在同步大量表时 checkpoint 不推进问题 [#8004](https://github.com/pingcap/tiflow/issues/8004) @[overvenus](https://github.com/overvenus) + - 修复当同步的延迟过大时 apply redo log 可能会出现 OOM 的问题 [#8085](https://github.com/pingcap/tiflow/issues/8085) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 修复当开启 redo log 写 meta 时性能下降的问题 [#8074](https://github.com/pingcap/tiflow/issues/8074) @[CharlesCheung96](https://github.com/CharlesCheung96) + - 修复没有配置大事务拆分时,同步数据超过 context deadline 的问题 [#7982](https://github.com/pingcap/tiflow/issues/7982) @[hi-rustin](https://github.com/hi-rustin) + - 修复在 PD 异常时,暂停一个 changefeed 会错误设置状态的问题 [#8330](https://github.com/pingcap/tiflow/issues/8330) @[sdojjy](https://github.com/sdojjy) + - 修复下游为 TiDB 或 MySQL 时,无主键且非空唯一索引所在列指定了 CHARACTER SET 同步时可能会出现数据不一致的问题 [#8420](https://github.com/pingcap/tiflow/issues/8420) @[asddongmen](https://github.com/asddongmen) + - 修复 table scheduling 或 blackhole sink 存在 panic 的问题 [#8024](https://github.com/pingcap/tiflow/issues/8024) [#8142](https://github.com/pingcap/tiflow/issues/8142) @[hicqu](https://github.com/hicqu) + + + TiDB Data Migration (DM) + + - 修复 `binlog-schema delete` 命令执行失败的问题 [#7373](https://github.com/pingcap/tiflow/issues/7373) @[liumengya94](https://github.com/liumengya94) + - 修复当最后一个 binlog 是被 skip 的 DDL 时,checkpoint 不推进的问题 [#8175](https://github.com/pingcap/tiflow/issues/8175) @[D3Hunter](https://github.com/D3Hunter) + - 修复当在某个表上同时指定 `UPDATE` 和非 `UPDATE` 类型的表达式过滤规则 `expression-filter` 时,所有 `UPDATE` 操作被跳过的问题 [#7831](https://github.com/pingcap/tiflow/issues/7831) @[lance6716](https://github.com/lance6716) + + + TiDB Lightning + + - 修复 precheck 检查项有时无法监测到之前的导入失败遗留的脏数据的问题 [#39477](https://github.com/pingcap/tidb/issues/39477) @[dsdashun](https://github.com/dsdashun) + - 修复 TiDB Lightning 在 split-region 阶段发生 panic 的问题 [#40934](https://github.com/pingcap/tidb/issues/40934) @[lance6716](https://github.com/lance6716) + - 修复冲突处理逻辑 (`duplicate-resolution`) 可能导致 checksum 不一致的问题 [#40657](https://github.com/pingcap/tidb/issues/40657) @[gozssky](https://github.com/gozssky) + - 修复在并行导入时,当除最后一个 TiDB Lightning 实例外的其他实例都遇到本地重复记录时,TiDB Lightning 可能会错误地跳过冲突处理的问题 [#40923](https://github.com/pingcap/tidb/issues/40923) @[lichunzhu](https://github.com/lichunzhu) + - 修复了在使用 Local Backend 模式导入数据时,当导入目标表的复合主键中存在 `auto_random` 列,且源数据中没有指定该列的值时,相关列没有自动生成数据的问题 [#41454](https://github.com/pingcap/tidb/issues/41454) @[D3Hunter](https://github.com/D3Hunter) diff --git a/releases/release-6.6.0.md b/releases/release-6.6.0.md index 24948a2c1deb..e5b133e4c5aa 100644 --- a/releases/release-6.6.0.md +++ b/releases/release-6.6.0.md @@ -81,9 +81,9 @@ TiDB 版本:6.6.0-[DMR](/releases/versioning.md#开发里程碑版本) * 支持悲观锁队列的稳定唤醒模型 [#13298](https://github.com/tikv/tikv/issues/13298) @[MyonKeminta](https://github.com/MyonKeminta) - 如果业务场景存在单点悲观锁冲突频繁的情况,原有的唤醒机制无法保证事务获取锁的时间,造成长尾延迟高,甚至获取锁超时。自 v6.6.0 起,你可以通过设置系统变量 [`tidb_pessimistic_txn_aggressive_locking`](/system-variables.md#tidb_pessimistic_txn_aggressive_locking-从-v660-版本开始引入) 为 `ON` 开启悲观锁的稳定唤醒模型。在该唤醒模型下,队列的唤醒顺序可被严格控制,避免无效唤醒造成的资源浪费。在锁冲突严重的场景中,能够减少长尾延时,降低 P99 响应时间。 + 如果业务场景存在单点悲观锁冲突频繁的情况,原有的唤醒机制无法保证事务获取锁的时间,造成长尾延迟高,甚至获取锁超时。自 v6.6.0 起,你可以通过设置系统变量 [`tidb_pessimistic_txn_aggressive_locking`](https://docs.pingcap.com/zh/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-%E4%BB%8E-v660-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5) 为 `ON` 开启悲观锁的稳定唤醒模型。在该唤醒模型下,队列的唤醒顺序可被严格控制,避免无效唤醒造成的资源浪费。在锁冲突严重的场景中,能够减少长尾延时,降低 P99 响应时间。 - 更多信息,请参考[用户文档](/system-variables.md#tidb_pessimistic_txn_aggressive_locking-从-v660-版本开始引入)。 + 更多信息,请参考[用户文档](https://docs.pingcap.com/zh/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-%E4%BB%8E-v660-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5)。 * 批量聚合数据请求 [#39361](https://github.com/pingcap/tidb/issues/39361) @[cfzjywxk](https://github.com/cfzjywxk) @[you06](https://github.com/you06) @@ -360,7 +360,7 @@ TiDB 版本:6.6.0-[DMR](/releases/versioning.md#开发里程碑版本) | [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) | 新增 | 该变量是[资源管控特性](/tidb-resource-control.md)的开关。默认值为 `OFF`。该变量设置为 `ON` 后,集群支持应用按照资源组做资源隔离。 | | [`tidb_historical_stats_duration`](/system-variables.md#tidb_historical_stats_duration-从-v660-版本开始引入) | 新增 | 这个变量用来控制历史统计信息在存储中的保留时间,默认值为 7 天。 | | [`tidb_index_join_double_read_penalty_cost_rate`](/system-variables.md#tidb_index_join_double_read_penalty_cost_rate-从-v660-版本开始引入) | 新增 | 用于控制是否给 index join 增加一些惩罚性代价。默认值为 `0`,即不开启该功能。 | -| [`tidb_pessimistic_txn_aggressive_locking`](/system-variables.md#tidb_pessimistic_txn_aggressive_locking-从-v660-版本开始引入) | 新增 | 是否对悲观锁启用加强的悲观锁唤醒模型。默认值为 `OFF`,表示默认不对悲观锁启用加强的悲观锁唤醒模型。 | +| [`tidb_pessimistic_txn_aggressive_locking`](https://docs.pingcap.com/zh/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-%E4%BB%8E-v660-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5) | 新增 | 是否对悲观锁启用加强的悲观锁唤醒模型。默认值为 `OFF`,表示默认不对悲观锁启用加强的悲观锁唤醒模型。 | | [`tidb_stmt_summary_enable_persistent`](/system-variables.md#tidb_stmt_summary_enable_persistent-从-v660-版本开始引入) | 新增 | 只读变量。表示是否开启 [statement summary tables 持久化](/statement-summary-tables.md#持久化-statements-summary)。该变量的值与配置文件中 [`tidb_stmt_summary_enable_persistent`](/tidb-configuration-file.md#tidb_stmt_summary_enable_persistent-从-v660-版本开始引入) 的取值相同。 | | [`tidb_stmt_summary_filename`](/system-variables.md#tidb_stmt_summary_filename-从-v660-版本开始引入) | 新增 | 只读变量。表示当开启 [statement summary tables 持久化](/statement-summary-tables.md#持久化-statements-summary)后持久化数据所写入的文件。该变量的值与配置文件中 [`tidb_stmt_summary_filename`](/tidb-configuration-file.md#tidb_stmt_summary_filename-从-v660-版本开始引入) 的取值相同。 | | [`tidb_stmt_summary_file_max_backups`](/system-variables.md#tidb_stmt_summary_file_max_backups-从-v660-版本开始引入) | 新增 | 只读变量。表示当开启 [statement summary tables 持久化](/statement-summary-tables.md#持久化-statements-summary)后持久化数据文件的最大数量限制。该变量的值与配置文件中 [`tidb_stmt_summary_file_max_backups`](/tidb-configuration-file.md#tidb_stmt_summary_file_max_backups-从-v660-版本开始引入) 的取值相同。 | diff --git a/releases/release-notes.md b/releases/release-notes.md index b029fa5f500e..dfb2776f845f 100644 --- a/releases/release-notes.md +++ b/releases/release-notes.md @@ -17,6 +17,7 @@ TiDB 历史版本发布声明如下: ## 6.5 +- [6.5.1](/releases/release-6.5.1.md): 2023-03-10 - [6.5.0](/releases/release-6.5.0.md): 2022-12-29 ## 6.4 diff --git a/releases/release-timeline.md b/releases/release-timeline.md index 7aaa0accfd3c..23906465dda9 100644 --- a/releases/release-timeline.md +++ b/releases/release-timeline.md @@ -10,6 +10,7 @@ summary: 了解 TiDB 的版本发布时间线。 | 版本 | 发布日期 | | :--- | :--- | | [7.0.0-DMR](/releases/release-7.0.0.md) | 2023-03-30 | +| [6.5.1](/releases/release-6.5.1.md) | 2023-03-10 | | [6.1.5](/releases/release-6.1.5.md) | 2023-02-28 | | [6.6.0-DMR](/releases/release-6.6.0.md) | 2023-02-20 | | [6.1.4](/releases/release-6.1.4.md) | 2023-02-08 | diff --git a/resources/cdnfresh.txt b/resources/cdnfresh.txt index 94122592a3af..96f3f9d1dc6b 100644 --- a/resources/cdnfresh.txt +++ b/resources/cdnfresh.txt @@ -2,6 +2,8 @@ https://download.pingcap.org/tidb-dev-zh-manual.pdf https://download.pingcap.org/tidb-dev-en-manual.pdf https://download.pingcap.org/tidb-stable-zh-manual.pdf https://download.pingcap.org/tidb-stable-en-manual.pdf +https://download.pingcap.org/tidb-v7.0-zh-manual.pdf +https://download.pingcap.org/tidb-v7.0-en-manual.pdf https://download.pingcap.org/tidb-v6.6-zh-manual.pdf https://download.pingcap.org/tidb-v6.6-en-manual.pdf https://download.pingcap.org/tidb-v6.4-zh-manual.pdf diff --git a/shard-row-id-bits.md b/shard-row-id-bits.md index 3c34a0a2bb37..16f6284b7552 100644 --- a/shard-row-id-bits.md +++ b/shard-row-id-bits.md @@ -10,7 +10,7 @@ aliases: ['/docs-cn/dev/shard-row-id-bits/'] ## 基本概念 -对于非[聚簇索引表](/clustered-indexes.md),TiDB 会使用一个隐式的自增 rowid。大量执行 `INSERT` 插入语句时会把数据集中写入单个 Region,造成写入热点。 +对于非[聚簇索引](/clustered-indexes.md)主键或没有主键的表,TiDB 会使用一个隐式的自增 rowid。大量执行 `INSERT` 插入语句时会把数据集中写入单个 Region,造成写入热点。 通过设置 `SHARD_ROW_ID_BITS`,可以把 rowid 打散写入多个不同的 Region,缓解写入热点问题。 @@ -18,7 +18,16 @@ aliases: ['/docs-cn/dev/shard-row-id-bits/'] - `SHARD_ROW_ID_BITS = 6` 表示 64 个分片 - `SHARD_ROW_ID_BITS = 0` 表示默认值 1 个分片 +关于 `SHARD_ROW_ID_BITS` 的更多使用信息,可参考[使用 SHARD_ROW_ID_BITS 处理热点表](/troubleshoot-hot-spot-issues.md#使用-shard_row_id_bits-处理热点表)。 + ## 语句示例 -- `CREATE TABLE`: `CREATE TABLE t (c int) SHARD_ROW_ID_BITS = 4;` -- `ALTER TABLE`: `ALTER TABLE t SHARD_ROW_ID_BITS = 4;` +```sql +CREATE TABLE t ( + id INT PRIMARY KEY NONCLUSTERED +) SHARD_ROW_ID_BITS = 4; +``` + +```sql +ALTER TABLE t SHARD_ROW_ID_BITS = 4; +``` diff --git a/sql-non-prepared-plan-cache.md b/sql-non-prepared-plan-cache.md new file mode 100644 index 000000000000..0fd0d34a3df7 --- /dev/null +++ b/sql-non-prepared-plan-cache.md @@ -0,0 +1,170 @@ +--- +title: 非 Prepare 语句执行计划缓存 +summary: 介绍 TiDB 中非 Prepare 语句执行计划缓存的原理、使用方法及示例。 +--- + +# 非 Prepare 语句执行计划缓存 + +> **警告:** +> +> 非 Prepare 语句执行计划缓存 (Non-Prepared Plan Cache) 目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 + +对于某些非 `PREPARE` 语句,TiDB 可以像 [`Prepare`/`Execute` 语句](/sql-prepared-plan-cache.md)一样支持执行计划缓存。这可以让这些语句跳过优化器阶段,以提升性能。 + +## 原理 + +Non-Prepared Plan Cache 为会话级别,并且与 [Prepared Plan Cache](/sql-prepared-plan-cache.md) 相互独立,缓存的计划互不影响。Non-Prepared Plan Cache 功能的基本原理如下: + +1. 开启 Non-Prepared Plan Cache 后,TiDB 首先根据 AST(抽象语法树)对查询进行参数化。例如,将 `SELECT * FROM t WHERE b < 10 AND a = 1` 参数化为 `SELECT * FROM t WHERE b < ? and a = ?`。 +2. 然后,使用参数化后的查询在 Non-Prepared Plan Cache 中查找。 +3. 如果能找到可以直接复用的计划,则直接使用,并跳过整个优化过程。 +4. 否则,继续进行查询优化,并在最后将生成的计划放回到缓存中,以便下次复用。 + +## 使用方法 + +目前,你可以通过 [`tidb_enable_non_prepared_plan_cache`](/system-variables.md#tidb_enable_non_prepared_plan_cache) 开启或关闭 Non-Prepared Plan Cache。同时,你还可以通过 [`tidb_non_prepared_plan_cache_size`](/system-variables.md#tidb_non_prepared_plan_cache_size) 来控制 Non-Prepared Plan Cache 的大小。当缓存的计划数超过 `tidb_non_prepared_plan_cache_size` 时,TiDB 会使用 LRU (Least Recently Used) 策略进行逐出。 + +## 示例 + +下面是一个使用示例: + +1. 创建用于测试的表 `t`: + + ```sql + CREATE TABLE t (a INT, b INT, KEY(b)); + ``` + +2. 开启 Non-Prepared Plan Cache: + + ```sql + SET tidb_enable_non_prepared_plan_cache = true; + ``` + +3. 依次执行以下查询: + + ```sql + SELECT * FROM t WHERE b < 10 AND a = 1; + SELECT * FROM t WHERE b < 5 AND a = 2; + ``` + +4. 查看第二个查询语句是否命中缓存: + + ```sql + SELECT @@last_plan_from_cache; + ``` + + 输出结果中 `last_plan_from_cache` 的值为 `1`,表示第二次执行的查询计划来自于缓存: + + ```sql + +------------------------+ + | @@last_plan_from_cache | + +------------------------+ + | 1 | + +------------------------+ + 1 row in set (0.00 sec) + ``` + +## 限制 + +TiDB 对参数化后形式相同的查询,只能缓存一个计划。例如,对于 `SELECT * FROM t WHERE a < 1` 和 `SELECT * FROM t WHERE a < 100000` 这两个查询语句,由于参数化后的形式相同,均为 `SELECT * FROM t WHERE a < ?`,因此它们会共用一个计划。 + +如果由此产生性能问题,可以使用 `ignore_plan_cache()` Hint 忽略计划缓存中的计划,让优化器每次重新为 SQL 生成执行计划。如果无法修改 SQL,可以通过创建 binding 来解决,例如 `CREATE BINDING FOR SELECT ... USING SELECT /*+ ignore_plan_cache() */ ...`。 + +由于上述风险以及执行计划缓存只在简单查询上有明显收益(如果查询较为复杂,查询本身执行时间较长,使用执行计划缓存收益不大),TiDB 目前对 Non-Prepared Plan Cache 的生效范围有严格的限制。具体限制如下: + +- [Prepared Plan Cache](/sql-prepared-plan-cache.md) 不支持的查询或者计划,Non-Prepared Plan Cache 也不支持。 +- 目前仅支持包含 `Scan`、`Selection` 或 `Projection` 算子的单表的点查或范围查询,例如 `SELECT * FROM t WHERE a < 10 AND b in (1, 2)`。 +- 不支持包含 `Agg`、`Limit`、`Window` 或 `Sort` 等复杂算子的查询。 +- 不支持包含非范围查询条件,例如: + - 不支持 `LIKE`,例如 `c LIKE 'c%'` + - 不支持 `+` 操作,例如 `a+1 < 2` +- 不支持过滤条件中包含 `JSON`、`ENUM`、`SET` 或 `BIT` 类型的列的查询,例如 `SELECT * FROM t WHERE json_col = '{}'`。 +- 不支持过滤条件中出现 `NULL` 值的查询,例如 `SELECT * FROM t WHERE a is NULL`。 +- 不支持参数化后参数个数超过 50 个的查询,例如 `SELECT * FROM t WHERE a in (1, 2, 3, ... 51)`。 +- 不支持访问分区表、虚拟列、临时表、视图、或内存表的查询,例如 `SELECT * FROM INFORMATION_SCHEMA.COLUMNS`,其中 `COLUMNS` 为 TiDB 内存表。 +- 不支持带有 Hint、子查询、Lock 的查询。 +- 不支持 DML 语句。 + +## 诊断 + +开启 Non-Prepared Plan Cache 后,可以使用 `EXPLAIN FORMAT='plan_cache' SELECT ...` 语句验证查询是否能够命中缓存。对于无法命中缓存的查询,系统会通过 warning 的方式返回无法命中的原因。 + +需要注意的是,如果不加 `FORMAT='plan_cache'`,则 `EXPLAIN` 语句永远不会命中缓存。 + +执行下面 `EXPLAIN FORMAT='plan_cache'` 语句,查看查询是否能够命中: + +```sql +EXPLAIN FORMAT='plan_cache' SELECT * FROM t WHERE a+2 < 10; +``` + +输出结果示例如下: + +```sql +3 rows in set, 1 warning (0.00 sec) +``` + +通过 `SHOW warnings;` 查看无法命中缓存的查询信息: + +```sql +SHOW warnings; +``` + +输出结果示例如下: + +```sql ++---------+------+-----------------------------------------------------------------------+ +| Level | Code | Message | ++---------+------+-----------------------------------------------------------------------+ +| Warning | 1105 | skip non-prep plan cache: query has some unsupported binary operation | ++---------+------+-----------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +可以看到在上述例子中,由于 Non-Prepared Plan Cache 不支持 `+` 操作,所以无法命中缓存。 + +## 监控 + +开启 Non-Prepared Plan Cache 后,可以在以下几个面板中查看缓存的内存使用情况、缓存中计划的个数、缓存命中的情况等信息。 + +![non-prepared-plan-cache](/media/tidb-non-prepared-plan-cache-metrics.png) + +`statements_summary` 表和慢查询日志也会体现缓存的命中情况。下面是查看 `statements_summary` 表中缓存命中情况的例子: + +1. 创建表 `t`: + + ```sql + CREATE TABLE t (a int); + ``` + +2. 打开 Non-Prepared Plan Cache 开关: + + ```sql + SET @@tidb_enable_non_prepared_plan_cache=1; + ``` + +3. 依次执行以下三个查询: + + ```sql + SELECT * FROM t WHERE a<1; + SELECT * FROM t WHERE a<2; + SELECT * FROM t WHERE a<3; + ``` + +4. 查询 `statements_summary` 表查看查询命中缓存的情况: + + ```sql + SELECT digest_text, query_sample_text, exec_count, plan_in_cache, plan_cache_hits FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY WHERE digest_text LIKE '%SELECT * FROM %'; + ``` + + 输出结果如下: + + ```sql + +---------------------------------+------------------------------------------+------------+---------------+-----------------+ + | digest_text | query_sample_text | exec_count | plan_in_cache | plan_cache_hits | + +---------------------------------+------------------------------------------+------------+---------------+-----------------+ + | SELECT * FROM `t` WHERE `a` < ? | SELECT * FROM t WHERE a<1 [arguments: 1] | 3 | 1 | 2 | + +---------------------------------+------------------------------------------+------------+---------------+-----------------+ + 1 row in set (0.01 sec) + ``` + + 可以看到,查询执行了三次且命中缓存两次。 \ No newline at end of file diff --git a/sql-plan-replayer.md b/sql-plan-replayer.md index bdf33e88820d..bb21b1ea44a8 100644 --- a/sql-plan-replayer.md +++ b/sql-plan-replayer.md @@ -43,7 +43,7 @@ TiDB 根据 `sql-statement` 整理出以下集群现场信息: ```sql use test; create table t(a int, b int); -insert into t values(1,1), (2, 2), (3, 3); +insert into t values(1,1), (2, 2), (3, 3); analyze table t; plan replayer dump explain select * from t; @@ -52,7 +52,7 @@ plan replayer dump explain select * from t; `PLAN REPLAYER DUMP` 会将以上信息打包整理成 `ZIP` 文件,并返回文件标识作为执行结果。该文件为一次性文件,被下载后 TiDB 会将其删除。 > **注意:** -> +> > `ZIP` 文件最多会在 TiDB 集群中保存一个小时,超时后 TiDB 会将其删除。 ```sql @@ -240,5 +240,17 @@ mysql> SELECT * FROM mysql.plan_replayer_status; 下载 `PLAN REPLAYER CAPTURE` 的文件方法与 `PLAN REPLAYER` 相同,请参考 [`PLAN REPLAYER` 导出示例](#plan-replayer-导出示例)。 > **注意:** -> +> > `PLAN REPLAYER CAPTURE` 的结果文件最多会在 TiDB 集群中保存一个小时,超时后 TiDB 会将其删除。 + +## 使用 `PLAN REPLAYER CONTINUOUS CAPTURE` + +开启 `PLAN REPLAYER CONTINUOUS CAPTURE` 功能后,TiDB 将以 SQL DIGEST 和 PLAN DIGEST 为维度异步地将业务 SQL 语句以 `PLAN REPLAYER` 的方式进行记录,对于相同 DIGEST 的 SQL 语句与执行计划,`PLAN REPLAYER CONTINUOUS CAPTURE` 不会重复记录。 + +### 开启 `PLAN REPLAYER CONTINUOUS CAPTURE` + +`PLAN REPLAYER CONTINUOUS CAPTURE` 功能通过系统变量 [`tidb_enable_plan_replayer_continuous_capture`](/system-variables.md#tidb_enable_plan_replayer_continuous_capture-从-v700-版本开始引入) 控制。要开启 `PLAN REPLAYER CONTINUOUS CAPTURE`,将变量值设为 `ON`。 + +### 查看 `PLAN REPLAYER CONTINUOUS CAPTURE` 抓取结果 + +查看 `PLAN REPLAYER CONTINUOUS CAPTURE` 抓取结果的方法同[查看 `PLAN REPLAYER CAPTURE` 抓取结果](#查看-plan-replayer-capture-抓取结果)。 diff --git a/sql-prepared-plan-cache.md b/sql-prepared-plan-cache.md index 6941190f9b29..1d04f263eda5 100644 --- a/sql-prepared-plan-cache.md +++ b/sql-prepared-plan-cache.md @@ -18,7 +18,8 @@ TiDB 优化器对这两类查询的处理是一样的:`Prepare` 时将参数 - `SELECT`、`UPDATE`、`INSERT`、`DELETE`、`Union`、`Intersect`、`Except` 以外的 SQL 语句; - 访问分区表、临时表或访问表中包含生成列的查询; -- 包含子查询的查询,如 `select * from t where a > (select ...)`; +- 查询中包含非关联子查询,例如 `SELECT * FROM t1 WHERE t1.a > (SELECT 1 FROM t2 WHERE t2.b < 1)`; +- 执行计划中带有 `PhysicalApply` 算子的关联子查询,例如 `SELECT * FROM t1 WHERE t1.a > (SELECT a FROM t2 WHERE t1.b > t2.b)`; - 包含 `ignore_plan_cache` 这一 Hint 的查询,例如 `select /*+ ignore_plan_cache() */ * from t`; - 包含除 `?` 外其他变量(即系统变量或用户自定义变量)的查询,例如 `select * from t where a>? and b>@x`; - 查询包含无法被缓存函数。目前不能被缓存的函数有:`database()`、`current_user`、`current_role`、`user`、`connection_id`、`last_insert_id`、`row_count`、`version`、`like`; diff --git a/sql-statements/sql-statement-admin-cleanup.md b/sql-statements/sql-statement-admin-cleanup.md new file mode 100644 index 000000000000..c9a3d7a6645f --- /dev/null +++ b/sql-statements/sql-statement-admin-cleanup.md @@ -0,0 +1,74 @@ +--- +title: ADMIN CLEANUP INDEX +summary: TiDB 数据库中 ADMIN CLEANUP 的使用概况。 +--- + +# ADMIN CLEANUP INDEX + +`ADMIN CLEANUP INDEX` 语句用于在表发生行数据和索引的一致性故障时,删除表中多余的索引,使表的行数据和索引恢复一致状态。注意,该语法尚不支持[外键约束](/foreign-key.md)。 + +## 语法图 + +```ebnf+diagram +AdminCleanupStmt ::= + 'ADMIN' 'CLEANUP' ( 'INDEX' TableName IndexName | 'TABLE' 'LOCK' TableNameList ) + +TableNameList ::= + TableName ( ',' TableName )* +``` + +## 示例 + +假设由于一些原因(例如灾难恢复场景,集群中丢失了部分行数据),数据库中的 `tbl` 表出现数据和索引不一致现象: + +```sql +SELECT * FROM tbl; +ERROR 1105 (HY000): inconsistent index idx handle count 3 isn't equal to value count 2 + +ADMIN CHECK INDEX tbl idx ; +ERROR 1105 (HY000): handle &kv.CommonHandle{encoded:[]uint8{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8}, colEndOffsets:[]uint16{0xa}}, index:types.Datum{k:0x5, decimal:0x0, length:0x0, i:0, collation:"utf8mb4_bin", b:[]uint8{0x0}, x:interface {}(nil)} != record: +``` + +从 `SELECT` 查询的错误信息可以看到,`tbl` 表中包含 2 条行数据和 3 条索引数据,这意味着行数据与索引数据出现了不一致故障,同时至少有 1 条索引处于悬空状态。此时可以使用 `ADMIN CLEANUP INDEX` 语句删除悬空的索引: + +```sql +ADMIN CLEANUP INDEX tbl idx; +``` + +执行结果示例如下: + +```sql +ADMIN CLEANUP INDEX tbl idx; ++---------------+ +| REMOVED_COUNT | ++---------------+ +| 1 | ++---------------+ +``` + +此时,可以重新使用 `ADMIN CHECK INDEX` 语句检查数据索引的一致性,验证数据是否恢复到正常状态: + +```sql +ADMIN CHECK INDEX tbl idx; +Query OK, 0 rows affected (0.01 sec) +``` + +> **注意:** +> +> 当由于副本丢失导致数据索引出现不一致时: +> +> - 通常行数据与索引数据都有丢失,此时需要同时使用 `ADMIN CLEANUP INDEX` 与 [`ADMIN RECOVER INDEX`](/sql-statements/sql-statement-admin-recover.md) 语句保证行数据与索引数据的一致性。 +> - `ADMIN CLEANUP INDEX` 总是单并发执行。在表数据量大时,建议通过重建索引的方式进行索引数据的恢复。 +> - `ADMIN CLEANUP INDEX` 在执行期间,不会为对应的表或索引记录加锁,TiDB 允许其他的会话同时对表记录进行更新或修改。然而,在此情况下,`ADMIN CLEANUP INDEX` 可能无法正确处理所有表记录。因此,在执行 `ADMIN CLEANUP INDEX` 时,请避免同时修改表数据。 +> - 若你使用 TiDB 企业版,此时建议[提交工单](https://support.pingcap.cn/)联系 PingCAP 支持工程师进行处理。 +> +> `ADMIN CLEANUP INDEX` 命令不具有原子性:若该命令在执行期间中断,建议重新执行直到成功。 + +## MySQL 兼容性 + +`ADMIN CLEANUP INDEX` 语句是 TiDB 对 MySQL 语法的扩展。 + +## 另请参阅 + +* [`ADMIN CHECK TABLE/INDEX`](/sql-statements/sql-statement-admin-check-table-index.md) +* [`ADMIN RECOVER INDEX`](/sql-statements/sql-statement-admin-recover.md) diff --git a/sql-statements/sql-statement-admin-recover.md b/sql-statements/sql-statement-admin-recover.md new file mode 100644 index 000000000000..e420d2973f8d --- /dev/null +++ b/sql-statements/sql-statement-admin-recover.md @@ -0,0 +1,72 @@ +--- +title: ADMIN RECOVER INDEX +summary: TiDB 数据库中 ADMIN RECOVER INDEX 的使用概况。 +--- + +# ADMIN RECOVER INDEX + +`ADMIN RECOVER INDEX` 语句用于在表发生行数据和索引的一致性故障时,根据表中多余的索引,使表的行数据和索引重新恢复到一致状态。注意,该语法尚不支持[外键约束](/foreign-key.md)。 + +## 语法图 + +```ebnf+diagram +AdminCleanupStmt ::= + 'ADMIN' 'RECOVER' 'INDEX' TableName IndexName +``` + +## 示例 + +假设由于一些原因(例如灾难恢复场景,集群中丢失了部分索引数据),数据库中的 `tbl` 表出现行数据和索引不一致现象: + +```sql +SELECT * FROM tbl; +ERROR 1105 (HY000): inconsistent index idx handle count 2 isn't equal to value count 3 + +ADMIN CHECK INDEX tbl idx ; +ERROR 1105 (HY000): handle &kv.CommonHandle{encoded:[]uint8{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8}, colEndOffsets:[]uint16{0xa}}, index:types.Datum{k:0x5, decimal:0x0, length:0x0, i:0, collation:"utf8mb4_bin", b:[]uint8{0x0}, x:interface {}(nil)} != record: +``` + +从 `SELECT` 查询的错误信息可以看到,`tbl` 表中包含 3 条行数据和 2 条索引数据,这意味着行数据与索引数据出现了不一致故障,同时至少有 1 条行数据缺少了对应的索引。此时可以使用 `ADMIN RECOVER INDEX` 语句补充缺少的索引: + +```sql +ADMIN RECOVER INDEX tbl idx; +``` + +执行结果示例如下: + +```sql +ADMIN RECOVER INDEX tbl idx; ++-------------+------------+ +| ADDED_COUNT | SCAN_COUNT | ++-------------+------------+ +| 1 | 3 | ++-------------+------------+ +1 row in set (0.00 sec) +``` + +此时,可以重新使用 `ADMIN CHECK INDEX` 语句对数据索引的一致性进行检查,验证数据恢复到正常状态: + +```sql +ADMIN CHECK INDEX tbl idx; +Query OK, 0 rows affected (0.01 sec) +``` + +> **注意:** +> +> 当由于副本丢失导致数据索引出现不一致时: +> +> - 通常行数据与索引数据都有丢失,此时需要同时使用 [`ADMIN CLEANUP INDEX`](/sql-statements/sql-statement-admin-cleanup.md) 与 `ADMIN RECOVER INDEX` 语句保证行数据与索引数据的一致性。 +> - `ADMIN RECOVER INDEX` 总是单并发执行。在表数据量大时,建议通过重建索引的方式进行索引数据的恢复。 +> - `ADMIN RECOVER INDEX` 在执行期间,不会为对应的表或索引记录加锁,这意味着 TiDB 允许同时有其他的会话对表记录进行更新或修改。然而,在此情况下 `ADMIN RECOVER INDEX` 可能无法正确处理所有数据。因此,在执行 `ADMIN RECOVER INDEX` 时,请避免同时修改表数据。 +> - 若你使用 TiDB 企业版,此时建议[提交工单](https://support.pingcap.cn/)联系 PingCAP 支持工程师进行处理。 +> +> `ADMIN RECOVER INDEX` 命令不具有原子性:若该命令在执行期间中断,建议重新执行直到成功。 + +## MySQL 兼容性 + +`ADMIN RECOVER INDEX` 语句是 TiDB 对 MySQL 语法的扩展。 + +## 另请参阅 + +* [`ADMIN CHECK TABLE/INDEX`](/sql-statements/sql-statement-admin-check-table-index.md) +* [`ADMIN CLEANUP INDEX`](/sql-statements/sql-statement-admin-cleanup.md) diff --git a/sql-statements/sql-statement-alter-resource-group.md b/sql-statements/sql-statement-alter-resource-group.md index 2749ae10d8d2..d36ee2f9b735 100644 --- a/sql-statements/sql-statement-alter-resource-group.md +++ b/sql-statements/sql-statement-alter-resource-group.md @@ -26,17 +26,22 @@ ResourceGroupOptionList: DirectResourceGroupOption: "RU_PER_SEC" EqOpt stringLit +| "PRIORITY" EqOpt ResourceGroupPriorityOption | "BURSTABLE" +ResourceGroupPriorityOption: + LOW +| MEDIUM +| HIGH ``` TiDB 支持以下 `DirectResourceGroupOption`, 其中 [Request Unit (RU)](/tidb-resource-control.md#什么是-request-unit-ru) 是 TiDB 对 CPU、IO 等系统资源统一抽象的单位。 | 参数 | 含义 | 举例 | |---------------|--------------|--------------------------------------| -| `RU_PER_SEC` | 每秒 RU 填充的速度 | `RU_PER_SEC = 500` 表示此资源组每秒回填 500 个 RU | - -如果设置了 `BURSTABLE` 属性,TiDB 允许对应的资源组超出配额后使用空余的系统资源。 +| `RU_PER_SEC` | 每秒 RU 填充的速度 | `RU_PER_SEC = 500` 表示此资源组每秒回填 500 个 RU。 | +| `PRIORITY` | 任务在 TiKV 上处理的绝对优先级 | `PRIORITY = HIGH` 表示优先级高。若未指定则默认为 `MEDIUM`。 | +| `BURSTABLE` | 允许对应的资源组超出配额后使用空余的系统资源。 | > **注意:** > @@ -47,28 +52,56 @@ TiDB 支持以下 `DirectResourceGroupOption`, 其中 [Request Unit (RU)](/tidb- 创建一个名为 `rg1` 的资源组,并修改它的属性。 ```sql -mysql> DROP RESOURCE GROUP IF EXISTS rg1; +DROP RESOURCE GROUP IF EXISTS rg1; +``` + +```sql Query OK, 0 rows affected (0.22 sec) -mysql> CREATE RESOURCE GROUP IF NOT EXISTS rg1 - -> RU_PER_SEC = 100 - -> BURSTABLE; +``` + +```sql +CREATE RESOURCE GROUP IF NOT EXISTS rg1 + RU_PER_SEC = 100 + BURSTABLE; +``` + +```sql Query OK, 0 rows affected (0.08 sec) -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; -+------+-------------+-----------+ -| NAME | RU_PER_SEC | BURSTABLE | -+------+-------------+-----------+ -| rg1 | 100 | YES | -+------+-------------+-----------+ +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; +``` + +```sql ++------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++------+------------+----------+-----------+ +| rg1 | 100 | MEDIUM | YES | ++------+------------+----------+-----------+ 1 rows in set (1.30 sec) -mysql> ALTER RESOURCE GROUP rg1 - -> RU_PER_SEC = 200; +``` + +```sql +ALTER RESOURCE GROUP rg1 + RU_PER_SEC = 200 + PRIORITY = LOW; +``` + +```sql Query OK, 0 rows affected (0.08 sec) -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; -+------+-------------+-----------+ -| NAME | RU_PER_SEC | BURSTABLE | -+------+-------------+-----------+ -| rg1 | 200 | NO | -+------+-------------+-----------+ +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; +``` + +```sql ++------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++------+------------+----------+-----------+ +| rg1 | 200 | LOW | NO | ++------+------------+----------+-----------+ 1 rows in set (1.30 sec) ``` diff --git a/sql-statements/sql-statement-alter-table.md b/sql-statements/sql-statement-alter-table.md index 9b8607226c30..37554e679324 100644 --- a/sql-statements/sql-statement-alter-table.md +++ b/sql-statements/sql-statement-alter-table.md @@ -167,7 +167,7 @@ TiDB 中的 `ALTER TABLE` 语法主要存在以下限制: - 使用 `ALTER TABLE` 语句修改一个表的多个模式对象(如列、索引)时: - 不允许在多个更改中指定同一个模式对象。 - - TiDB 根据**执行前**的表结构检查合法性。例如 `ALTER TABLE ADD INDEX i(b), DROP INDEX i;` 会报错,因为表结构中不存在名字为 `i` 的索引。 + - TiDB 根据**执行前**的表结构检查合法性。例如 `ALTER TABLE t ADD COLUMN c1 INT, ADD COLUMN c2 INT AFTER c1;` 会报错,因为表结构中不存在名字为 `c1` 的表。 - TiDB 的执行顺序是从左往右逐个执行更改,该行为在个别场景下和 MySQL 不兼容。 - 不支持主键列上 [Reorg-Data](/sql-statements/sql-statement-modify-column.md#reorg-data-change) 类型的变更。 - 不支持分区表上的列类型变更。 diff --git a/sql-statements/sql-statement-calibrate-resource.md b/sql-statements/sql-statement-calibrate-resource.md new file mode 100644 index 000000000000..d4308da1dfc6 --- /dev/null +++ b/sql-statements/sql-statement-calibrate-resource.md @@ -0,0 +1,30 @@ +--- +title: CALIBRATE RESOURCE +summary: TiDB 数据库中 CALIBRATE RESOURCE 的使用概况。 +--- + +# `CALIBRATE RESOURCE` + +`CALIBRATE RESOURCE` 语句用于预估并输出当前集群的 [`Request Unit (RU)`](/tidb-resource-control.md#什么是-request-unit-ru) 的容量。 + +## 语法图 + +```ebnf+diagram +CalibrateResourceStmt ::= 'CALIBRATE' 'RESOURCE' +``` + +## 示例 + +```sql +CALIBRATE RESOURCE; ++-------+ +| QUOTA | ++-------+ +| 68569 | ++-------+ +1 row in set (0.03 sec) +``` + +> **注意:** +> +> 集群 RU 的容量会随集群的拓扑结构和各个组件软硬件配置的变化而变化,每个集群实际能消耗的 RU 还与实际的负载相关。此预估值仅供参考,可能会与实际的最大值存在偏差。 diff --git a/sql-statements/sql-statement-create-resource-group.md b/sql-statements/sql-statement-create-resource-group.md index b8ecc749e4d0..4235a001cb7a 100644 --- a/sql-statements/sql-statement-create-resource-group.md +++ b/sql-statements/sql-statement-create-resource-group.md @@ -26,8 +26,13 @@ ResourceGroupOptionList: DirectResourceGroupOption: "RU_PER_SEC" EqOpt stringLit +| "PRIORITY" EqOpt ResourceGroupPriorityOption | "BURSTABLE" +ResourceGroupPriorityOption: + LOW +| MEDIUM +| HIGH ``` 资源组的 `ResourceGroupName` 是全局唯一的,不允许重复。 @@ -36,35 +41,58 @@ TiDB 支持以下 `DirectResourceGroupOption`, 其中 [Request Unit (RU)](/tidb- | 参数 | 含义 | 举例 | |---------------|--------------|--------------------------------------| -| `RU_PER_SEC` | 每秒 RU 填充的速度 | `RU_PER_SEC = 500` 表示此资源组每秒回填 500 个 RU | - -如果设置了 `BURSTABLE` 属性,TiDB 允许对应的资源组超出配额后使用空余的系统资源。 +| `RU_PER_SEC` | 每秒 RU 填充的速度 | `RU_PER_SEC = 500` 表示此资源组每秒回填 500 个 RU。 | +| `PRIORITY` | 任务在 TiKV 上处理的绝对优先级 | `PRIORITY = HIGH` 表示优先级高。若未指定,则默认为 `MEDIUM`。 | +| `BURSTABLE` | 允许对应的资源组超出配额后使用空余的系统资源。 | > **注意:** > -> `CREATE RESOURCE GROUP` 语句只能在全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 参数设置为 `ON` 时才能执行。 +> - `CREATE RESOURCE GROUP` 语句只能在全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 设置为 `ON` 时才能执行。 +> - TiDB 集群在初始化时会自动创建 `default` 资源组,其 `RU_PER_SEC` 的默认值为 `UNLIMITED` (等同于 `INT` 类型最大值,即 `2147483647`),且为 `BURSTABLE` 模式。所有未绑定资源组的请求都将自动绑定至此资源组。在新建配置其他资源组时,建议根据实际情况修改 `default` 资源组的配置。 ## 示例 创建 `rg1` 和 `rg2` 两个资源组。 ```sql -mysql> DROP RESOURCE GROUP IF EXISTS rg1; +DROP RESOURCE GROUP IF EXISTS rg1; +``` + +```sql Query OK, 0 rows affected (0.22 sec) -mysql> CREATE RESOURCE GROUP IF NOT EXISTS rg1 - -> RU_PER_SEC = 100 - -> BURSTABLE; +``` + +```sql +CREATE RESOURCE GROUP IF NOT EXISTS rg1 + RU_PER_SEC = 100 + PRIORITY = HIGH + BURSTABLE; +``` + +```sql Query OK, 0 rows affected (0.08 sec) -mysql> CREATE RESOURCE GROUP IF NOT EXISTS rg2 - -> RU_PER_SEC = 200; +``` + +```sql +CREATE RESOURCE GROUP IF NOT EXISTS rg2 + RU_PER_SEC = 200; +``` + +```sql Query OK, 0 rows affected (0.08 sec) -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1' or NAME = 'rg2'; -+------+-------------+-----------+ -| NAME | RU_PER_SEC | BURSTABLE | -+------+-------------+-----------+ -| rg1 | 100 | YES | -| rg2 | 200 | NO | -+------+-------------+-----------+ +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1' or NAME = 'rg2'; +``` + +```sql ++------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++------+------------+----------+-----------+ +| rg1 | 100 | HIGH | YES | +| rg2 | 200 | MEDIUM | NO | ++------+------------+----------+-----------+ 2 rows in set (1.30 sec) ``` diff --git a/sql-statements/sql-statement-drop-resource-group.md b/sql-statements/sql-statement-drop-resource-group.md index 07f70cc69d16..b562f4ba86ca 100644 --- a/sql-statements/sql-statement-drop-resource-group.md +++ b/sql-statements/sql-statement-drop-resource-group.md @@ -22,29 +22,55 @@ ResourceGroupName: > **注意:** > -> `DROP RESOURCE GROUP` 语句只能在全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 参数设置为 `ON` 时才能执行。 +> - `DROP RESOURCE GROUP` 语句只能在全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 设置为 `ON` 时才能执行。 +> - `default` 资源组为系统保留的资源组,不支持删除。 ## 示例 删除名为 `rg1` 的资源组: ```sql -mysql> DROP RESOURCE GROUP IF EXISTS rg1; +DROP RESOURCE GROUP IF EXISTS rg1; +``` + +```sql Query OK, 0 rows affected (0.22 sec) -mysql> CREATE RESOURCE GROUP IF NOT EXISTS rg1 RU_PER_SEC = 500 BURSTABLE; +``` + +```sql +CREATE RESOURCE GROUP IF NOT EXISTS rg1 RU_PER_SEC = 500 BURSTABLE; +``` + +```sql Query OK, 0 rows affected (0.08 sec) -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; -+------+------------+-----------+ -| NAME | RU_PER_SEC | BURSTABLE | -+------+------------+-----------+ -| rg1 | 500 | YES | -+------+------------+-----------+ +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; +``` + +```sql ++------+------------+----------+-----------+ +| NAME | RU_PER_SEC | PRIORITY | BURSTABLE | ++------+------------+----------+-----------+ +| rg1 | 500 | MEDIUM | YES | ++------+------------+----------+-----------+ 1 row in set (0.01 sec) +``` + +```sql +DROP RESOURCE GROUP IF EXISTS rg1; +``` -mysql> DROP RESOURCE GROUP IF EXISTS rg1; +```sql Query OK, 1 rows affected (0.09 sec) +``` + +```sql +SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; +``` -mysql> SELECT * FROM information_schema.resource_groups WHERE NAME ='rg1'; +```sql Empty set (0.00 sec) ``` diff --git a/sql-statements/sql-statement-load-data.md b/sql-statements/sql-statement-load-data.md index 0a3962c69aa6..d9797e1b6910 100644 --- a/sql-statements/sql-statement-load-data.md +++ b/sql-statements/sql-statement-load-data.md @@ -12,14 +12,65 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-load-data/','/docs-cn/dev/r ```ebnf+diagram LoadDataStmt ::= - 'LOAD' 'DATA' LocalOpt 'INFILE' stringLit DuplicateOpt 'INTO' 'TABLE' TableName CharsetOpt Fields Lines IgnoreLines ColumnNameOrUserVarListOptWithBrackets LoadDataSetSpecOpt + 'LOAD' 'DATA' LocalOpt 'INFILE' stringLit FormatOpt DuplicateOpt 'INTO' 'TABLE' TableName CharsetOpt Fields Lines IgnoreLines ColumnNameOrUserVarListOptWithBrackets LoadDataSetSpecOpt LoadDataOptionListOpt + +LocalOpt ::= ('LOCAL')? + +FormatOpt ::= + ('FORMAT' ('DELIMITED DATA' | 'SQL FILE' | 'PARQUET'))? + +Fields ::= + ('TERMINATED' 'BY' stringLit + | ('OPTIONALLY')? 'ENCLOSED' 'BY' stringLit + | 'ESCAPED' 'BY' stringLit + | 'DEFINED' 'NULL' 'BY' stringLit ('OPTIONALLY' 'ENCLOSED')?)? + +LoadDataOptionListOpt ::= + ('WITH' (LoadDataOption (',' LoadDataOption)*))? + +LoadDataOption ::= + detached | batch_size '=' numberLiteral ``` ## 参数说明 -用户可以使用 `LocalOpt` 参数来指定导入的数据文件位于客户端或者服务端。目前 TiDB 只支持从客户端进行数据导入,因此在导入数据时 `LocalOpt` 应设置成 `Local`。 +### `LOCAL` + +你可以使用 `LOCAL` 来指定导入位于客户端的数据文件,此时传入文件参数必须为客户端文件系统路径。 + +### S3/GCS 路径 + +如果你不指定 `LOCAL`,则文件参数必须是有效的 S3/GCS URI 路径,详见[外部存储](/br/backup-and-restore-storages.md)。 + +当数据文件存储在 S3/GCS 上时,你可以导入单个文件,也可使用通配符 `*` 来匹配需要导入的多个文件。注意通配符不会递归处理子目录下相关的文件。以数据存储在 S3 为例,示例如下: + +- 导入单个文件:`s3:///path/to/data/foo.csv` +- 导入指定路径下的所有文件:`s3:///path/to/data/*` +- 导入指定路径下的所有以 `.csv` 结尾的文件:`s3:///path/to/data/*.csv` +- 导入指定路径下所有以 `foo` 为前缀的文件:`s3:///path/to/data/foo*` +- 导入指定路径下以 `foo` 为前缀、以 `.csv` 结尾的文件:`s3:///path/to/data/foo*.csv` + +### `FORMAT` + +你可以通过 `FORMAT` 参数来指定数据文件的格式。如果不指定该参数,需要使用的格式为 `DELIMITED DATA`,该格式即 MySQL `LOAD DATA` 支持的数据格式。 + +### `Fields`、`Lines`、`Ignore Lines` + +只有数据格式是 `DELIMITED DATA` 时,才能指定 `Fields`、`Lines`、`Ignore Lines` 等语句。 + +你可以使用 `Fields` 和 `Lines` 参数来指定如何处理数据格式: + +- 使用 `FIELDS TERMINATED BY` 来指定数据的分隔符号。 +- 使用 `FIELDS ENCLOSED BY` 来指定数据的包围符号。 +- 如果你希望以某个字符为结尾来切分行数据,可以使用 `LINES TERMINATED BY` 来指定行的终止符。 + +可以使用 `DEFINED NULL BY` 来指定数据文件中如何表示 NULL 值。 -用户可以使用 `Fields` 和 `Lines` 参数来指定如何处理数据格式,使用 `FIELDS TERMINATED BY` 来指定每个数据的分隔符号,使用 `FIELDS ENCLOSED BY` 来指定消除数据的包围符号。如果用户希望以某个字符为结尾切分每行数据,可以使用 `LINES TERMINATED BY` 来指定行的终止符。 +- 与 MySQL 行为一致,如果 `ESCAPED BY` 不为空时,例如是默认值 `\`,那么 `\N` 会被认为是 NULL 值。 +- 如果使用 `DEFINED NULL BY`,例如 `DEFINED NULL BY 'my-null'`,`my-null` 会被认为是 NULL 值。 +- 如果使用 `DEFINED NULL BY ... OPTIONALLY ENCLOSED`,例如 `DEFINED NULL BY 'my-null' OPTIONALLY ENCLOSED`,`my-null` 和 `"my-null"`(假设 `ENCLOSED BY '"'`)会被认为是 NULL 值。 +- 如果没有使用 `DEFINED NULL BY` 或者 `DEFINED NULL BY ... OPTIONALLY ENCLOSED`,但使用了 `ENCLOSED BY`,例如 `ENCLOSED BY '"'`,那么 `NULL` 会被认为是 NULL 值。这个行为与 MySQL 一致。 +- 其他情况不会被认为是 NULL 值。 例如对于以下格式的数据: @@ -34,59 +85,70 @@ LoadDataStmt ::= FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' ``` -如果不指定处理数据的参数,将会按以下参数处理 +当数据格式为 `DELIMITED DATA` 且不指定处理数据的参数时,将按以下参数处理: ```sql -FIELDS TERMINATED BY '\t' ENCLOSED BY '' -LINES TERMINATED BY '\n' +FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' +LINES TERMINATED BY '\n' STARTING BY '' ``` -用户可以通过 `IGNORE number LINES` 参数来忽略文件开始的 `number` 行,例如可以使用 `IGNORE 1 LINES` 来忽略文件的首行。 +你可以通过 `IGNORE LINES` 参数来忽略文件开始的 `` 行。例如,可以使用 `IGNORE 1 LINES` 来忽略文件的第一行。 + +### `WITH detached` + +如果你指定了 S3/GCS 路径(且未指定 `LOCAL` 参数),可以通过 `WITH detached` 来让 `LOAD DATA` 任务在后台运行。此时 `LOAD DATA` 会返回 job ID。 + +可以通过 [`SHOW LOAD DATA`](/sql-statements/sql-statement-show-load-data.md) 查看创建的 job,也可以使用 [`CANCEL LOAD DATA` 和 `DROP LOAD DATA`](/sql-statements/sql-statement-operate-load-data-job.md) 取消或删除创建的 job。 + +### `WITH batch_size=` + +可以通过 `WITH batch_size=` 来指定批量写入 TiDB 时的行数,默认值为 `1000`。如果不希望分批写入,可以指定为 `0`。 ## 示例 -{{< copyable "sql" >}} +后台运行 job,执行后会输出对应的 job id: ```sql -CREATE TABLE trips ( - trip_id bigint NOT NULL PRIMARY KEY AUTO_INCREMENT, - duration integer not null, - start_date datetime, - end_date datetime, - start_station_number integer, - start_station varchar(255), - end_station_number integer, - end_station varchar(255), - bike_number varchar(255), - member_type varchar(255) - ); +LOAD DATA INFILE 's3://bucket-name/test.csv?access_key=XXX&secret_access_key=XXX' INTO TABLE my_db.my_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\n' WITH detached; ``` -``` -Query OK, 0 rows affected (0.14 sec) +```sql ++--------+ +| Job_ID | ++--------+ +| 150063 | ++--------+ +1 row in set (3.14 sec) ``` -通过 `LOAD DATA` 导入数据,指定数据的分隔符为逗号,忽略包围数据的引号,并且忽略文件的第一行数据。 +```sql +SHOW LOAD DATA JOB 1; +``` -如果此时遇到 `ERROR 1148 (42000): the used command is not allowed with this TiDB version` 报错信息。可以参考以下文档解决: +```sql ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| Job_ID | Create_Time | Start_Time | End_Time | Data_Source | Target_Table | Import_Mode | Created_By | Job_State | Job_Status | Source_File_Size | Loaded_File_Size | Result_Code | Result_Message | ++--------+----------------------------+----------------------------+---------------------+---------------------------+-------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| 1 | 2023-03-16 22:29:12.990576 | 2023-03-16 22:29:12.991951 | 0000-00-00 00:00:00 | s3://bucket-name/test.csv | `my_db`.`my_table` | logical | root@% | loading | running | 52.43MB | 43.58MB | | | ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +1 row in set (0.01 sec) +``` -[ERROR 1148 (42000): the used command is not allowed with this TiDB version 问题的处理方法](/error-codes.md#mysql-原生报错汇总) +通过 `LOAD DATA` 导入数据,指定数据的分隔符为逗号,忽略包围数据的引号,并且忽略文件的第一行数据。 -{{< copyable "sql" >}} +如果此时遇到 `ERROR 1148 (42000): the used command is not allowed with this TiDB version` 报错信息。可以参考文档解决:[ERROR 1148 (42000): the used command is not allowed with this TiDB version 问题的处理方法](/error-codes.md#mysql-原生报错汇总) ```sql LOAD DATA LOCAL INFILE '/mnt/evo970/data-sets/bikeshare-data/2017Q4-capitalbikeshare-tripdata.csv' INTO TABLE trips FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES (duration, start_date, end_date, start_station_number, start_station, end_station_number, end_station, bike_number, member_type); ``` -``` +```sql Query OK, 815264 rows affected (39.63 sec) Records: 815264 Deleted: 0 Skipped: 0 Warnings: 0 ``` `LOAD DATA` 也支持使用十六进制 ASCII 字符表达式或二进制 ASCII 字符表达式作为 `FIELDS ENCLOSED BY` 和 `FIELDS TERMINATED BY` 的参数。示例如下: -{{< copyable "sql" >}} - ```sql LOAD DATA LOCAL INFILE '/mnt/evo970/data-sets/bikeshare-data/2017Q4-capitalbikeshare-tripdata.csv' INTO TABLE trips FIELDS TERMINATED BY x'2c' ENCLOSED BY b'100010' LINES TERMINATED BY '\r\n' IGNORE 1 LINES (duration, start_date, end_date, start_station_number, start_station, end_station_number, end_station, bike_number, member_type); ``` @@ -99,12 +161,15 @@ TiDB 中的 `LOAD DATA` 语句应该完全兼容 MySQL(除字符集选项被 > **注意:** > -> 在 TiDB 的早期版本中,`LOAD DATA` 语句每 20000 行进行一次提交。新版本的 TiDB 默认在一个事务中提交所有行。从 TiDB 4.0 及以前版本升级后,可能出现 `ERROR 8004 (HY000) at line 1: Transaction is too large, size: 100000058` 错误。 -> -> 要解决该问题,建议调大 `tidb.toml` 文件中的 `txn-total-size-limit` 值。如果无法增加此限制,还可以将 [`tidb_dml_batch_size`](/system-variables.md#tidb_dml_batch_size) 的值设置为 `20000` 来恢复升级前的行为。 +> - 在 TiDB v4.0.0 之前的版本中,`LOAD DATA` 语句每 20000 行进行一次提交。 +> - 从 TiDB v4.0.0 开始一直到 TiDB v6.6.0 的版本,TiDB 默认在一个事务中提交所有行。 +> - 从 TiDB v7.0.0 开始,批量提交的行数由 `LOAD DATA` 语句的 `WITH batch_size=` 参数控制,默认 1000 行提交一次。 +> - 从 TiDB v4.0.0 及以前版本升级后,可能出现 `ERROR 8004 (HY000) at line 1: Transaction is too large, size: 100000058` 错误。要解决该问题,建议调大 `tidb.toml` 文件中的 [`txn-total-size-limit`](/tidb-configuration-file.md#txn-total-size-limit) 值。如果无法增加此限制,还可以将 [`tidb_dml_batch_size`](/system-variables.md#tidb_dml_batch_size) 的值设置为 `20000` 来恢复升级前的行为。 ## 另请参阅 * [INSERT](/sql-statements/sql-statement-insert.md) * [乐观事务模型](/optimistic-transaction.md) * [TiDB Lightning](/tidb-lightning/tidb-lightning-overview.md) +* [`SHOW LOAD DATA`](/sql-statements/sql-statement-show-load-data.md) +* [`CANCEL LOAD DATA` 和 `DROP LOAD DATA`](/sql-statements/sql-statement-operate-load-data-job.md) diff --git a/sql-statements/sql-statement-lock-tables-and-unlock-tables.md b/sql-statements/sql-statement-lock-tables-and-unlock-tables.md new file mode 100644 index 000000000000..9b4bf4da747c --- /dev/null +++ b/sql-statements/sql-statement-lock-tables-and-unlock-tables.md @@ -0,0 +1,107 @@ +--- +title: LOCK TABLES 和 UNLOCK TABLES +summary: TiDB 数据库中 LOCK TABLES 和 UNLOCK TABLES 的使用概况。 +--- + +# LOCK TABLES 和 UNLOCK TABLES + +> **警告:** +> +> `LOCK TABLES` 和 `UNLOCK TABLES` 目前为实验特性,不建议在生产环境中使用。 + +客户端会话可以使用 `LOCK TABLES` 语句获取表锁,以便和其他会话合作访问表,或者防止其他会话修改表。会话只能为自己获取或释放锁。一个会话无法为另一个会话获取表锁或释放另一个会话持有的表锁。 + +`LOCK TABLES` 可以为当前客户端会话获取表锁。你可以获取普通表的表锁,但你必须拥有锁定对象的 `LOCK TABLES` 和 `SELECT` 权限。 + +`UNLOCK TABLES` 显式释放当前会话持有的所有表锁。`LOCK TABLES` 在获取新锁之前会隐式释放当前会话持有的所有表锁。 + +表锁可以防止其他会话的读取或写入。持有 `WRITE` 锁的会话可以执行表级操作,例如 `DROP TABLE` 或 `TRUNCATE TABLE`。 + +> **警告:** +> +> 开启表锁功能需要在所有 TiDB 实例的配置文件中设置 [`enable-table-lock`](/tidb-configuration-file.md#enable-table-lock-从-v400-版本开始引入) 为 `true`。 + +## 语法图 + +```ebnf+diagram +LockTablesDef + ::= 'LOCK' ( 'TABLES' | 'TABLE' ) TableName LockType ( ',' TableName LockType)* + + +UnlockTablesDef + ::= 'UNLOCK' 'TABLES' + +LockType + ::= 'READ' ('LOCAL')? + | 'WRITE' ('LOCAL')? +``` + +## 获取表锁 + +你可以在会话中使用 `LOCK TABLES` 语句获取表锁。表锁有以下类型: + +`READ` 锁: + +- 持有 `READ` 锁的会话可以读表,但不能写入。 +- 多个会话可以同时获取同一个表的 `READ` 锁。 +- 其他会话可以在不显式获取 `READ` 锁的情况下读表。 + +`READ LOCAL` 锁只是语法兼容 MySQL,实际上并不支持。 + +`WRITE` 锁: + +- 持有 `WRITE` 锁的会话可以读取和写入表。 +- 只有持有 `WRITE` 锁的会话才能访问该表。在释放锁之前,其他会话不能读取或写入该表。 + +`WRITE LOCAL` 锁: + +- 持有 `WRITE LOCAL` 锁的会话可以读取和写入表。 +- 只有持有 `WRITE LOCAL` 锁的会话才能写入该表,但其他会话依然可以读取该表的数据。 + +如果 `LOCK TABLES` 语句想要获取的表锁被其他会话持有且必须等待锁释放时,则 `LOCK TABLES` 语句会执行报错,例如: + +```sql +> LOCK TABLES t1 read; +ERROR 8020 (HY000): Table 't1' was locked in WRITE by server: f4799bcb-cad7-4285-8a6d-23d3555173f1_session: 2199023255959 +``` + +以上错误信息表明,在 TiDB `f4799bcb-cad7-4285-8a6d-23d3555173f1` 中,ID 为 `2199023255959` 的会话已经持有表 `t1` 的 `WRITE` 锁,所以,当前会话无法获取表 `t1` 的 `READ` 锁。 + +不能在单个 `LOCK TABLES` 语句中多次获取同一个表的锁。 + +```sql +> LOCK TABLES t WRITE, t READ; +ERROR 1066 (42000): Not unique table/alias: 't' +``` + +## 释放表锁 + +释放会话持有的表锁时,将同时释放该会话所有持有的表锁。会话可以显式或隐式释放表锁: + +- 会话可以使用 `UNLOCK TABLES` 语句显式释放其持有的所有表锁。 +- 当会话使用 `LOCK TABLES` 语句来获取表锁,而且同时已经持有其他表锁时,则在获取新表锁之前,将隐式释放其已经持有的所有表锁。 + +当客户端会话的连接终止(无论是正常还是异常),TiDB 都会隐式释放会话持有的所有表锁。如果客户端重新连接,锁将不再有效。因此,通常不建议在客户端使用自动重新连接,因为在开启自动重新连接时,如果发生重新连接,任何表锁或当前事务都将丢失,而且不会通知客户端。禁用自动重新连接后,如果连接断开,则客户端会话发出的下一条语句将会收到报错信息。客户端可以检测到错误并采取适当的操作,例如重新获取锁或重做事务。 + +## 表锁的使用限制和条件 + +你可以安全地使用 `KILL` 语句终止已经持有表锁的会话。 + +不支持获取以下数据库中表的表锁: + +- `INFORMATION_SCHEMA` +- `PERFORMANCE_SCHEMA` +- `METRICS_SCHEMA` +- `mysql` + +## 和 MySQL 的兼容性 + +### 获取表锁 + +- 在 TiDB 中,如果会话 A 已经持有了一个表的表锁,另一个会话 B 对该表写入时会报错;但 MySQL 会阻塞会话 B 对该表的写入,直到会话 A 释放该表锁。其他会话对该表的锁请求会被阻塞直到当前会话释放 `WRITE` 锁。 +- 在 TiDB 中,如果 `LOCK TABLES` 语句想要获取的表锁被其他会话持有且必须等待锁释放时,`LOCK TABLES` 语句会执行报错;但 MySQL 会阻塞 `LOCK TABLES` 语句的执行,直到成功获取想要的表锁。 +- 在 TiDB 中,使用 `LOCK TABLES` 语句获取表锁的作用域是整个集群;但 MySQL 中表锁的作用域是单个 MySQL 服务器,与 NDB 群集不兼容。 + +### 释放表锁 + +在 TiDB 的会话中显示开启一个事务时(例如使用 `BEGIN` 语句),TiDB 不会隐式释放当前会话已经持有的表锁;但 MySQL 会隐式释放当前会话已经持有的表锁。 diff --git a/sql-statements/sql-statement-operate-load-data-job.md b/sql-statements/sql-statement-operate-load-data-job.md new file mode 100644 index 000000000000..d3d061586718 --- /dev/null +++ b/sql-statements/sql-statement-operate-load-data-job.md @@ -0,0 +1,47 @@ +--- +title: CANCEL LOAD DATA 和 DROP LOAD DATA +summary: TiDB 数据库中 CANCEL LOAD DATA 和 DROP LOAD DATA 的使用概况。 +--- + +# CANCEL LOAD DATA 和 DROP LOAD DATA + +`CANCEL LOAD DATA` 语句用于取消系统中创建的 LOAD DATA 任务。 + +`DROP LOAD DATA` 语句用于删除系统中创建的 LOAD DATA 任务。 + +## 语法图 + +```ebnf+diagram +CancelLoadDataJobsStmt ::= + 'CANCEL' 'LAOD' 'DATA' 'JOB' JobID + +DropLoadDataJobsStmt ::= + 'DROP' 'LAOD' 'DATA' 'JOB' JobID +``` + +## 示例 + +```sql +CANCEL LOAD DATA JOB 1; +``` + +``` +Query OK, 0 rows affected (0.01 sec) +``` + +```sql +DROP LOAD DATA JOB 1; +``` + +``` +Query OK, 1 row affected (0.01 sec) +``` + +## MySQL 兼容性 + +该语句是 TiDB 对 MySQL 语法的扩展。 + +## 另请参阅 + +* [LOAD DATA](/sql-statements/sql-statement-load-data.md) +* [SHOW LOAD DATA](/sql-statements/sql-statement-show-load-data.md) diff --git a/sql-statements/sql-statement-set-resource-group.md b/sql-statements/sql-statement-set-resource-group.md new file mode 100644 index 000000000000..d6db0dcdad4f --- /dev/null +++ b/sql-statements/sql-statement-set-resource-group.md @@ -0,0 +1,88 @@ +--- +title: SET RESOURCE GROUP +summary: TiDB 数据库中 SET RESOURCE GROUP 的使用概况。 +--- + +# SET RESOURCE GROUP + +`SET RESOURCE GROUP` 用于设置当前会话使用的资源组。 + +## 语法图 + +**SetResourceGroupStmt:** + +```ebnf+diagram +SetResourceGroupStmt: + "SET" "RESOURCE" "GROUP" ResourceGroupName + +ResourceGroupName: + Identifier +``` + +## 示例 + +创建一个用户 `user1`,创建两个资源组 `rg1` 和 `rg2`,并将用户 `user1` 绑定资源组 `rg1`。 + +```sql +CREATE USER 'user1'; +CREATE RESOURCE GROUP 'rg1' RU_PER_SEC = 1000; +ALTER USER 'user1' RESOURCE GROUP `rg1`; +``` + +使用 `user1` 登录,查看当前用户绑定的资源组。 + +```sql +SELECT CURRENT_RESOURCE_GROUP(); +``` + +```sql ++--------------------------+ +| CURRENT_RESOURCE_GROUP() | ++--------------------------+ +| rg1 | ++--------------------------+ +1 row in set (0.00 sec) +``` + +执行 `SET RESOURCE GROUP` 将当前会话的资源组设置为 `rg2`。 + +```sql +SET RESOURCE GROUP `rg2`; +SELECT CURRENT_RESOURCE_GROUP(); +``` + +```sql ++--------------------------+ +| CURRENT_RESOURCE_GROUP() | ++--------------------------+ +| rg2 | ++--------------------------+ +1 row in set (0.00 sec) +``` + +执行 `SET RESOURCE GROUP` 设置当前会话使用默认资源组。 + +```sql +SET RESOURCE GROUP ``; +SELECT CURRENT_RESOURCE_GROUP(); +``` + +```sql ++--------------------------+ +| CURRENT_RESOURCE_GROUP() | ++--------------------------+ +| default | ++--------------------------+ +1 row in set (0.00 sec) +``` + +## MySQL 兼容性 + +MySQL 也支持 [SET RESOURCE GROUP](https://dev.mysql.com/doc/refman/8.0/en/set-resource-group.html),但是接受的参数和 TiDB 不同,两者并不兼容。 + +## 另请参阅 + +* [CREATE RESOURCE GROUP](/sql-statements/sql-statement-create-resource-group.md) +* [DROP RESOURCE GROUP](/sql-statements/sql-statement-drop-resource-group.md) +* [ALTER RESOURCE GROUP](/sql-statements/sql-statement-alter-resource-group.md) +* [使用资源管控 (Resource Control) 实现资源隔离](/tidb-resource-control.md) diff --git a/sql-statements/sql-statement-show-config.md b/sql-statements/sql-statement-show-config.md index da64b7f2e563..ffd4c3bc34dd 100644 --- a/sql-statements/sql-statement-show-config.md +++ b/sql-statements/sql-statement-show-config.md @@ -6,10 +6,6 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-show-config/'] # SHOW CONFIG -> **警告:** -> -> 当前该功能为实验特性,不建议在生产环境中使用。 - `SHOW CONFIG` 语句用于展示 TiDB 各个组件当前正在应用的配置,请注意,配置与系统变量作用于不同维度,请不要混淆,如果希望获取系统变量信息,请使用 [SHOW VARIABLES](/sql-statements/sql-statement-show-variables.md) 语法。 ## 语法图 diff --git a/sql-statements/sql-statement-show-create-resource-group.md b/sql-statements/sql-statement-show-create-resource-group.md index 683f9f1553e0..814288a2ff7c 100644 --- a/sql-statements/sql-statement-show-create-resource-group.md +++ b/sql-statements/sql-statement-show-create-resource-group.md @@ -29,11 +29,11 @@ Query OK, 0 rows affected (0.10 sec) ```sql SHOW CREATE RESOURCE GROUP rg1; ***************************[ 1. row ]*************************** -+----------------+--------------------------------------------+ -| Resource_Group | Create Resource Group | -+----------------+--------------------------------------------+ -| rg1 | CREATE RESOURCE GROUP `rg1` RU_PER_SEC=100 | -+----------------+--------------------------------------------+ ++----------------+------------------------------------------------------------+ +| Resource_Group | Create Resource Group | ++----------------+------------------------------------------------------------+ +| rg1 | CREATE RESOURCE GROUP `rg1` RU_PER_SEC=100 PRIORITY=MEDIUM | ++----------------+------------------------------------------------------------+ 1 row in set (0.01 sec) ``` diff --git a/sql-statements/sql-statement-show-load-data.md b/sql-statements/sql-statement-show-load-data.md new file mode 100644 index 000000000000..7e19ec61ff6b --- /dev/null +++ b/sql-statements/sql-statement-show-load-data.md @@ -0,0 +1,74 @@ +--- +title: SHOW LOAD DATA +summary: TiDB 数据库中 SHOW LOAD DATA 的使用概况。 +--- + +# SHOW LOAD DATA + +`SHOW LOAD DATA` 语句用于显示系统中创建的 LOAD DATA 任务。该语句只能显示由当前用户创建的任务。 + +## 语法图 + +```ebnf+diagram +ShowLoadDataJobsStmt ::= + 'SHOW' 'LAOD' 'DATA' 'JOBS' + +ShowLoadDataJobStmt ::= + 'SHOW' 'LAOD' 'DATA' 'JOB' JobID +``` + +`SHOW LOAD DATA` 语句显示的字段含义如下: + +| 列名 | 说明 | +|------------------|-------------------------| +| Job_ID | 任务 ID | +| Create_Time | 任务创建时间 | +| Start_Time | 任务启动时间 | +| End_Time | 任务结束时间 | +| Data_Source | 数据源信息 | +| Target_Table | 目标表 | +| Import_Mode | 导入模式,目前该字段只能取值 `logical` | +| Created_By | 创建该任务的数据库用户名 | +| Job_State | 表示任务当前所处的阶段,对于 `logical` 模式的任务,只有 `loading` 这一个阶段 | +| Job_Status | 表示当前任务的状态。有以下几种状态:`pending` 表示任务已创建但还未开始运行;`running` 表示运行中;`canceled` 表示已经取消的任务;`failed` 表示任务失败并退出;`finished` 表示任务已完成。 | +| Source_File_Size | 源文件大小 | +| Loaded_File_Size | 已经读到并写入目标表的数据量大小 | +| Result_Code | 任务状态为 `finished` 时,其值为 `0`。任务状态为 `failed` 时,其值为对应的错误码。 | +| Result_Message | 如果导入成功,则返回摘要信息。如果导入失败,则返回错误信息。 | + +## 示例 + +```sql +SHOW LOAD DATA JOBS; +``` + +``` ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| Job_ID | Create_Time | Start_Time | End_Time | Data_Source | Target_Table | Import_Mode | Created_By | Job_State | Job_Status | Source_File_Size | Loaded_File_Size | Result_Code | Result_Message | ++--------+----------------------------+----------------------------+---------------------+---------------------------+-------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| 1 | 2023-03-16 22:29:12.990576 | 2023-03-16 22:29:12.991951 | 0000-00-00 00:00:00 | s3://bucket-name/test.csv | `my_db`.`my_table` | logical | root@% | loading | running | 52.43MB | 43.58MB | | | ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +1 row in set (0.01 sec) +``` + +```sql +SHOW LOAD DATA JOB 1; +``` + +``` ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| Job_ID | Create_Time | Start_Time | End_Time | Data_Source | Target_Table | Import_Mode | Created_By | Job_State | Job_Status | Source_File_Size | Loaded_File_Size | Result_Code | Result_Message | ++--------+----------------------------+----------------------------+---------------------+---------------------------+-------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +| 1 | 2023-03-16 22:29:12.990576 | 2023-03-16 22:29:12.991951 | 0000-00-00 00:00:00 | s3://bucket-name/test.csv | `my_db`.`my_table` | logical | root@% | loading | running | 52.43MB | 43.58MB | | | ++--------+----------------------------+----------------------------+---------------------+---------------------------+--------------------+-------------+------------+-----------+------------+------------------+------------------+-------------+----------------+ +1 row in set (0.01 sec) +``` + +## MySQL 兼容性 + +该语句是 TiDB 对 MySQL 语法的扩展。 + +## 另请参阅 + +* [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) +* [`CANCEL LOAD DATA` 和 `DROP LOAD DATA`](/sql-statements/sql-statement-operate-load-data-job.md) diff --git a/stale-read.md b/stale-read.md index d5f68873871c..e2dcb903b303 100644 --- a/stale-read.md +++ b/stale-read.md @@ -25,6 +25,21 @@ TiDB 提供语句级别、会话级别以及全局级别的 Stale Read 使用方 除此以外,你也可以通过设置系统变量 [`tidb_external_ts`](/system-variables.md#tidb_external_ts-从-v640-版本开始引入) 来在某一会话或全局范围读取某一时间点前的历史数据。要使用该方式,请参阅[通过系统变量 `tidb_external_ts` 读取历史数据](/tidb-external-ts.md)。 +### 减少 Stale Read 延时 + +Stale Read 功能会定期推进 TiDB 集群的 Resolved TS 时间戳,该时间戳能保证 TiDB 读到满足事务一致性的数据。当 Stale Read 使用的时间戳(比如 `AS OF TIMESTAMP '2016-10-08 16:45:26'`)大于 Resolved TS 时,Stale Read 会先触发 TiDB 推进 Resolved TS,等待推进完成后再读取数据,从而导致延时上升。 + +通过调整下面 TiKV 的配置项,你可以使 TiDB 加快 Resolved TS 推进,以减少 Stale Read 延时: + +```toml +[resolved-ts] +advance-ts-interval = "20s" # 默认为 20 秒,可适当调小该值以加快 Resolved TS 推进,比如调整为 1 秒。 +``` + +> **注意:** +> +> 调小该参数会增加 TiKV CPU 使用率和各节点之间的流量。 + ## 限制 当对表的 Stale Read 查询下推到 TiFlash 时,如果该表在 Stale Read 所指定的读取时间戳之后执行过 DDL 操作,此查询将会报错。原因是 TiFlash 只支持从最新的表结构读取数据。 diff --git a/statement-summary-tables.md b/statement-summary-tables.md index 60557819a12a..57fc851c1734 100644 --- a/statement-summary-tables.md +++ b/statement-summary-tables.md @@ -105,7 +105,7 @@ select * from employee where id in (...) and salary between ? and ?; - `tidb_enable_stmt_summary`:是否打开 statement summary 功能。1 代表打开,0 代表关闭,默认打开。statement summary 关闭后,系统表里的数据会被清空,下次打开后重新统计。经测试,打开后对性能几乎没有影响。 - `tidb_stmt_summary_refresh_interval`:`statements_summary` 的清空周期,单位是秒 (s),默认值是 `1800`。 - `tidb_stmt_summary_history_size`:`statements_summary_history` 保存每种 SQL 的历史的数量,也是 `statements_summary_evicted` 的表容量,默认值是 `24`。 -- `tidb_stmt_summary_max_stmt_count`:statement summary tables 保存的 SQL 种类数量,默认 3000 条。当 SQL 种类超过该值时,会移除最近没有使用的 SQL。这些 SQL 将会被 `statements_summary_evicted` 统计记录。 +- `tidb_stmt_summary_max_stmt_count`:statement summary tables 保存的 SQL 种类数量,默认 3000 条。当 SQL 种类超过该值时,会移除最近没有使用的 SQL。这些 SQL 将会被 `DIGEST` 为 `NULL` 的行和 `statements_summary_evicted` 统计记录。`DIGEST` 为 `NULL` 的行数据在 [TiDB Dashboard SQL 语句分析列表页面](/dashboard/dashboard-statement-list.md#others) 中显示为 `Others`。 - `tidb_stmt_summary_max_sql_length`:字段 `DIGEST_TEXT` 和 `QUERY_SAMPLE_TEXT` 的最大显示长度,默认值是 4096。 - `tidb_stmt_summary_internal_query`:是否统计 TiDB 的内部 SQL。1 代表统计,0 代表不统计,默认不统计。 diff --git a/system-variables.md b/system-variables.md index 7986cbd74700..2e53f98e55d5 100644 --- a/system-variables.md +++ b/system-variables.md @@ -976,13 +976,7 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 > **警告:** > -> 当前索引加速功能未完全兼容添加唯一索引操作。在添加唯一索引时,建议关闭索引加速功能(将 `tidb_ddl_enable_fast_reorg` 设置为 `OFF`)。 -> -> 当关闭 [PITR (Point-in-time recovery)](/br/backup-and-restore-overview.md) 时使用索引加速功能,添加索引的速度预期是 v6.1.0 的 10 倍。但是同时开启 PITR 和索引加速时,不会有性能提升。为了优化性能,建议你先停止 PITR 后台备份任务,以索引加速的方式快速添加索引,然后再启动 PITR 备份任务。否则,可能会发生以下行为: -> -> - 如果先启动 PITR 备份任务,再添加索引,此时即使索引加速功能打开,添加索引任务默认会自动回退到旧模式,即以较慢的速度添加索引,但 PITR 的备份任务能够正常运行并备份新增的索引数据。 -> - 如果先启动添加索引加速任务,再尝试启动 PITR 备份任务,此时 PITR 备份任务会抛出错误并退出,但这不会影响正在添加索引的任务。在索引加速任务完成后,你需要重新启动 PITR 日志备份任务,并手动执行一次全量备份。 -> - 如果同时启动 PITR 备份任务和添加索引加速任务,可能会由于两个任务无法察觉到对方而导致 PITR 不能成功备份新增的索引数据。在添加索引任务完成后,你仍需要重新启动 PITR 日志备份任务,并手动执行一次全量备份。 +> 目前,PITR 恢复会额外处理日志备份时间段内通过索引加速功能创建的索引,以达到兼容效果。详细内容请参考[索引加速功能为什么与 PITR 功能不兼容](/faq/backup-and-restore-faq.md#索引加速功能为什么与-pitr-功能不兼容)。 ### `tidb_ddl_distribute_reorg` 从 v6.6.0 版本开始引入 @@ -1093,10 +1087,14 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 默认值:`0` - 范围:`[0, 2147483647]` - 单位:行 -- 这个变量的值大于 `0` 时,TiDB 会将 `INSERT` 或 `LOAD DATA` 等语句在更小的事务中批量提交。这样可减少内存使用,确保大批量修改时事务大小不会达到 `txn-total-size-limit` 限制。 +- 这个变量的值大于 `0` 时,TiDB 会将 `INSERT` 语句在更小的事务中批量提交。这样可减少内存使用,确保大批量修改时事务大小不会达到 `txn-total-size-limit` 限制。 - 只有变量值为 `0` 时才符合 ACID 要求。否则无法保证 TiDB 的原子性和隔离性要求。 - 要使该特性生效,还需要开启 `tidb_enable_batch_dml`,以及至少开启 `tidb_batch_insert` 和 `tidb_batch_delete` 中的一个。 +> **注意:** +> +> 自 v7.0.0 起,`tidb_dml_batch_size`对 [`LOAD DATA` 语句](/sql-statements/sql-statement-load-data.md)不再生效。如需控制 `LOAD DATA` 语句的事务大小,可使用参数 [`batch_size`](/sql-statements/sql-statement-load-data.md#with-batch_sizenumber)。 + ### `tidb_enable_1pc` 从 v5.0 版本开始引入 - 作用域:SESSION | GLOBAL @@ -1321,13 +1319,13 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 > **警告:** > -> 当前版本中该变量控制的功能尚未完全生效,请保留默认值。 +> 非 Prepare 语句执行计划缓存目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 - 作用域:SESSION | GLOBAL - 是否持久化到集群:是 - 类型:布尔型 - 默认值:`OFF` -- 这个变量用来控制是否开启 General Plan Cache。 +- 这个变量用来控制是否开启[非 Prepare 语句执行计划缓存](/sql-non-prepared-plan-cache.md)。 ### `tidb_enable_gogc_tuner` 从 v6.4.0 版本开始引入 @@ -1470,8 +1468,9 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 作用域:SESSION | GLOBAL - 是否持久化到集群:是 - 类型:布尔型 -- 默认值:`OFF` +- 默认值:在 v7.0.0 之前版本中为 `OFF`,即默认关闭。在 v7.0.0 及之后的版本中为 `ON`,即默认开启。 - 这个变量用于控制 TiDB 对特殊集合算子 `NOT IN` 和 `!= ALL` 引导的子查询产生的 ANTI JOIN 是否采用 Null Aware Hash Join 的执行方式。 +- 从旧版本升级到 v7.0.0 及之后版本,该功能自动开启,即该变量的值修改为默认值 `ON`。 ### `tidb_enable_outer_join_reorder` 从 v6.1.0 版本开始引入 @@ -1485,6 +1484,14 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 如果升级前 TiDB 的版本低于 v6.1.0,升级后该变量的默认值为 `ON`。 - 如果升级前 TiDB 的版本等于或大于 v6.1.0,升级后该变量的默认值跟随升级前的设定值。 +### `tidb_enable_inl_join_inner_multi_pattern` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:布尔型 +- 默认值:`OFF` +- 该变量用于控制当内表上有 `Selection`/`Projection` 算子时是否支持 Index Join。`OFF` 表示不支持。 + ### `tidb_enable_ordered_result_mode` - 作用域:SESSION | GLOBAL @@ -1533,6 +1540,14 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 默认值:`ON` - 这个变量用来控制 Prepared Plan Cache 是否缓存 `LIMIT` 后面带变量 (`LIMIT ?`) 的执行计划。目前不支持缓存 `LIMIT` 后面带变量且变量值大于 10000 的执行计划。 +### `tidb_enable_plan_cache_for_subquery` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:布尔型 +- 默认值:`ON` +- 这个变量用来控制 Prepared Plan Cache 是否缓存包含子查询的查询。 + ### `tidb_enable_plan_replayer_capture` - 作用域:SESSION | GLOBAL @@ -1541,16 +1556,13 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 默认值:`ON` - 这个变量用来控制是否开启 [`PLAN REPLAYER CAPTURE` 功能](/sql-plan-replayer.md#使用-plan-replayer-capture-抓取目标计划)。默认值 `ON` 代表开启 `PLAN REPLAYER CAPTURE` 功能。 -### `tidb_enable_plan_replayer_continues_capture` - -> **警告:** -> -> 当前版本中该变量控制的功能尚未完全生效,请保留默认值。 +### `tidb_enable_plan_replayer_continuous_capture` 从 v7.0.0 版本开始引入 - 作用域:SESSION | GLOBAL - 是否持久化到集群:是 - 类型:布尔型 - 默认值:`OFF` +- 这个变量用来控制是否开启 [`PLAN REPLAYER CONTINUOUS CAPTURE` 功能](/sql-plan-replayer.md#使用-plan-replayer-continuous-capture)。默认值 `OFF` 代表关闭功能。 ### `tidb_enable_prepared_plan_cache` 从 v6.1.0 版本开始引入 @@ -1594,9 +1606,9 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数 - 作用域:GLOBAL - 是否持久化到集群:是 -- 默认值:`OFF` +- 默认值:`ON` - 类型:布尔型 -- 该变量是[资源管控特性](/tidb-resource-control.md)的开关。该变量设置为 `ON` 后,集群支持应用按照资源组做资源隔离。 +- 该变量是[资源管控特性](/tidb-resource-control.md)的开关。该变量设置为 `ON` 时,集群支持应用按照资源组做资源隔离。 ### `tidb_enable_reuse_chunk` 从 v6.4.0 版本开始引入 @@ -1911,14 +1923,14 @@ v5.0 后,用户仍可以单独修改以上系统变量(会有废弃警告) > **警告:** > -> 当前版本中该变量控制的功能尚未完全生效,请保留默认值。 +> 非 Prepare 语句执行计划缓存目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 - 作用域:SESSION | GLOBAL - 是否持久化到集群:是 - 类型:整数型 - 默认值:`100` - 范围:`[1, 100000]` -- 这个变量用来控制 General Plan Cache 最多能够缓存的计划数量。 +- 这个变量用来控制[非 Prepare 语句执行计划缓存](/sql-non-prepared-plan-cache.md)最多能够缓存的计划数量。 ### `tidb_generate_binary_plan` 从 v6.2.0 版本开始引入 @@ -2141,6 +2153,19 @@ v5.0 后,用户仍可以单独修改以上系统变量(会有废弃警告) - 类型:字符串 - 这个变量是一个只读变量,用于获取当前会话中最后一个 `PLAN REPLAYER dump` 的结果。 +### `tidb_load_based_replica_read_threshold` 从 v7.0.0 版本开始引入 + +> **警告:** +> +> 当前版本中该变量控制的功能尚未完全生效,请保留默认值。 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 默认值:`"0s"` +- 范围:`[0s, 1h]` +- 类型:字符串 +- 这个变量用来设置基于负载的 replica read 的触发阈值。当 leader 节点的预估排队时间超过阈值时,TiDB 会优先从 follower 节点读取数据。格式为时间,例如 `"100ms"` 或 `"1s"`。 + ### `tidb_log_file_max_days` 从 v5.3.0 版本开始引入 - 作用域:GLOBAL @@ -2174,6 +2199,48 @@ v5.0 后,用户仍可以单独修改以上系统变量(会有废弃警告) - 单位:秒 - 这个变量用于指定自动 ANALYZE 的最大执行时间。当执行时间超出指定的时间时,自动 ANALYZE 会被终止。当该变量值为 0 时,自动 ANALYZE 没有最大执行时间的限制。 +### `tidb_max_bytes_before_tiflash_external_group_by` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:整数型 +- 默认值:`-1` +- 范围:`[-1, 9223372036854775807]` +- 这个变量用于指定 TiFlash 中带有 `GROUP BY` 的 Hash Aggregation 算子的最大内存使用量,单位为 byte,超过该值之后 TiFlash 会触发 Hash Aggregation 算子的落盘。当该变量值为 -1 时,TiDB 不传递该变量给 TiFlash。只有该变量值大于等于 0 时,TiDB 才会传递该变量给 TiFlash。该变量为 0 时表示内存使用无限制,即 TiFlash Hash Aggregation 算子不会触发落盘。详情见 [TiFlash 数据落盘](/tiflash/tiflash-spill-disk.md)。 + +> **注意:** +> +> - 假设一个 TiDB 集群有多个 TiFlash 节点,Aggregation 通常会在多个 TiFlash 节点上分布式执行。该变量控制的是单个 TiFlash 节点中 Aggregation 算子的最大内存使用量。 +> - 当该变量设置为 -1 时,TiFlash 将根据自身配置项 [`max_bytes_before_external_group_by`](/tiflash/tiflash-configuration.md#tiflash-配置参数-1) 的值来决定 Aggregation 算子的最大内存使用量。 + +### `tidb_max_bytes_before_tiflash_external_join` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:整数型 +- 默认值:`-1` +- 范围:`[-1, 9223372036854775807]` +- 这个变量用于指定 TiFlash 中带等值关联条件的 Hash Join 算子的最大内存使用量,单位为 byte,超过该值之后 TiFlash 会触发 Hash Join 算子的落盘。当该变量值为 -1 时,TiDB 不传递该变量给 TiFlash。只有该变量值大于等于 0 时,TiDB 才会传递该变量给 TiFlash。该变量为 0 时表示内存使用无限制,即 TiFlash Hash Join 算子不会触发落盘。详情见 [TiFlash 数据落盘](/tiflash/tiflash-spill-disk.md)。 + +> **注意:** +> +> - 假设一个 TiDB 集群有多个 TiFlash 节点,Join 通常会在多个 TiFlash 节点上分布式执行。该变量控制的是单个 TiFlash 节点中 Join 算子的最大内存使用量。 +> - 当该变量设置为 -1 时,TiFlash 将根据自身配置项 [`max_bytes_before_external_join`](/tiflash/tiflash-configuration.md#tiflash-配置参数-1) 的值来决定 Join 算子的最大内存使用量。 + +### `tidb_max_bytes_before_tiflash_external_sort` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:整数型 +- 默认值:`-1` +- 范围:`[-1, 9223372036854775807]` +- 这个变量用于指定 TiFlash 中带 topN 和 sort 算子的最大内存使用量,单位为 byte,超过该值之后 TiFlash 会触发 topN 和 sort 算子的落盘。当该变量值为 -1 时,TiDB 不传递该变量给 TiFlash。只有该变量值大于等于 0 时,TiDB 才会传递该变量给 TiFlash。该变量为 0 时表示内存使用无限制,即 TiFlash topN 和 sort 算子不会触发落盘。详情见 [TiFlash 数据落盘](/tiflash/tiflash-spill-disk.md)。 + +> **注意:** +> +> - 假设一个 TiDB 集群有多个 TiFlash 节点,TopN 和 Sort 通常会在多个 TiFlash 节点中分布式执行。该变量控制的是单个 TiFlash 节点中 TopN 和 Sort 算子的最大内存使用量。 +> - 当该变量设置为 -1 时,TiFlash 将根据自身配置项 [`max_bytes_before_external_sort`](/tiflash/tiflash-configuration.md#tiflash-配置参数-1) 的值来决定 TopN 和 Sort 算子的最大内存使用量。 + ### `tidb_max_chunk_size` - 作用域:SESSION | GLOBAL @@ -2454,6 +2521,14 @@ v5.0 后,用户仍可以单独修改以上系统变量(会有废弃警告) - 默认值:`3.0` - 表示 TiDB 处理一行数据的 CPU 开销。该变量是[代价模型](/cost-model.md)内部使用的变量,不建议修改该变量的值。 +### `tidb_opt_derive_topn` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:布尔型 +- 默认值:`OFF` +- 表示是否开启[从窗口函数中推导 TopN 或 Limit](/derive-topn-from-window.md) 的优化规则。 + ### `tidb_opt_desc_factor` - 作用域:SESSION | GLOBAL @@ -2513,6 +2588,15 @@ mysql> desc select count(distinct a) from test.t; - 默认值:`ON` - 这个变量用来控制优化器是否开启交叉估算。 +### `tidb_opt_enable_late_materialization` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:布尔型 +- 默认值:`OFF` +- 这个变量用来控制是否启用 [TiFlash 延迟物化](/tiflash/tiflash-late-materialization.md)功能。 +- 默认情况下,如果 `SELECT` 语句中包含过滤条件(`WHERE` 子句),TiFlash 会先扫描查询所需列的全部数据后再进行过滤。当设置该变量为 `ON` 开启 TiFlash 延迟物化功能时,TiFlash 可以先扫描过滤条件相关的列数据,过滤得到符合条件的行后,再扫描这些行的其他列数据,继续后续计算,从而减少 IO 扫描和数据处理的计算量。 + ### `tidb_opt_force_inline_cte` 从 v6.3.0 版本开始引入 - 作用域:SESSION | GLOBAL @@ -2521,6 +2605,18 @@ mysql> desc select count(distinct a) from test.t; - 默认值:`OFF` - 这个变量用来控制是否强制 inline CTE。默认值为 `OFF`,即默认不强制 inline CTE。注意,此时依旧可以通过 `MERGE()` hint 来开启个别 CTE 的 inline。如果设置为 `ON`,则当前 session 中所有查询的 CTE(递归 CTE 除外)都会 inline。 +### `tidb_opt_advanced_join_hint` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:布尔型 +- 默认值:`ON` +- 这个变量用来控制包括 [`HASH_JOIN()` Hint](/optimizer-hints.md#hash_joint1_name--tl_name-)、[`MERGE_JOIN()` Hint](/optimizer-hints.md#merge_joint1_name--tl_name-) 等用于控制连接算法的 Join Method Hint 是否会影响 Join Reorder 的优化过程,包括 [`LEADING()` Hint](/optimizer-hints.md#leadingt1_name--tl_name-) 的使用。默认值为 `ON`,即默认不影响。如果设置为 `OFF`,在一些同时使用 Join Method Hint 和 `LEADING()` Hint 的场景下可能会产生冲突。 + +> **注意:** +> +> v7.0.0 之前的版本行为和将该变量设置为 `OFF` 的行为一致。为确保向前兼容,从旧版本升级到 v7.0.0 及之后版本的集群,该变量会被设置成 `OFF`。为了获取更灵活的 Hint 行为,强烈建议在确保无性能回退的情况下,将该变量切换为 `ON`。 + ### `tidb_opt_insubq_to_join_and_agg` - 作用域:SESSION | GLOBAL @@ -2597,6 +2693,46 @@ mysql> desc select count(distinct a) from test.t; - 默认值:`1.0` - 表示传输 1 比特数据的网络净开销。该变量是[代价模型](/cost-model.md)内部使用的变量,**不建议**修改该变量的值。 +### `tidb_opt_ordering_index_selectivity_threshold` 从 v7.0.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 类型:浮点数 +- 默认值:`0` +- 范围:`[0, 1]` +- 用于当 SQL 中存在 `ORDER BY` 和 `LIMIT` 子句且带有过滤条件时,控制优化器选择索引的行为。 +- 对于此类查询,优化器会考虑选择对应的索引来满足 `ORDER BY` 和 `LIMIT` 子句(即使这个索引并不满足任何过滤条件)。但是由于数据分布的复杂性,优化器在这种场景下可能会选择不优的索引。 +- 该变量表示一个阈值。当存在索引能满足过滤条件,且其选择率估算值低于该阈值时,优化器会避免选择用于满足 `ORDER BY` 和 `LIMIT` 的索引,而优先选择用于满足过滤条件的索引。 +- 例如,当把该变量设为 `0` 时,优化器保持默认行为;当设为 `1` 时,优化器总是优先选择满足过滤条件的索引,避免选择满足 `ORDER BY` 和 `LIMIT` 的索引。 +- 在以下示例中,`t` 表共有 1,000,000 行数据。使用 `b` 列上的索引时,其估算行数是大约 8,748 行,因此其选择率估算值大约是 0.0087。默认情况下,优化器选择了 `a` 列上的索引。而将该变量设为 `0.01` 之后,由于 `b` 列上的索引的选择率 (0.0087) 低于 0.01,优化器选择了 `b` 列上的索引。 + +```sql +> EXPLAIN SELECT * FROM t WHERE b <= 9000 ORDER BY a LIMIT 1; ++-----------------------------------+---------+-----------+----------------------+--------------------+ +| id | estRows | task | access object | operator info | ++-----------------------------------+---------+-----------+----------------------+--------------------+ +| Limit_12 | 1.00 | root | | offset:0, count:1 | +| └─Projection_25 | 1.00 | root | | test.t.a, test.t.b | +| └─IndexLookUp_24 | 1.00 | root | | | +| ├─IndexFullScan_21(Build) | 114.30 | cop[tikv] | table:t, index:ia(a) | keep order:true | +| └─Selection_23(Probe) | 1.00 | cop[tikv] | | le(test.t.b, 9000) | +| └─TableRowIDScan_22 | 114.30 | cop[tikv] | table:t | keep order:false | ++-----------------------------------+---------+-----------+----------------------+--------------------+ + +> SET SESSION tidb_opt_ordering_index_selectivity_threshold = 0.01; + +> EXPLAIN SELECT * FROM t WHERE b <= 9000 ORDER BY a LIMIT 1; ++----------------------------------+---------+-----------+----------------------+-------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------------+---------+-----------+----------------------+-------------------------------------+ +| TopN_9 | 1.00 | root | | test.t.a, offset:0, count:1 | +| └─IndexLookUp_20 | 1.00 | root | | | +| ├─IndexRangeScan_17(Build) | 8748.62 | cop[tikv] | table:t, index:ib(b) | range:[-inf,9000], keep order:false | +| └─TopN_19(Probe) | 1.00 | cop[tikv] | | test.t.a, offset:0, count:1 | +| └─TableRowIDScan_18 | 8748.62 | cop[tikv] | table:t | keep order:false | ++----------------------------------+---------+-----------+----------------------+-------------------------------------+ +``` + ### `tidb_opt_prefer_range_scan` 从 v5.0 版本开始引入 - 作用域:SESSION | GLOBAL @@ -2844,18 +2980,20 @@ SHOW WARNINGS; - 默认值:`ON` - 这个变量用于控制是否开启 [ANALYZE 配置持久化](/statistics.md#analyze-配置持久化)特性。 -### `tidb_pessimistic_txn_aggressive_locking` 从 v6.6.0 版本开始引入 +### `tidb_pessimistic_txn_fair_locking` 从 v7.0.0 版本开始引入 - 作用域:SESSION | GLOBAL - 是否持久化到集群:是 - 类型:布尔型 -- 默认值:`OFF` +- 默认值:`ON` - 是否对悲观锁启用加强的悲观锁唤醒模型。该模型可严格控制悲观锁单点冲突场景下事务的唤醒顺序,避免无效唤醒,大大降低原有唤醒机制中的随机性对事务延迟带来的不确定性。如果业务场景中遇到了单点悲观锁冲突频繁的情况(如高频更新同一行数据等),并进而引起语句重试频繁、尾延迟高,甚至偶尔发生 `pessimistic lock retry limit reached` 错误,可以尝试开启该变量来解决问题。 +- 对于从 v7.0.0 以前的版本升级到 v7.0.0 或更新版本的 TiDB 集群,该选项默认关闭。 > **注意:** > -> * 视具体业务场景的不同,启用该选项可能对存在频繁锁冲突的事务造成一定程度的吞吐下降(平均延迟上升)。 -> * 该选项目前仅对需要上锁单个 key 的语句有效。如果一个语句需要对多行同时上锁,则该选项不会对此类语句生效。 +> - 视具体业务场景的不同,启用该选项可能对存在频繁锁冲突的事务造成一定程度的吞吐下降(平均延迟上升)。 +> - 该选项目前仅对需要上锁单个 key 的语句有效。如果一个语句需要对多行同时上锁,则该选项不会对此类语句生效。 +> - 该功能从 v6.6.0 版本引入。在 v6.6.0 版本中,该功能由变量 [`tidb_pessimistic_txn_aggressive_locking`](https://docs.pingcap.com/zh/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-%E4%BB%8E-v660-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5) 控制,默认关闭。 ### `tidb_placement_mode` 从 v6.0.0 版本开始引入 @@ -2985,6 +3123,7 @@ EXPLAIN FORMAT='brief' SELECT COUNT(1) FROM t WHERE a = 1 AND b IS NOT NULL; > > - 该特性与 [`replica-read`](#tidb_replica_read-从-v40-版本开始引入) 尚不兼容,开启 `tidb_rc_read_check_ts` 的读请求无法使用 [`replica-read`](#tidb_replica_read-从-v40-版本开始引入),请勿同时开启两项特性。 > - 如果客户端使用游标操作,建议不开启 `tidb_rc_read_check_ts` 这一特性,避免前一批返回数据已经被客户端使用而语句最终会报错的情况。 +> - 自 v7.0.0 版本开始,该变量对于使用 prepared statement 协议下 cursor fetch read 游标模式不再生效。 - 作用域:GLOBAL - 是否持久化到集群:否,仅作用于当前连接的 TiDB 实例 @@ -3455,99 +3594,76 @@ Query OK, 0 rows affected, 1 warning (0.00 sec) ### `tidb_ttl_delete_rate_limit` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`0` - 范围:`[0, 9223372036854775807]` -- 这个变量用来对每个 TiDB 节点的 TTL 删除操作进行限流。其值代表了在 TTL 任务中单个节点每秒允许 `DELETE` 语句执行的最大次数。当此变量设置为 `0` 时,则表示不做限制。 +- 这个变量用来对每个 TiDB 节点的 TTL 删除操作进行限流。其值代表了在 TTL 任务中单个节点每秒允许 `DELETE` 语句执行的最大次数。当此变量设置为 `0` 时,则表示不做限制。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_delete_batch_size` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`100` - 范围:`[1, 10240]` -- 这个变量用于设置 TTL 任务中单个删除事务中允许删除的最大行数。 +- 这个变量用于设置 TTL 任务中单个删除事务中允许删除的最大行数。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_delete_worker_count` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`4` - 范围:`[1, 256]` -- 这个变量用于设置每个 TiDB 节点上 TTL 删除任务的最大并发数。 +- 这个变量用于设置每个 TiDB 节点上 TTL 删除任务的最大并发数。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_job_enable` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`ON` - 类型:布尔型 -- 这个变量用于控制是否启动 TTL 后台清理任务。如果设置为 `OFF`,所有具有 TTL 属性的表会自动停止对过期数据的清理。 +- 这个变量用于控制是否启动 TTL 后台清理任务。如果设置为 `OFF`,所有具有 TTL 属性的表会自动停止对过期数据的清理。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_scan_batch_size` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`500` - 范围:`[1, 10240]` -- 这个变量用于设置 TTL 任务中用来扫描过期数据的每个 `SELECT` 语句的 `LIMIT` 的值。 +- 这个变量用于设置 TTL 任务中用来扫描过期数据的每个 `SELECT` 语句的 `LIMIT` 的值。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_scan_worker_count` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 是否持久化到集群:是 - 默认值:`4` - 范围:`[1, 256]` -- 这个变量用于设置每个 TiDB 节点 TTL 扫描任务的最大并发数。 +- 这个变量用于设置每个 TiDB 节点 TTL 扫描任务的最大并发数。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_job_schedule_window_start_time` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 类型:时间 - 是否持久化到集群:是 - 默认值:`00:00 +0000` -- 这个变量用于控制 TTL 后台清理任务的调度窗口的起始时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。 +- 这个变量用于控制 TTL 后台清理任务的调度窗口的起始时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_ttl_job_schedule_window_end_time` 从 v6.5.0 版本开始引入 -> **警告:** -> -> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。 - - 作用域:GLOBAL - 类型:时间 - 是否持久化到集群:是 - 默认值:`23:59 +0000` -- 这个变量用于控制 TTL 后台清理任务的调度窗口的结束时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。 +- 这个变量用于控制 TTL 后台清理任务的调度窗口的结束时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。更多信息,请参考 [Time to Live](/time-to-live.md)。 + +### `tidb_ttl_running_tasks` 从 v7.0.0 版本开始引入 + +- 作用域:GLOBAL +- 是否持久化到集群:是 +- 类型:整数型 +- 默认值:`-1` +- 范围:`-1` 或 `[1, 256]` +- 这个变量用于限制整个集群内 TTL 任务的并发量。`-1` 表示与 TiKV 节点的数量相同。更多信息,请参考 [Time to Live](/time-to-live.md)。 ### `tidb_txn_assertion_level` 从 v6.0.0 版本开始引入 @@ -3626,7 +3742,7 @@ Query OK, 0 rows affected, 1 warning (0.00 sec) - 是否持久化到集群:是 - 默认值:`OFF` - 类型:布尔型 -- 如果开启 [FastScan 功能](/develop/dev-guide-use-fastscan.md)(设置为 `ON` 时),TiFlash 可以提供更高效的查询性能,但不保证查询结果的精度和数据一致性。 +- 如果开启 [FastScan 功能](/tiflash/use-fastscan.md)(设置为 `ON` 时),TiFlash 可以提供更高效的查询性能,但不保证查询结果的精度和数据一致性。 ### `tiflash_fine_grained_shuffle_batch_size` 从 v6.2.0 版本开始引入 diff --git a/templates/copyright.tex b/templates/copyright.tex index b9417ae10266..a52b173a5036 100644 --- a/templates/copyright.tex +++ b/templates/copyright.tex @@ -1,3 +1,3 @@ \noindent \rule{\textwidth}{1pt} -©2022 PingCAP 公司保留所有权利。除非版权法允许,否则在未得到本公司事先给出的书面许可的情况下,严禁复制、改编或翻译本文。 +© 2023 PingCAP 公司保留所有权利。除非版权法允许,否则在未得到本公司事先给出的书面许可的情况下,严禁复制、改编或翻译本文。 diff --git a/ticdc-performance-tuning-methods.md b/ticdc-performance-tuning-methods.md new file mode 100644 index 000000000000..98d76c3b12c2 --- /dev/null +++ b/ticdc-performance-tuning-methods.md @@ -0,0 +1,71 @@ +--- +title: TiCDC 性能分析和优化方法 +summary: 本文介绍了 Performance Overview 面板中的 TiCDC 部分,帮助你了解和监控 TiCDC 工作负载。 +--- + +# TiCDC 性能分析和优化方法 + +本文介绍 TiCDC 资源使用率和关键的性能指标。你可以通过 Performance Overview 面板中的 [CDC 面板](/grafana-performance-overview-dashboard.md#cdc)来监控和评估 TiCDC 同步数据的性能。 + +## TiCDC 集群的资源利用率 + +通过以下三个指标,你可以快速判断 TiCDC 集群的资源使用率: + +- CPU usage:TiCDC 节点的 CPU 使用情况 +- Memory usage:TiCDC 节点的内存使用情况 +- Goroutine count:TiCDC 节点 Goroutine 的个数 + +## TiCDC 数据同步关键指标 + +### TiCDC 整体指标 + +通过以下指标,你可以了解 TiCDC 数据同步的整体情况: + +- Changefeed checkpoint lag:同步任务上下游数据的进度差,以时间单位秒计算。 + + 如果 TiCDC 消费数据的速度和写入下游的速度能跟上上游的数据变更,该指标将保持在较小的延迟范围内,通常是 10 秒以内。如果 TiCDC 消费数据的速度和写入下游的速度跟不上上游的数据变更,则该指标将持续增长。 + + 该指标增长(即 TiCDC checkpoint lag 增长)的常见原因如下: + + - 系统资源不足:如果 TiCDC 系统中的 CPU、内存或磁盘空间不足,可能会导致数据处理速度过慢,从而导致 TiCDC Changefeed checkpoint 过长。 + - 网络问题:如果 TiCDC 系统中存在网络中断、延迟或带宽不足的问题,可能会影响数据的传输速度,从而导致 TiCDC Changefeed checkpoint 过长。 + - 上游 QPS 过高:如果 TiCDC 系统需要处理的数据量过大,可能会导致数据处理超时,从而导致 TiCDC Changefeed checkpoint 增长,通常一个 TiCDC 节点处理的 QPS 上限为 60K 左右。 + - 数据库问题: + - 上游 TiKV 集群 `min resolved ts` 和最新的 PD TSO 差距过大,通常是因为上游写入负载过大,TiKV 无法及时推进 resolved ts 造成。 + - 下游数据库写入延迟高导致 TiCDC 无法及时将数据同步到下游。 + +- Changefeed resolved ts lag:TiCDC 节点内部同步状态与上游的进度差,以时间单位秒计算。如果 TiCDC Changefeed resolved ts lag 值很高,可能意味着 TiCDC 系统的 Puller 或者 Sorter 模块数据处理能力不足,或者可能存在网络延迟或磁盘读写速度慢的问题。在这种情况下,需要采取适当的措施,例如增加 TiCDC 实例数量或优化网络配置,以确保 TiCDC 系统的高效和稳定运行。 +- The status of changefeeds:Changefeed 各状态的解释,请参考 [Changefeed 状态流转](/ticdc/ticdc-changefeed-overview.md)。 + +示例 1:单个 TiCDC 节点上游 QPS 过高导致 checkpoint lag 过高 + +如下图所示,因为上游 QPS 过高,该集群中只有单个 TiCDC 节点,TiCDC 节点处于过载状态,CPU 使用率较高,Changefeed checkpoint lag 和 Changefeed resolved ts lag 持续增长。Changefeeds 的状态间歇性地从 0 变为 1,意味着 changefeed 不断出错。你可尝试通过增加资源解决该问题: + +- 添加 TiCDC 节点:将 TiCDC 集群扩展到多个节点,以增加处理能力。 +- 优化 TiCDC 节点的资源:提高 TiCDC 节点的 CPU 和内存配置,以改善性能。 + +![TiCDC overview](/media/performance/cdc/cdc-slow.png) + +### 数据流吞吐指标和下游延迟信息 + +通过以下指标,你可以了解数据流的吞吐和下游延迟信息: + +- Puller output events/s:TiCDC 节点中 Puller 模块每秒输出到 Sorter 模块的数据变更行数 +- Sorter output events/s:TiCDC 节点中 Sorter 模块每秒输出到 Mounter 模块的行数 +- Mounter output events/s:TiCDC 节点中 Mounter 模块每秒输出到 Sink 模块的行数 +- Table sink output events/s:TiCDC 节点中 Table Sorter 模块每秒输出到 Sink 模块的行数 +- SinkV2 - Sink flush rows/s:TiCDC 节点中 Sink 模块每秒输出到下游的行数 +- Transaction Sink Full Flush Duration:TiCDC 节点中 MySQL Sink 写下游事务的平均延迟和 p999 延迟 +- MQ Worker Send Message Duration Percentile:下游为 Kafka 时 MQ worker 发送消息的延迟 +- Kafka Outgoing Bytes:MQ Workload 写下游事务的流量 + +示例 2:下游数据库写入速度对 TiCDC 数据同步性能的影响 + +如下图所示,该环境上下游都为 TiDB 集群。通过 `TiCDC Puller output events/s` 可以确认上游数据库的 QPS 值。通过 `Transaction Sink Full Flush Duration` 可以确认,第一段负载的下游数据库平均写入延迟高,第二段负载的下游平均写入延迟低。 + +- 在第一段负载期间,由于下游 TiDB 集群写入数据缓慢,导致 TiCDC 消费数据的速度跟不上上游的 QPS,引起 Changefeed checkpoint lag 不断增长。然而,Changefeed resolved ts lag 仍然在 300 毫秒以内,说明同步延迟和吞吐瓶颈不在 puller 和 sorter 模块中,而在下游的 sink 模块。 +- 在第二段负载期间,因为下游 TiDB 集群的写入速度快,TiCDC 同步数据的速度完全追上了上游的速度,因此 Changefeed checkpoint lag 和 Changefeed resolved ts lag 保持在 500 毫秒以内,此时 TiCDC 的同步速度较为理想。 + +![TiCDC overview](/media/performance/cdc/cdc-fast-1.png) + +![data flow and txn latency](/media/performance/cdc/cdc-fast-2.png) \ No newline at end of file diff --git a/ticdc/ticdc-avro-protocol.md b/ticdc/ticdc-avro-protocol.md index cff3a0a07158..6c2be610a664 100644 --- a/ticdc/ticdc-avro-protocol.md +++ b/ticdc/ticdc-avro-protocol.md @@ -262,7 +262,7 @@ DECIMAL(10, 4) ## DDL 事件与 Schema 变更 -Avro 并不会向下游生成 DDL 事件。Avro 会在每次 DML 事件发生时检测是否发生 schema 变更,如果发生了 schema 变更,Avro 会生成新的 schema,并尝试向 Schema Registry 注册。注册时,Schema Registry 会做兼容性检测,如果此次 schema 变更没有通过兼容性检测,注册将会失败,Avro 并不会尝试解决 schema 的兼容性问题。 +Avro 并不会向下游生成 DDL 事件。Avro 会在每次 DML 事件发生时检测是否发生 schema 变更,如果发生了 schema 变更,Avro 会生成新的 schema,并尝试向 Schema Registry 注册。注册时,Schema Registry 会做兼容性检测,如果此次 schema 变更没有通过兼容性检测,注册将会失败,TiCDC 并不会尝试解决 schema 的兼容性问题。 同时,即使 schema 变更通过兼容性检测并成功注册新版本,数据的生产者和消费者可能仍然需要升级才能正确工作。 @@ -273,3 +273,7 @@ Avro 并不会向下游生成 DDL 事件。Avro 会在每次 DML 事件发生时 ## Topic 分发 Schema Registry 支持三种 [Subject Name Strategy](https://docs.confluent.io/platform/current/schema-registry/serdes-develop/index.html#subject-name-strategy):TopicNameStrategy、RecordNameStrategy 和 TopicRecordNameStrategy。目前 TiCDC Avro 只支持 TopicNameStrategy 一种,这意味着一个 kafka topic 只能接收一种数据格式的数据,所以 TiCDC Avro 禁止将多张表映射到同一个 topic。在创建 changefeed 时,如果配置的分发规则中,topic 规则不包含 `{schema}` 和 `{table}` 占位符,将会报错。 + +## 兼容性说明 + +* 在升级 TiCDC 集群到 v7.0.0 时,如果使用 Avro 同步的表包含 `FLOAT` 类型数据,请在升级前手动调整 Confluent Schema Registry 的兼容性策略为 `None`,使 changefeed 能够成功更新 schema。否则,在升级之后 changefeed 将无法更新 schema 并进入错误状态。详情请参考 GitHub issue [#8490](https://github.com/pingcap/tiflow/issues/8490)。 diff --git a/ticdc/ticdc-changefeed-config.md b/ticdc/ticdc-changefeed-config.md index 2dca13cac51d..f53d63738448 100644 --- a/ticdc/ticdc-changefeed-config.md +++ b/ticdc/ticdc-changefeed-config.md @@ -91,11 +91,11 @@ ignore-insert-value-expr = "price > 1000 and origin = 'no where'" # 忽略包含 [scheduler] # 将表按 Region 个数划分成多个同步范围,这些范围可由多个 TiCDC 节点同步。 -# 注意: -# 1. 横向扩展功能目前为实验特性,不建议在生产环境中使用。 -# 2. 该参数只在 Kafka changefeed 上生效,暂不支持 MySQL changefeed。 -# 3. TiCDC 不会将小于该参数 Region 个数的表划分成多个同步范围。 -# region-per-span = 50000 +# 注意:该功能只在 Kafka changefeed 上生效,暂不支持 MySQL changefeed。 +# 默认为 "false"。设置为 "true" 以打开该功能。 +enable-table-across-nodes = false +# 打开该功能后,该功能只对 Region 个数大于 `region-threshold` 值的表生效。 +region-threshold = 100000 [sink] # 对于 MQ 类的 Sink,可以通过 dispatchers 配置 event 分发器 diff --git a/ticdc/ticdc-csv.md b/ticdc/ticdc-csv.md index f8e85ccfb9dd..e01a7247269c 100644 --- a/ticdc/ticdc-csv.md +++ b/ticdc/ticdc-csv.md @@ -35,6 +35,10 @@ include-commit-ts = true - 单表的同一事务不会存储在不同的 CSV 文件中。 - 相同事务涉及的不同表会存储在不同的 CSV 文件中。 +## 数据存储路径结构 + +关于数据存储路径结构的更多信息,请参考[同步数据到存储服务](/ticdc/ticdc-sink-to-cloud-storage.md#存储路径组织结构)。 + ## 数据格式定义 CSV 文件中,单行的每一列定义如下: diff --git a/ticdc/ticdc-open-api-v2.md b/ticdc/ticdc-open-api-v2.md new file mode 100644 index 000000000000..8cda309088db --- /dev/null +++ b/ticdc/ticdc-open-api-v2.md @@ -0,0 +1,1008 @@ +--- +title: TiCDC OpenAPI v2 +summary: 了解如何使用 OpenAPI v2 接口来管理集群状态和数据同步。 +--- + +# TiCDC OpenAPI v2 + +TiCDC 提供 OpenAPI 功能,你可以通过 OpenAPI v2 对 TiCDC 集群进行查询和运维操作。OpenAPI 的功能是 [`cdc cli` 工具](/ticdc/ticdc-manage-changefeed.md)的一个子集。 + +> **注意:** +> +> TiCDC OpenAPI v1 将在未来版本中被删除。推荐使用 TiCDC OpenAPI v2。 + +你可以通过 OpenAPI 完成 TiCDC 集群的如下运维操作: + +- [获取 TiCDC 节点状态信息](#获取-ticdc-节点状态信息) +- [检查 TiCDC 集群的健康状态](#检查-ticdc-集群的健康状态) +- [创建同步任务](#创建同步任务) +- [删除同步任务](#删除同步任务) +- [更新同步任务配置](#更新同步任务配置) +- [查询同步任务列表](#查询同步任务列表) +- [查询特定同步任务](#查询特定同步任务) +- [暂停同步任务](#暂停同步任务) +- [恢复同步任务](#恢复同步任务) +- [查询同步子任务列表](#查询同步子任务列表) +- [查询特定同步子任务](#查询特定同步子任务) +- [查询 TiCDC 服务进程列表](#查询-ticdc-服务进程列表) +- [驱逐 owner 节点](#驱逐-owner-节点) +- [动态调整 TiCDC Server 日志级别](#动态调整-ticdc-server-日志级别) + +所有 API 的请求体与返回值统一使用 JSON 格式数据。请求如果成功,则统一返回 `200 OK`。本文档以下部分描述当前提供的 API 的具体使用方法。 + +在下文的示例描述中,假设 TiCDC server 的监听 IP 地址为 `127.0.0.1`,端口为 `8300`。在启动 TiCDC server 时,可以通过 `--addr=ip:port` 指定 TiCDC 绑定的 IP 地址和端口。 + +## API 统一错误格式 + +对 API 发起请求后,如发生错误,返回错误信息的格式如下所示: + +```json +{ + "error_msg": "", + "error_code": "" +} +``` + +如上所示,`error_msg` 描述错误信息,`error_code` 则是对应的错误码。 + +## API List 接口统一返回格式 + +一个 API 请求如果返回是一个资源列表(例如,返回所有的服务进程 `Captures`),TiCDC 统一的返回格式如下: + +```json +{ + "total": 2, + "items": [ + { + "id": "d2912e63-3349-447c-90ba-wwww", + "is_owner": true, + "address": "127.0.0.1:8300" + }, + { + "id": "d2912e63-3349-447c-90ba-xxxx", + "is_owner": false, + "address": "127.0.0.1:8302" + } + ] +} +``` + +如上所示: + +- `total`: 表示有一共有多少个资源。 +- `items`: 当次请求返回的资源在这个数组里,数组所有的元素都是同种资源。 + +## 获取 TiCDC 节点状态信息 + +该接口是一个同步接口,请求成功会返回对应节点的状态信息。 + +### 请求 URI + +`GET /api/v2/status` + +### 使用样例 + +以下请求会获取 IP 地址为 `127.0.0.1`,端口号为 `8300` 的 TiCDC 节点的状态信息。 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/status +``` + +```json +{ + "version": "v7.0.0-master-dirty", + "git_hash": "10413bded1bdb2850aa6d7b94eb375102e9c44dc", + "id": "d2912e63-3349-447c-90ba-72a4e04b5e9e", + "pid": 1447, + "is_owner": true, + "liveness": 0 +} +``` + +以上返回信息的字段解释如下: + +- `version`:当前 TiCDC 版本号。 +- `git_hash`:Git 哈希值。 +- `id`:该节点的 capture ID。 +- `pid`:该节点 capture 进程的 PID。 +- `is_owner`:表示该节点是否是 owner。 +- `liveness`: 该节点是否在线。`0` 表示正常,`1` 表示处于 `graceful shutdown` 状态。 + +## 检查 TiCDC 集群的健康状态 + +该接口是一个同步接口,在集群健康的时候会返回 `200 OK`。 + +### 请求 URI + +`GET /api/v2/health` + +### 使用样例 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/health +``` + +如果集群健康,则返回 `200 OK` 和一个空的 json {}: + +```json +{} +``` + +如果集群不健康,则返回错误信息。 + +## 创建同步任务 + +该接口用于向 TiCDC 提交一个同步任务,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +### 请求 URI + +`POST /api/v2/changefeeds` + +### 参数说明 + +```json +{ + "changefeed_id": "string", + "replica_config": { + "bdr_mode": true, + "case_sensitive": true, + "check_gc_safe_point": true, + "consistent": { + "flush_interval": 0, + "level": "string", + "max_log_size": 0, + "storage": "string" + }, + "enable_old_value": true, + "enable_sync_point": true, + "filter": { + "do_dbs": [ + "string" + ], + "do_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "event_filters": [ + { + "ignore_delete_value_expr": "string", + "ignore_event": [ + "string" + ], + "ignore_insert_value_expr": "string", + "ignore_sql": [ + "string" + ], + "ignore_update_new_value_expr": "string", + "ignore_update_old_value_expr": "string", + "matcher": [ + "string" + ] + } + ], + "ignore_dbs": [ + "string" + ], + "ignore_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "ignore_txn_start_ts": [ + 0 + ], + "rules": [ + "string" + ] + }, + "force_replicate": true, + "ignore_ineligible_table": true, + "memory_quota": 0, + "mounter": { + "worker_num": 0 + }, + "sink": { + "column_selectors": [ + { + "columns": [ + "string" + ], + "matcher": [ + "string" + ] + } + ], + "csv": { + "delimiter": "string", + "include_commit_ts": true, + "null": "string", + "quote": "string" + }, + "date_separator": "string", + "dispatchers": [ + { + "matcher": [ + "string" + ], + "partition": "string", + "topic": "string" + } + ], + "enable_partition_separator": true, + "encoder_concurrency": 0, + "protocol": "string", + "schema_registry": "string", + "terminator": "string", + "transaction_atomicity": "string" + }, + "sync_point_interval": "string", + "sync_point_retention": "string" + }, + "sink_uri": "string", + "start_ts": 0, + "target_ts": 0 +} +``` + +参数说明如下: + +| 参数名 | 说明 | +|:-----------------|:------------------------------------------------------------------------------------| +| `changefeed_id` | `STRING` 类型,同步任务的 ID。(非必选) | +| `replica_config` | 同步任务的配置参数。(非必选) | +| **`sink_uri`** | `STRING` 类型,同步任务下游的地址。(**必选**) | +| `start_ts` | `UINT64` 类型,指定 changefeed 的开始 TSO。TiCDC 集群将从这个 TSO 开始拉取数据。默认为当前时间。(非必选) | +| `target_ts` | `UINT64` 类型,指定 changefeed 的目标 TSO。达到这个 TSO 后,TiCDC 集群将停止拉取数据。默认为空,即 TiCDC 不会自动停止。(非必选) | + +`changefeed_id`、`start_ts`、`target_ts`、`sink_uri` 的含义和格式与[使用 cli 创建同步任务](/ticdc/ticdc-manage-changefeed.md#创建同步任务)中所作的解释相同,具体解释请参见该文档。需要注意,当在 `sink_uri` 中指定证书的路径时,须确保已将对应证书上传到对应的 TiCDC server 上。 + +`replica_config` 参数说明如下: + +| 参数名 | 说明 | +|:--------------------------|:----------------------------------------------------------------------------------------------------| +| `bdr_mode` | `BOOLEAN` 类型,是否开启[双向同步复制](/ticdc/ticdc-bidirectional-replication.md)。默认值为 `false`。(非必选) | +| `case_sensitive` | `BOOLEAN` 类型,过滤表名时大小写是否敏感,默认值为 `true`。(非必选) | +| `check_gc_safe_point` | `BOOLEAN` 类型,是否检查同步任务的开始时间早于 GC 时间,默认值为 `true`。(非必选) | +| `consistent` | Redo log 配置。(非必选) | +| `enable_old_value` | `BOOLEAN` 类型,是否输出 old value 值(即变更前的值),默认值为 `true`。(非必选) | +| `enable_sync_point` | `BOOLEAN` 类型,是否开启 `sync point` 功能。(非必选) | +| `filter` | filter 配置。(非必选) | +| `force_replicate` | `BOOLEAN` 类型,该值默认为 `false`,当指定为 `true` 时,同步任务会尝试强制同步没有唯一索引的表。(非必选) | +| `ignore_ineligible_table` | `BOOLEAN` 类型,该值默认为 `false`,当指定为 `true` 时,同步任务会忽略无法进行同步的表。(非必选) | +| `memory_quota` | `UINT64` 类型,同步任务的内存 quota。(非必选) | +| `mounter` | 同步任务 `mounter` 配置。(非必选) | +| `sink` | 同步任务的`sink`配置。(非必选) | +| `sync_point_interval` | `STRING` 类型,注意返回值为 `UINT64` 类型的纳秒级时间,`sync point` 功能开启时,对齐上下游 snapshot 的时间间隔。默认值为 `10m`,最小值为 `30s`。(非必选) | +| `sync_point_retention` | `STRING` 类型,注意返回值为 `UINT64` 类型的纳秒级时间,`sync point` 功能开启时,在下游表中保存的数据的时长,超过这个时间的数据会被清理。默认值为 `24h`。(非必选) | + +`consistent` 参数说明如下: + +| 参数名 | 说明 | +|:-----------------|:---------------------------------------| +| `flush_interval` | `UINT64` 类型,redo log 文件 flush 间隔。(非必选) | +| `level` | `STRING` 类型,同步数据的一致性级别。(非必选) | +| `max_log_size` | `UINT64` 类型,redo log 的最大值。(非必选) | +| `storage` | `STRING` 类型,存储的目标地址。(非必选) | + +`filter` 参数说明如下: + +| 参数名 | 说明 | +|:----------------------|:--------------------------------------------------------------------------------------| +| `do_dbs` | `STRING ARRAY` 类型,需要同步的数据库。(非必选) | +| `do_tables` | 需要同步的表。(非必选) | +| `ignore_dbs` | `STRING ARRAY` 类型,不同步的数据库。(非必选) | +| `ignore_tables` | 不同步的表。(非必选) | +| `event_filters` | event 过滤配置。(非必选) | +| `ignore_txn_start_ts` | `UINT64 ARRAY` 类型,指定之后会忽略指定 `start_ts` 的事务,如 `[1, 2]`。(非必选) | +| `rules` | `STRING ARRAY` 类型,表库过滤的规则,如 `['foo*.*', 'bar*.*']`。详情请参考[表库过滤](/table-filter.md)。(非必选) | + +`filter.event_filters` 参数说明如下,可参考[日志过滤器](/ticdc/ticdc-filter.md)。 + +| 参数名 | 说明 | +|:-------------------------------|:--------------------------------------------------------------------------------------------| +| `ignore_delete_value_expr` | `STRING ARRAY` 类型,如 `"name = 'john'"` 表示过滤掉包含 `name = 'john'` 条件的 DELETE DML。(非必选) | +| `ignore_event` | `STRING ARRAY` 类型,如 `["insert"]` 表示过滤掉 INSERT 事件。(非必选) | +| `ignore_insert_value_expr` | `STRING ARRAY` 类型,如 `"id >= 100"` 表示过滤掉包含 `id >= 100` 条件的 INSERT DML。(非必选) | +| `ignore_sql` | `STRING ARRAY` 类型,如 `["^drop", "add column"]` 表示过滤掉以 `DROP` 开头或者包含 `ADD COLUMN` 的 DDL。(非必选) | +| `ignore_update_new_value_expr` | `STRING ARRAY` 类型,如 `"gender = 'male'"` 表示过滤掉新值 `gender = 'male'` 的 UPDATE DML。(非必选) | +| `ignore_update_old_value_expr` | `STRING ARRAY` 类型,如 `"age < 18"` 表示过滤掉旧值 `age < 18` 的 UPDATE DML。(非必选) | +| `matcher` | `STRING ARRAY` 类型,是一个白名单,如 `["test.worker"]`,表示该过滤规则只应用于 `test` 库中的 `worker` 表。(非必选) | + +`mounter` 参数说明如下: + +| 参数名 | 说明 | +|:-------------|:-----------------------------------------------------------| +| `worker_num` | `INT` 类型。Mounter 线程数,Mounter 用于解码 TiKV 输出的数据,默认值为 `16`。(非必选) | + +`sink` 参数说明如下: + +| 参数名 | 说明 | +|:------------------------|:--------------------------------------------------------------------------------------------------------| +| `column_selectors` | column selector 配置。(非必选) | +| `csv` | CSV 配置。(非必选) | +| `date_separator` | `STRING` 类型,文件路径的日期分隔类型。可选类型有 `none`、`year`、`month` 和 `day`。默认值为 `none`,即不使用日期分隔。(非必选) | +| `dispatchers` | 事件分发配置数组。(非必选) | +| `encoder_concurrency` | `INT` 类型。MQ sink 中编码器的线程数。默认值为 `16`。(非必选) | +| `protocol` | `STRING` 类型,对于 MQ 类的 Sink,可以指定消息的协议格式。目前支持以下协议:`canal-json`、`open-protocol`、`canal`、`avro` 和 `maxwell`。 | +| `schema_registry` | `STRING` 类型,schema registry 地址。(非必选) | +| `terminator` | `STRING` 类型,换行符,用来分隔两个数据变更事件。默认值为空,表示使用 `"\r\n"` 作为换行符。(非必选) | +| `transaction_atomicity` | `STRING` 类型,事务一致性等级。(非必选) | + +`sink.column_selectors` 是一个数组,元素参数说明如下: + +| 参数名 | 说明 | +|:----------|:------------------------------------------| +| `columns` | `STRING ARRAY` 类型,column 数组。 | +| `matcher` | `STRING ARRAY` 类型,matcher 配置,匹配语法和过滤器规则的语法相同。 | + +`sink.csv` 参数说明如下: + +| 参数名 | 说明 | +|:--------------------|:------------------------------------------------| +| `delimiter` | `STRING` 类型,字段之间的分隔符。必须为 ASCII 字符,默认值为 `,`。 | +| `include_commit_ts` | `BOOLEAN` 类型,是否在 CSV 行中包含 commit-ts。默认值为 `false`。 | +| `null` | `STRING` 类型,如果这一列是 null,那这一列该如何表示。默认是用 `\N` 来表示。 | +| `quote` | `STRING` 类型,用于包裹字段的引号字符。空值代表不使用引号字符。默认值为 `"`。 | + +`sink.dispatchers`:对于 MQ 类的 Sink,可以通过该参数配置 event 分发器,支持以下分发器:`default`、`ts`、`rowid`、`table` 。分发规则如下: + +- `default`:有多个唯一索引(包括主键)时按照 table 模式分发;只有一个唯一索引(或主键)时按照 rowid 模式分发;如果开启了 old value 特性,按照 table 模式分发。 +- `ts`:以行变更的 commitTs 做 Hash 计算并进行 event 分发。 +- `rowid`:以所选的 HandleKey 列名和列值做 Hash 计算并进行 event 分发。 +- `table`:以表的 schema 名和 table 名做 Hash 计算并进行 event 分发。 + +`sink.dispatchers` 是一个数组,元素参数说明如下: + +| 参数名 | 说明 | +|:------------|:----------------------------------| +| `matcher` | `STRING ARRAY` 类型,匹配语法和过滤器规则的语法相同。 | +| `partition` | `STRING` 类型,事件分发的目标 partition。 | +| `topic` | `STRING` 类型,事件分发的目标 topic。 | + +### 使用样例 + +以下请求会创建一个 ID 为 `test5`,sink_uri 为 `blackhole://` 的同步任务。 + +```shell +curl -X POST -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v2/changefeeds -d '{"changefeed_id":"test5","sink_uri":"blackhole://"}' +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 + +### 响应体格式 + +```json +{ + "admin_job_type": 0, + "checkpoint_time": "string", + "checkpoint_ts": 0, + "config": { + "bdr_mode": true, + "case_sensitive": true, + "check_gc_safe_point": true, + "consistent": { + "flush_interval": 0, + "level": "string", + "max_log_size": 0, + "storage": "string" + }, + "enable_old_value": true, + "enable_sync_point": true, + "filter": { + "do_dbs": [ + "string" + ], + "do_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "event_filters": [ + { + "ignore_delete_value_expr": "string", + "ignore_event": [ + "string" + ], + "ignore_insert_value_expr": "string", + "ignore_sql": [ + "string" + ], + "ignore_update_new_value_expr": "string", + "ignore_update_old_value_expr": "string", + "matcher": [ + "string" + ] + } + ], + "ignore_dbs": [ + "string" + ], + "ignore_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "ignore_txn_start_ts": [ + 0 + ], + "rules": [ + "string" + ] + }, + "force_replicate": true, + "ignore_ineligible_table": true, + "memory_quota": 0, + "mounter": { + "worker_num": 0 + }, + "sink": { + "column_selectors": [ + { + "columns": [ + "string" + ], + "matcher": [ + "string" + ] + } + ], + "csv": { + "delimiter": "string", + "include_commit_ts": true, + "null": "string", + "quote": "string" + }, + "date_separator": "string", + "dispatchers": [ + { + "matcher": [ + "string" + ], + "partition": "string", + "topic": "string" + } + ], + "enable_partition_separator": true, + "encoder_concurrency": 0, + "protocol": "string", + "schema_registry": "string", + "terminator": "string", + "transaction_atomicity": "string" + }, + "sync_point_interval": "string", + "sync_point_retention": "string" + }, + "create_time": "string", + "creator_version": "string", + "error": { + "addr": "string", + "code": "string", + "message": "string" + }, + "id": "string", + "resolved_ts": 0, + "sink_uri": "string", + "start_ts": 0, + "state": "string", + "target_ts": 0, + "task_status": [ + { + "capture_id": "string", + "table_ids": [ + 0 + ] + } + ] +} +``` + +参数说明如下: + +| 参数名 | 说明 | +|:------------------|:---------------------------------------------------------------| +| `admin_job_type` | `INTEGER` 类型,admin 事件类型 | +| `checkpoint_time` | `STRING` 类型,同步任务当前 checkpoint 的格式化时间表示 | +| `checkpoint_ts` | `STRING` 类型,同步任务当前 checkpoint 的 TSO 表示 | +| `config` | 同步任务配置,结构和含义与创建同步任务中的 `replica_config` 配置项相同 | +| `create_time` | `STRING` 类型,同步任务创建的时间 | +| `creator_version` | `STRING` 类型,同步任务创建时 TiCDC 的版本 | +| `error` | 同步任务错误 | +| `id` | `STRING` 类型,同步任务 ID | +| `resolved_ts` | `UINT64` 类型,同步任务 resolved ts | +| `sink_uri` | `STRING` 类型,同步任务的 sink uri | +| `start_ts` | `UINT64` 类型,同步任务 start ts | +| `state` | `STRING` 类型,同步任务状态,状态可分为 `normal`、`stopped`、`error`、`failed`、`finished` | +| `target_ts` | `UINT64` 类型,同步任务的 target ts | +| `task_status` | 同步任务分发的详细状态 | + +`task_status` 参数说明如下: + +| 参数名 | 说明 | +|:-------------|:--------------------------------------------| +| `capture_id` | `STRING` 类型,`Capture` ID | +| `table_ids` | `UINT64 ARRAY` 类型,该 Capture 上正在同步的 table 的 ID | + +`error` 参数说明如下: + +| 参数名 | 说明 | +|:-------|:-------------------------| +| `addr` | `STRING` 类型,`Capture` 地址 | +| `code` | `STRING` 类型,错误码 | +| `message` | `STRING` 类型,错误的详细信息 | + +## 删除同步任务 + +该接口是幂等的(即其任意多次执行所产生的影响均与一次执行的影响相同),用于删除一个 changefeed 同步任务,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +### 请求 URI + +`DELETE /api/v2/changefeeds/{changefeed_id}` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:----------------------------| +| `changefeed_id` | 需要删除的同步任务 (changefeed) 的 ID | + +### 使用样例 + +以下请求会删除 ID 为 `test1` 的同步任务。 + +```shell +curl -X DELETE http://127.0.0.1:8300/api/v2/changefeeds/test1 +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 + +## 更新同步任务配置 + +该接口用于更新一个同步任务,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +修改 changefeed 配置需要按照`暂停任务 -> 修改配置 -> 恢复任务`的流程。 + +### 请求 URI + +`PUT /api/v2/changefeeds/{changefeed_id}` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:----------------------------| +| `changefeed_id` | 需要更新的同步任务 (changefeed) 的 ID | + +#### 请求体参数 + +```json +{ + "replica_config": { + "bdr_mode": true, + "case_sensitive": true, + "check_gc_safe_point": true, + "consistent": { + "flush_interval": 0, + "level": "string", + "max_log_size": 0, + "storage": "string" + }, + "enable_old_value": true, + "enable_sync_point": true, + "filter": { + "do_dbs": [ + "string" + ], + "do_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "event_filters": [ + { + "ignore_delete_value_expr": "string", + "ignore_event": [ + "string" + ], + "ignore_insert_value_expr": "string", + "ignore_sql": [ + "string" + ], + "ignore_update_new_value_expr": "string", + "ignore_update_old_value_expr": "string", + "matcher": [ + "string" + ] + } + ], + "ignore_dbs": [ + "string" + ], + "ignore_tables": [ + { + "database_name": "string", + "table_name": "string" + } + ], + "ignore_txn_start_ts": [ + 0 + ], + "rules": [ + "string" + ] + }, + "force_replicate": true, + "ignore_ineligible_table": true, + "memory_quota": 0, + "mounter": { + "worker_num": 0 + }, + "sink": { + "column_selectors": [ + { + "columns": [ + "string" + ], + "matcher": [ + "string" + ] + } + ], + "csv": { + "delimiter": "string", + "include_commit_ts": true, + "null": "string", + "quote": "string" + }, + "date_separator": "string", + "dispatchers": [ + { + "matcher": [ + "string" + ], + "partition": "string", + "topic": "string" + } + ], + "enable_partition_separator": true, + "encoder_concurrency": 0, + "protocol": "string", + "schema_registry": "string", + "terminator": "string", + "transaction_atomicity": "string" + }, + "sync_point_interval": "string", + "sync_point_retention": "string" + }, + "sink_uri": "string", + "target_ts": 0 +} +``` + +目前仅支持通过 API 修改同步任务的如下配置。 + +| 参数名 | 说明 | +|:-----------------|:----------------------------------------| +| `target_ts` | `UINT64` 类型,指定 changefeed 的目标 TSO。(非必选) | +| `sink_uri` | `STRING` 类型,同步任务下游的地址。(非必选) | +| `replica_config` | sink 的配置参数, 必须是完整的配置。(非必选) | + +以上参数含义与[创建同步任务](#创建同步任务)中的参数相同,此处不再赘述。 + +### 使用样例 + +以下请求会更新 ID 为 `test1` 的同步任务的 `target_ts` 为 `32`。 + +```shell + curl -X PUT -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v2/changefeeds/test1 -d '{"target_ts":32}' +``` + +若是请求成功,则返回 `200 OK`,若请求失败,则返回错误信息和错误码。响应的 JSON 格式以及字段含义与[创建同步任务](#创建同步任务)中的响应参数相同,此处不再赘述。 + +## 查询同步任务列表 + +该接口是一个同步接口,请求成功会返回 TiCDC 集群中所有同步任务 (changefeed) 的基本信息。 + +### 请求 URI + +`GET /api/v2/changefeeds` + +### 参数说明 + +#### 查询参数 + +| 参数名 | 说明 | +|:--------|:------------------------| +| `state` | 非必选,指定后将会只返回该状态的同步任务的信息 | + +`state` 可选值为 `all`、`normal`、`stopped`、`error`、`failed`、`finished`。 + +若不指定该参数,则默认返回处于 `normal`、`stopped`、`failed` 状态的同步任务基本信息。 + +### 使用样例 + +以下请求查询所有状态 (state) 为 `normal` 的同步任务的基本信息。 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/changefeeds?state=normal +``` + +```json +{ + "total": 2, + "items": [ + { + "id": "test", + "state": "normal", + "checkpoint_tso": 439749918821711874, + "checkpoint_time": "2023-02-27 23:46:52.888", + "error": null + }, + { + "id": "test2", + "state": "normal", + "checkpoint_tso": 439749918821711874, + "checkpoint_time": "2023-02-27 23:46:52.888", + "error": null + } + ] +} +``` + +以上返回的信息的说明如下: + +- `id`:同步任务的 ID。 +- `state`:同步任务当前所处的[状态](/ticdc/ticdc-changefeed-overview.md#changefeed-状态流转)。 +- `checkpoint_tso`:同步任务当前 checkpoint 的 TSO 表示。 +- `checkpoint_time`:同步任务当前 checkpoint 的格式化时间表示。 +- `error`:同步任务的错误信息。 + +## 查询特定同步任务 + +该接口是一个同步接口,请求成功会返回指定同步任务 (changefeed) 的详细信息。 + +### 请求 URI + +`GET /api/v2/changefeeds/{changefeed_id}` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:----------------------------| +| `changefeed_id` | 需要查询的同步任务 (changefeed) 的 ID | + +### 使用样例 + +以下请求会查询 ID 为 `test1` 的同步任务的详细信息。 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/changefeeds/test1 +``` + +响应的 JSON 格式以及字段含义与[创建同步任务](#创建同步任务)中的响应参数相同,此处不再赘述。 + +## 暂停同步任务 + +该接口暂停一个同步任务,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +### 请求 URI + +`POST /api/v2/changefeeds/{changefeed_id}/pause` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:----------------------------| +| `changefeed_id` | 需要暂停的同步任务 (changefeed) 的 ID | + +### 使用样例 + +以下请求会暂停 ID 为 `test1` 的同步任务。 + +```shell +curl -X POST http://127.0.0.1:8300/api/v2/changefeeds/test1/pause +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 + +## 恢复同步任务 + +该接口恢复一个同步任务,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +### 请求 URI + +`POST /api/v2/changefeeds/{changefeed_id}/resume` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:----------------------------| +| `changefeed_id` | 需要恢复的同步任务 (changefeed) 的 ID | + +#### 请求体参数 + +```json +{ + "overwrite_checkpoint_ts": 0 +} +``` + +| 参数名 | 说明 | +|:--------------------------|:------------------------------------------------------| +| `overwrite_checkpoint_ts` | `UINT64` 类型,恢复同步任务 (changefeed) 时重新指定的 checkpoint TSO | + +### 使用样例 + +以下请求会恢复 ID 为 `test1` 的同步任务。 + +```shell +curl -X POST http://127.0.0.1:8300/api/v2/changefeeds/test1/resume -d '{}' +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 + +## 查询同步子任务列表 + +该接口是一个同步接口,请求成功会返回当前 TiCDC 集群中的所有同步子任务 (`processor`) 的基本信息。 + +### 请求 URI + +`GET /api/v2/processors` + +### 使用样例 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/processors +``` + +```json +{ + "total": 3, + "items": [ + { + "changefeed_id": "test2", + "capture_id": "d2912e63-3349-447c-90ba-72a4e04b5e9e" + }, + { + "changefeed_id": "test1", + "capture_id": "d2912e63-3349-447c-90ba-72a4e04b5e9e" + }, + { + "changefeed_id": "test", + "capture_id": "d2912e63-3349-447c-90ba-72a4e04b5e9e" + } + ] +} +``` + +以上返回的信息的说明如下: + +- `changefeed_id`:同步任务的 ID。 +- `capture_id`:`Capture` 的 ID。 + +## 查询特定同步子任务 + +该接口是一个同步接口,请求成功会返回指定同步子任务 (`processor`) 的详细信息。 + +### 请求 URI + +`GET /api/v2/processors/{changefeed_id}/{capture_id}` + +### 参数说明 + +#### 路径参数 + +| 参数名 | 说明 | +|:----------------|:------------------------| +| `changefeed_id` | 需要查询的子任务的 Changefeed ID | +| `capture_id` | 需要查询的子任务的 Capture ID | + +### 使用样例 + +以下请求查询 `changefeed_id` 为 `test`、`capture_id` 为 `561c3784-77f0-4863-ad52-65a3436db6af` 的同步子任务。一个同步子任务通过 `changefeed_id` 和 `capture_id` 来标识。 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/processors/test/561c3784-77f0-4863-ad52-65a3436db6af +``` + +```json +{ + "table_ids": [ + 80 + ] +} +``` + +以上返回的信息的说明如下: + +- `table_ids`:在这个 capture 上同步的 table 的 ID。 + +## 查询 TiCDC 服务进程列表 + +该接口是一个同步接口,请求成功会返回当前 TiCDC 集群中的所有服务进程 (`capture`) 的基本信息。 + +### 请求 URI + +`GET /api/v2/captures` + +### 使用样例 + +```shell +curl -X GET http://127.0.0.1:8300/api/v2/captures +``` + +```json +{ + "total": 1, + "items": [ + { + "id": "d2912e63-3349-447c-90ba-72a4e04b5e9e", + "is_owner": true, + "address": "127.0.0.1:8300" + } + ] +} +``` + +以上返回的信息的说明如下: + +- `id`:`capture` 的 ID。 +- `is_owner`:该 `capture` 是否是 owner 。 +- `address`:该 `capture` 的地址。 + +## 驱逐 owner 节点 + +该接口是一个异步的请求,请求成功会返回 `200 OK`。该返回结果表示服务器收到了执行命令指示,并不代表命令被成功执行。 + +### 请求 URI + +`POST /api/v2/owner/resign` + +### 使用样例 + +以下请求会驱逐 TiCDC 当前的 owner 节点,并会触发新一轮的选举,产生新的 owner 节点。 + +```shell +curl -X POST http://127.0.0.1:8300/api/v2/owner/resign +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 + +## 动态调整 TiCDC Server 日志级别 + +该接口是一个同步接口,请求成功会返回 `200 OK`。 + +### 请求 URI + +`POST /api/v2/log` + +### 请求参数 + +#### 请求体参数 + +| 参数名 | 说明 | +|:------------|:----------| +| `log_level` | 想要设置的日志等级 | + +`log_level` 支持 [zap 提供的日志级别](https://godoc.org/go.uber.org/zap#UnmarshalText):"debug"、"info"、"warn"、"error"、"dpanic"、"panic"、"fatal"。 + +### 使用样例 + +```shell +curl -X POST -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v2/log -d '{"log_level":"debug"}' +``` + +如果请求成功,则返回 `200 OK`。如果请求失败,则返回错误信息和错误码。 diff --git a/ticdc/ticdc-open-api.md b/ticdc/ticdc-open-api.md index 44558a835a17..5b4dd640bc6c 100644 --- a/ticdc/ticdc-open-api.md +++ b/ticdc/ticdc-open-api.md @@ -1,9 +1,13 @@ --- -title: TiCDC OpenAPI +title: TiCDC OpenAPI v1 summary: 了解如何使用 OpenAPI 接口来管理集群状态和数据同步。 --- -# TiCDC OpenAPI +# TiCDC OpenAPI v1 + +> **注意:** +> +> TiCDC OpenAPI v1 将在未来版本中被删除。推荐使用 [TiCDC OpenAPI v2](/ticdc/ticdc-open-api-v2.md)。 TiCDC 提供 OpenAPI 功能,你可以通过 OpenAPI 对 TiCDC 集群进行查询和运维操作。OpenAPI 的总体功能和 [`cdc cli` 工具](/ticdc/ticdc-manage-changefeed.md)类似。 @@ -157,7 +161,7 @@ curl -X GET http://127.0.0.1:8300/api/v1/health ### 使用样例 -以下请求会创建一个 ID 为 `test5`,sink_uri 为 `blackhome://` 的同步任务。 +以下请求会创建一个 ID 为 `test5`,sink_uri 为 `blackhole://` 的同步任务。 ```shell curl -X POST -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v1/changefeeds -d '{"changefeed_id":"test5","sink_uri":"blackhole://"}' diff --git a/ticdc/ticdc-sink-to-cloud-storage.md b/ticdc/ticdc-sink-to-cloud-storage.md index b72072a700c4..edeb45ff211c 100644 --- a/ticdc/ticdc-sink-to-cloud-storage.md +++ b/ticdc/ticdc-sink-to-cloud-storage.md @@ -5,11 +5,7 @@ summary: 了解如何使用 TiCDC 将数据同步到存储服务,以及数据 # 同步数据到存储服务 -> **警告:** -> -> 当前该功能为实验特性,不建议在生产环境中使用。 - -从 v6.5.0 开始,TiCDC 支持将行变更事件保存至存储服务,如 Amazon S3、Azure Blob Storage 和 NFS。本文介绍如何使用 TiCDC 创建同步任务 (Changefeed) 将增量数据同步到这类存储服务,并介绍数据的存储方式。具体如下: +从 TiDB v6.5.0 开始,TiCDC 支持将行变更事件保存至存储服务,如 Amazon S3、GCS、Azure Blob Storage 和 NFS。本文介绍如何使用 TiCDC 创建同步任务 (Changefeed) 将增量数据同步到这类存储服务,并介绍数据的存储方式。具体如下: - [如何将变更数据同步至存储服务](#同步变更数据至存储服务)。 - [变更数据如何在存储服务中保存](#存储路径组织结构)。 @@ -41,9 +37,9 @@ Info: {"upstream_id":7171388873935111376,"namespace":"default","id":"simple-repl 本章节介绍如何在 Changefeed URI 中配置存储服务 Amazon S3、Azure Blob Storage 和 NFS。 -### 配置 Amazon S3 和 Azure Blob Storage +### 配置外部存储 -Amazon S3 和 Azure Blob Storage 的 URI 参数与 BR 中这两种存储的 URL 参数相同。详细参数说明请参考 [BR 备份存储服务的 URI 格式](/br/backup-and-restore-storages.md#格式说明)。 +Amazon S3、GCS 以及 Azure Blob Storage 的 URI 参数与 BR 中这三种存储的 URI 参数相同。详细参数说明请参考 [BR 备份存储服务的 URI 格式](/br/backup-and-restore-storages.md#格式说明)。 ### 配置 NFS @@ -101,6 +97,22 @@ URI 中其他可配置的参数如下: > - 发生 DDL 操作后,表的版本为该 DDL 在上游 TiDB 执行结束的 TSO。但是,表版本的变化并不意味着表结构的变化。例如,在表中的某一列添加注释,不会导致 `schema.json` 文件内容发生变化。 > - 进程重启,表的版本为进程重启时 Changefeed 的 checkpoint TSO。在有很多表的情况下,重启时需要遍历所有目录并找到上一次重启时每张表写入的位置,这样的操作耗时较长。因此,TiCDC 选择在一个以 checkpoint TSO 为版本的新目录下写入数据,而不是在旧版本的目录下继续写入数据。 +### Index 文件 + +Index 文件用于防止已写入的数据被错误覆盖,与数据变更记录存储在相同路径: + +```shell +{scheme}://{prefix}/{schema}/{table}/{table-version-separator}/{partition-separator}/{date-separator}/CDC.index +``` + +Index 文件记录了当前目录下所使用到的最大文件名,比如: + +``` +CDC000005.csv +``` + +上述内容表明该目录下 `CDC000001.csv` 到 `CDC000004.csv` 文件已被占用,当 TiCDC 集群中发生表调度或者节点重启时,新的节点会读取 Index 文件,并判断 `CDC000005.csv` 是否被占用。如果未被占用,则新节点会从 `CDC000005.csv` 开始写文件。如果已被占用,则从 `CDC000006.csv` 开始写文件,这样可防止覆盖其他节点写入的数据。 + ### 元数据 元数据信息将会存储到以下路径: diff --git a/ticdc/ticdc-sink-to-kafka.md b/ticdc/ticdc-sink-to-kafka.md index 326e509366dc..a2676ed5e654 100644 --- a/ticdc/ticdc-sink-to-kafka.md +++ b/ticdc/ticdc-sink-to-kafka.md @@ -67,14 +67,14 @@ URI 中可配置的的参数如下: | `cert` | 连接下游 Kafka 实例所需的证书文件路径(可选)。 | | `key` | 连接下游 Kafka 实例所需的证书密钥文件路径(可选)。 | | `sasl-user` | 连接下游 Kafka 实例所需的 SASL/PLAIN 或 SASL/SCRAM 认证的用户名(authcid)(可选)。 | -| `sasl-password` | 连接下游 Kafka 实例所需的 SASL/PLAIN 或 SASL/SCRAM 认证的密码(可选)。 | +| `sasl-password` | 连接下游 Kafka 实例所需的 SASL/PLAIN 或 SASL/SCRAM 认证的密码(可选)。如有特殊字符,需要用 URL encode 转义。 | | `sasl-mechanism` | 连接下游 Kafka 实例所需的 SASL 认证方式的名称,可选值有 `plain`、`scram-sha-256`、`scram-sha-512` 和 `gssapi`。 | | `sasl-gssapi-auth-type` | gssapi 认证类型,可选值有 `user` 和 `keytab`(可选)。 | | `sasl-gssapi-keytab-path` | gssapi keytab 路径(可选)。| | `sasl-gssapi-kerberos-config-path` | gssapi kerberos 配置路径(可选)。 | | `sasl-gssapi-service-name` | gssapi 服务名称(可选)。 | | `sasl-gssapi-user` | gssapi 认证使用的用户名(可选)。 | -| `sasl-gssapi-password` | gssapi 认证使用的密码(可选)。 | +| `sasl-gssapi-password` | gssapi 认证使用的密码(可选)。如有特殊字符,需要用 URL encode 转义。 | | `sasl-gssapi-realm` | gssapi realm 名称(可选)。 | | `sasl-gssapi-disable-pafxfast` | gssapi 是否禁用 PA-FX-FAST(可选)。 | | `dial-timeout` | 和下游 Kafka 建立连接的超时时长,默认值为 `10s`。 | @@ -244,12 +244,20 @@ partition 分发器用 partition = "xxx" 来指定,支持 default、ts、index > **警告:** > -> - 横向扩展功能目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 -> - TiCDC v6.6.0 仅支持在 Kafka 同步任务上开启大单表的横向扩展功能。 +> TiCDC v7.0.0 仅支持在 Kafka 同步任务上开启大单表的横向扩展功能。 配置样例如下所示: ```toml [scheduler] -region-per-span = 50000 +# 设置为 "true" 以打开该功能。 +enable-table-across-nodes = true +# 打开该功能后,该功能只对 Region 个数大于 `region-threshold` 值的表生效。 +region-threshold = 100000 +``` + +一个表包含的 Region 个数可用如下 SQL 查询: + +```sql +SELECT COUNT(*) FROM INFORMATION_SCHEMA.TIKV_REGION_STATUS WHERE DB_NAME="database1" AND TABLE_NAME="table1" AND IS_INDEX=0; ``` diff --git a/tidb-binlog/tidb-binlog-faq.md b/tidb-binlog/tidb-binlog-faq.md index c5826e5de64f..700de1a1b426 100644 --- a/tidb-binlog/tidb-binlog-faq.md +++ b/tidb-binlog/tidb-binlog-faq.md @@ -17,9 +17,9 @@ aliases: ['/docs-cn/dev/tidb-binlog/tidb-binlog-faq/','/docs-cn/dev/reference/ti TiDB Binlog 的同步延迟为秒级别,在非业务高峰时延迟一般为 3 秒左右。 -## Drainer 同步下游 TiDB/MySQL 的帐号需要哪些权限? +## Drainer 同步下游 TiDB/MySQL 的账号需要哪些权限? -Drainer 同步帐号需要有如下权限: +Drainer 同步账号需要有如下权限: * Insert * Update diff --git a/tidb-configuration-file.md b/tidb-configuration-file.md index 1bfa0f5c73bb..18d077d0aa16 100644 --- a/tidb-configuration-file.md +++ b/tidb-configuration-file.md @@ -211,7 +211,7 @@ TiDB 配置文件比命令行参数支持更多的选项。你可以在 [config/ + 控制是否开启表级锁特性。 + 默认值:false -+ 表级锁用于协调多个 session 之间对同一张表的并发访问。目前已支持的锁种类包括 `READ`、`WRITE` 和 `WRITE LOCAL`。当该配置项为 `false` 时,执行 `LOCK TABLE` 和 `UNLOCK TABLE` 语句不会生效,并且会报 "LOCK/UNLOCK TABLES is not supported" 的警告。 ++ 表级锁用于协调多个 session 之间对同一张表的并发访问。目前已支持的锁种类包括 `READ`、`WRITE` 和 `WRITE LOCAL`。当该配置项为 `false` 时,执行 `LOCK TABLES` 和 `UNLOCK TABLES` 语句不会生效,并且会报 "LOCK/UNLOCK TABLES is not supported" 的警告。更多信息,请参考 [`LOCK TABLES` 和 `UNLOCK TABLES`](/sql-statements/sql-statement-lock-tables-and-unlock-tables.md)。 ## log diff --git a/tidb-lightning/tidb-lightning-configuration.md b/tidb-lightning/tidb-lightning-configuration.md index d3738796a34a..1aa158abeda7 100644 --- a/tidb-lightning/tidb-lightning-configuration.md +++ b/tidb-lightning/tidb-lightning-configuration.md @@ -52,7 +52,7 @@ table-concurrency = 6 # 数据的并发数。默认与逻辑 CPU 的数量相同。 # 混合部署的情况下可以将其大小配置为逻辑 CPU 数的 75%,以限制 CPU 的使用。 -# region-concurrency = +# region-concurrency = # I/O 最大并发数。I/O 并发量太高时,会因硬盘内部缓存频繁被刷新 # 而增加 I/O 等待时间,导致缓存未命中和读取速度降低。 @@ -63,6 +63,7 @@ io-concurrency = 5 # 在忽略非严重错误所在的行数据之后,迁移任务可以继续执行。 # 将该值设置为 N,表示 TiDB Lightning 会在遇到第 (N+1) 个错误时停止迁移任务。 # 被忽略的行会被记录到位于目标集群的 "task info" 数据库中。最大错误数可以通过下面参数配置。 +# 默认值为 MaxInt64 字节,即 9223372036854775807 字节。 max-error = 0 # 参数 task-info-schema-name 指定用于存储 TiDB Lightning 执行结果的数据库。 # 要关闭该功能,需要将该值设置为空字符串。 @@ -146,6 +147,12 @@ addr = "172.16.31.10:8287" # 默认值为 MaxInt64 字节,即 9223372036854775807 字节。 # disk-quota = "10GB" +# Physical Import Mode 是否通过 SQL 方式添加索引。默认为 `false`,表示 TiDB Lightning 会将行数据以及索引数据都编码成 KV pairs 后一同导入 TiKV,实现机制和历史版本保持一致。如果设置为 `true`,即 TiDB Lightning 会在导入数据完成后,使用 add index 的 SQL 来添加索引。 +# 通过 SQL 方式添加索引的优点是将导入数据与导入索引分开,可以快速导入数据,即使导入数据后,索引添加失败,也不会影响数据的一致性。 +# add-index-by-sql = false + +# 在使用 TiDB Lightning 导入多租户的 TiDB cluster 的场景下,指定对应的 key space 名称。默认取值为空字符串,表示 TiDB Lightning 会自动获取导入对应租户的 key space 名称;如果指定了值,则使用指定的 key space 名称来导入。 +# keyspace-name = "" [mydumper] # 设置文件读取的区块大小,确保该值比数据源的最长字符串长。 read-block-size = "64KiB" # 默认值 @@ -254,9 +261,9 @@ log-level = "error" # 设置 TiDB 会话变量,提升 Checksum 和 Analyze 的速度。 # 各参数定义可参阅”控制 Analyze 并发度“文档 build-stats-concurrency = 20 -distsql-scan-concurrency = 100 +distsql-scan-concurrency = 15 index-serial-scan-concurrency = 20 -checksum-table-concurrency = 16 +checksum-table-concurrency = 2 # 解析和执行 SQL 语句的默认 SQL 模式。 sql-mode = "ONLY_FULL_GROUP_BY,NO_ENGINE_SUBSTITUTION" diff --git a/tidb-lightning/tidb-lightning-physical-import-mode-usage.md b/tidb-lightning/tidb-lightning-physical-import-mode-usage.md index 3f81ddeb43ca..e3076ed66894 100644 --- a/tidb-lightning/tidb-lightning-physical-import-mode-usage.md +++ b/tidb-lightning/tidb-lightning-physical-import-mode-usage.md @@ -40,6 +40,10 @@ sorted-kv-dir = "./some-dir" # 限制 TiDB Lightning 向每个 TiKV 节点写入的带宽大小,默认为 0,表示不限制。 # store-write-bwlimit = "128MiB" +# Physical Import Mode 是否通过 SQL 方式添加索引。默认为 `false`,表示 TiDB Lightning 会将行数据以及索引数据都编码成 KV pairs 后一同导入 TiKV,实现机制和历史版本保持一致。如果设置为 `true`,即 TiDB Lightning 会导完数据后,再使用 add index 的 SQL 来添加索引。 +# 通过 SQL 方式添加索引的优点是将导入数据与导入索引分开,可以快速导入数据,即使导入数据后,索引添加失败,也不会影响数据的一致性。 +# add-index-by-sql = false + [tidb] # 目标集群的信息。tidb-server 的地址,填一个即可。 host = "172.16.31.1" diff --git a/tidb-lightning/tidb-lightning-physical-import-mode.md b/tidb-lightning/tidb-lightning-physical-import-mode.md index 3d31486ca6ae..f32d6c270742 100644 --- a/tidb-lightning/tidb-lightning-physical-import-mode.md +++ b/tidb-lightning/tidb-lightning-physical-import-mode.md @@ -18,15 +18,19 @@ Physical Import Mode 对应的后端模式为 `local`。 2. `tidb-lightning` 在目标数据库建立表结构,并获取其元数据。 + 如果将 `add-index-by-sql` 设置为 `true`,`tidb-lightning` 会使用 SQL 接口添加索引,并且会在导入数据前移除目标表的所有次级索引。 + 3. 每张表都会被分割为多个连续的**区块**,这样来自大表 (200 GB+) 的数据就可以多个并发导入。 4. `tidb-lightning` 会为每一个区块准备一个“引擎文件 (engine file)”来处理键值对。`tidb-lightning` 会并发读取 SQL dump,将数据源转换成与 TiDB 相同编码的键值对,然后将这些键值对排序写入本地临时存储文件中。 5. 当一个引擎文件数据写入完毕时,`tidb-lightning` 便开始对目标 TiKV 集群数据进行分裂和调度,然后导入数据到 TiKV 集群。 - 引擎文件包含两种:**数据引擎**与**索引引擎**,各自又对应两种键值对:行数据和次级索引。通常行数据在数据源里是完全有序的,而次级索引是无序的。因此,数据引擎文件在对应区块写入完成后会被立即上传,而所有的索引引擎文件只有在整张表所有区块编码完成后才会执行导入。 + 引擎文件包含两种:**数据引擎**与**索引引擎**,各自又对应两种键值对:行数据和次级索引。通常行数据在数据源里是完全有序的,而次级索引是无序的。因此,数据引擎文件在对应区块写入完成后会被立即上传,而所有的索引引擎文件只有在整张表所有区块编码完成后才会执行导入。 + + 注意当 `tidb-lightning` 使用 SQL 接口添加索引时(即 `add-index-by-sql` 设置为 `true`),索引引擎将不会写入数据,因为此时目标表的次级索引已经在第 2 步中被移除。 -6. 整张表相关联的所有引擎文件完成导入后,`tidb-lightning` 会对比本地数据源及下游集群的校验和 (checksum),确保导入的数据无损,然后让 TiDB 分析 (`ANALYZE`) 这些新增的数据,以优化日后的操作。同时,`tidb-lightning` 调整 `AUTO_INCREMENT` 值防止之后新增数据时发生冲突。 +6. 整张表相关联的所有引擎文件完成导入后,`tidb-lightning` 会对比本地数据源及下游集群的校验和 (checksum),确保导入的数据无损,然后添加在第 2 步中被移除的次级索引或让 TiDB 分析 (`ANALYZE`) 这些新增的数据,以优化日后的操作。同时,`tidb-lightning` 调整 `AUTO_INCREMENT` 值防止之后新增数据时发生冲突。 表的自增 ID 是通过行数的**上界**估计值得到的,与表的数据文件总大小成正比。因此,最后的自增 ID 通常比实际行数大得多。这属于正常现象,因为在 TiDB 中自增 ID [不一定是连续分配的](/mysql-compatibility.md#自增-id)。 diff --git a/tidb-read-staleness.md b/tidb-read-staleness.md index bbea3ebf6814..26f96db8ed8e 100644 --- a/tidb-read-staleness.md +++ b/tidb-read-staleness.md @@ -21,6 +21,10 @@ summary: 了解如何通过系统变量 `tidb_read_staleness` 读取历史数据 - 结束当前会话。 - 使用 `SET` 语句,把 `tidb_read_staleness` 变量的值设为 `""`。 +> **注意:** +> +> 你可以通过调整 TiKV 的 `advance-ts-interval` 配置项提高 Stale Read 数据的时效性(即减少延时),详情参见[减少 Stale Read 延时](/stale-read.md#减少-stale-read-延时)。 + ## 示例 本节通过具体操作示例介绍系统变量 `tidb_read_staleness`的使用方法。 diff --git a/tidb-resource-control.md b/tidb-resource-control.md index f24ca28ffe83..d4fb17de587b 100644 --- a/tidb-resource-control.md +++ b/tidb-resource-control.md @@ -7,14 +7,14 @@ summary: 介绍如何通过资源管控能力来实现对应用资源消耗的 > **警告:** > -> 资源管控是 TiDB 在 v6.6.0 中引入的实验特性,其语法或者行为表现在 GA 前可能会发生变化。 +> 资源管控是 TiDB 在 v7.0.0 是实验特性,其语法或者行为表现在 GA 前可能会发生变化。 -使用资源管控特性,集群管理员可以定义资源组 (Resource Group),通过资源组限定读写的配额。将用户绑定到某个资源组后,TiDB 层会根据用户所绑定资源组设定的读写配额对用户的读写请求做流控,TiKV 层会根据读写配额映射的优先级来对请求做调度。通过流控和调度这两层控制,你可以实现应用的资源隔离,满足服务质量 (QoS) 要求。 +使用资源管控特性,集群管理员可以定义资源组 (Resource Group),通过资源组限定读写的配额。 -TiDB 资源管控特性提供了两层资源管理能力,包括在 TiDB 层的流控能力和 TiKV 层的优先级调度的能力。两个能力可以单独或者同时开启,详情请参见[参数组合效果表](#相关参数)。 +TiDB 资源管控特性提供了两层资源管理能力,包括在 TiDB 层的流控能力和 TiKV 层的优先级调度的能力。两个能力可以单独或者同时开启,详情请参见[参数组合效果表](#相关参数)。将用户绑定到某个资源组后,TiDB 层会根据用户所绑定资源组设定的读写配额对用户的读写请求做流控,TiKV 层会根据读写配额映射的优先级来对请求做调度。通过流控和调度这两层控制,可以实现应用的资源隔离,满足服务质量 (QoS) 要求。 -- TiDB 流控:TiDB 流控使用[令牌桶算法](https://en.wikipedia.org/wiki/Token_bucket) 做流控;如果桶内令牌数不够,而且资源组没有指定 `BURSTABLE` 特性,属于该资源组的请求会等待令牌桶回填令牌并重试,重试可能会超时失败。 -- TiKV 调度:如果开启该特性,TiKV 使用基于资源组 `RU_PER_SEC` 的取值映射成各自资源组读写请求的优先级,基于各自的优先级在存储层使用优先级队列调度处理请求。 +- TiDB 流控:TiDB 流控使用[令牌桶算法](https://en.wikipedia.org/wiki/Token_bucket) 做流控。如果桶内令牌数不够,而且资源组没有指定 `BURSTABLE` 特性,属于该资源组的请求会等待令牌桶回填令牌并重试,重试可能会超时失败。 +- TiKV 调度:你可以为资源组设置绝对优先级 ([`PRIORITY`](/information-schema/information-schema-resource-groups.md#示例)),不同的资源按照 `PRIORITY` 的设置进行调度,`PRIORITY` 高的任务会被优先调度。如果没有设置绝对优先级 (`PRIORITY`),TiKV 会将资源组的 `RU_PER_SEC` 取值映射成各自资源组读写请求的优先级,并基于各自的优先级在存储层使用优先级队列调度处理请求。 ## 使用场景 @@ -25,6 +25,13 @@ TiDB 资源管控特性提供了两层资源管理能力,包括在 TiDB 层的 此外,合理利用资源管控特性可以减少集群数量,降低运维难度及管理成本。 +## 使用限制 + +目前,资源管控特性具有以下限制: + +- 只支持对前台客户发起的读写请求做限流和调度,不支持对 DDL 以及 Auto Analyze 等后台任务的限流和调度。 +- 资源管控将带来额外的调度开销。因此,开启该特性后,性能可能会有轻微下降。 + ## 什么是 Request Unit (RU) Request Unit (RU) 是 TiDB 对 CPU、IO 等系统资源的统一抽象的单位, 目前包括 CPU、IOPS 和 IO 带宽三个指标。这三个指标的消耗会按照一定的比例统一到 RU 单位上。 @@ -47,8 +54,8 @@ Request Unit (RU) 是 TiDB 对 CPU、IO 等系统资源的统一抽象的单位, 资源管控特性引入了两个新的全局开关变量: -* TiDB: 通过配置全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 控制是否打开资源组流控。 -* TiKV: 通过配置参数 [`resource-control.enabled`](/tikv-configuration-file.md#resource-control) 控制是否使用基于资源组配额的请求调度。 +- TiDB: 通过配置全局变量 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 控制是否打开资源组流控。 +- TiKV: 通过配置参数 [`resource-control.enabled`](/tikv-configuration-file.md#resource-control) 控制是否使用基于资源组配额的请求调度。 这两个参数的组合效果见下表: @@ -57,36 +64,23 @@ Request Unit (RU) 是 TiDB 对 CPU、IO 等系统资源的统一抽象的单位, | `resource-control.enabled`= true | 流控和调度(推荐组合) | 无效配置 | | `resource-control.enabled`= false | 仅流控(不推荐) | 特性被关闭 | -关于资源管控实现机制及相关参数的详细介绍,请参考 [RFC: Global Resource Control in TiDB](https://docs.google.com/document/d/1sV5EVv8Cdpc6aBCDihc2akpE0iuantPf/edit?n=RFC_Global_Resource_Control_in_TiDB.docx#heading=h.sjp9cmjfszlu)。 +关于资源管控实现机制及相关参数的详细介绍,请参考 [RFC: Global Resource Control in TiDB](https://github.com/pingcap/tidb/blob/master/docs/design/2022-11-25-global-resource-control.md)。 ## 使用方法 +### 管理资源组 + 创建、修改、删除资源组,需要拥有 `SUPER` 或者 `RESOURCE_GROUP_ADMIN` 权限。 -你可以通过 [`CREATE RESOURCE GROUP`](/sql-statements/sql-statement-create-resource-group.md) 在集群中创建资源组,再通过 [`CREATE USER`](/sql-statements/sql-statement-create-user.md) 或 [`ALTER USER`](/sql-statements/sql-statement-alter-user.md) 语句将用户绑定到特定的资源组。 +你可以通过 [`CREATE RESOURCE GROUP`](/sql-statements/sql-statement-create-resource-group.md) 在集群中创建资源组。 对于已有的资源组,可以通过 [`ALTER RESOURCE GROUP`](/sql-statements/sql-statement-alter-resource-group.md) 修改资源组的读写配额,对资源组的配额修改会立即生效。 -可以通过 [`DROP RESOURCE GROUP`](/sql-statements/sql-statement-drop-resource-group.md) 删除资源组。 +可以使用 [`DROP RESOURCE GROUP`](/sql-statements/sql-statement-drop-resource-group.md) 删除资源组。 -> **注意:** -> -> - `CREATE USER` 或者 `ALTER USER` 对用户资源组绑定后,不会对该用户的已有会话生效,而是只对该用户新建的会话生效。 -> - 如果用户没有绑定到某个资源组或者是绑定到 `default` 资源组,该用户的请求不会受 TiDB 的流控限制。`default` 资源组目前对用户不可见也不可以创建或者修改属性,不能通过 `SHOW CREATE RESOURCE GROUP` 或 `SELECT * FROM information_schema.resource_groups` 查看,但是可以通过 `mysql.user` 表查看。 - -### 第 1 步:开启资源管控特性 +### 创建资源组 -1. 执行以下命令开启资源管控特性: - - ```sql - SET GLOBAL tidb_enable_resource_control = 'ON'; - ``` - -2. 将 TiKV 参数 [`resource-control.enabled`](/tikv-configuration-file.md#resource-control) 设为 `true`。 - -### 第 2 步:创建资源组,并绑定用户到资源组 - -下面举例说明如何创建资源组,并绑定用户到资源组。 +下面举例说明如何创建资源组。 1. 创建 `rg1` 资源组,RU 的回填速度是每秒 500 RU,并且允许这个资源组的应用超额占用资源。 @@ -100,20 +94,73 @@ Request Unit (RU) 是 TiDB 对 CPU、IO 等系统资源的统一抽象的单位, CREATE RESOURCE GROUP IF NOT EXISTS rg2 RU_PER_SEC = 600; ``` -3. 将用户 `usr1` 和 `usr2` 分别绑定到资源组 `rg1` 和 `rg2`。 +3. 创建 `rg3` 资源组,设置绝对优先级为 `HIGH`。绝对优先级目前支持 `LOW|MEDIUM|HIGH`,资源组的默认绝对优先级为 `MEDIUM`。 ```sql - ALTER USER usr1 RESOURCE GROUP rg1; + CREATE RESOURCE GROUP IF NOT EXISTS rg3 RU_PER_SEC = 100 PRIORITY = HIGH; ``` - ```sql - ALTER USER usr2 RESOURCE GROUP rg2; - ``` +### 绑定资源组 + +TiDB 支持如下三个级别的资源组设置: + +- 用户级别。通过 [`CREATE USER`](/sql-statements/sql-statement-create-user.md) 或 [`ALTER USER`](/sql-statements/sql-statement-alter-user.md) 语句将用户绑定到特定的资源组。绑定后,对应的用户新创建的会话会自动绑定对应的资源组。 +- 会话级别。通过 [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) 设置当前会话使用的资源组。 +- 语句级别。通过 [`RESOURCE_GROUP()`](/optimizer-hints.md#resource_groupresource_group_name) 设置当前语句使用的资源组。 + +#### 将用户绑定到资源组 + +下面的示例创建一个用户 `usr1` 并将其绑定到资源组 `rg1`。其中 `rg1` 为[创建资源组](#创建资源组)示例中创建的资源组。 + +```sql +CREATE USER 'usr1'@'%' IDENTIFIED BY '123' RESOURCE GROUP rg1; +``` + +下面示例使用 `ALTER USER` 将用户 `usr2` 绑定到资源组 `rg2`。其中 `rg2` 为[创建资源组](#创建资源组)示例中创建的资源组。 -完成上述创建资源组和绑定用户的操作后,用户新建立的会话对资源的占用会受到指定用量 (RU) 的限制。如果系统负载比较高,没有多余的容量,`usr2` 用户的资源消耗速度会严格控制不超过指定用量,由于 `usr1` 绑定的 `rg1` 配置了 `BURSTABLE`,所以 `usr1` 消耗速度允许超过指定用量。 +```sql +ALTER USER usr2 RESOURCE GROUP rg2; +``` + +绑定用户后,用户新建立的会话对资源的占用会受到指定用量 (RU) 的限制。如果系统负载比较高,没有多余的容量,用户 `usr2` 的资源消耗速度会被严格控制不超过指定用量。由于 `usr1` 绑定的 `rg1` 配置了 `BURSTABLE`,所以 `usr1` 消耗速度允许超过指定用量。 如果资源组对应的请求太多导致资源组的资源不足,客户端的请求处理会发生等待。如果等待时间过长,请求会报错。 +> **注意:** +> +> - 使用 `CREATE USER` 或者 `ALTER USER` 将用户绑定到资源组后,只会对该用户新建的会话生效,不会对该用户已有的会话生效。 +> - TiDB 集群在初始化时会自动创建 `default` 资源组,其 `RU_PER_SEC` 的默认值为 `UNLIMITED` (等同于 `INT` 类型最大值,即 `2147483647`),且为 `BURSTABLE` 模式。对于没有绑定资源组的语句会自动绑定至此资源组。此资源组不支持删除,但允许修改其 RU 的配置。 + +#### 将当前会话绑定到资源组 + +通过把当前会话绑定到资源组,会话对资源的占用会受到指定用量 (RU) 的限制。 + +下面的示例将当前的会话绑定至资源组 `rg1`。 + +```sql +SET RESOURCE GROUP rg1; +``` + +#### 将语句绑定到资源组 + +通过在 SQL 语句中添加 [`RESOURCE_GROUP(resource_group_name)`](/optimizer-hints.md#resource_groupresource_group_name) Hint,可以将该语句绑定到指定的资源组。此 Hint 支持 `SELECT`、`INSERT`、`UPDATE`、`DELETE` 四种语句。 + +示例: + +```sql +SELECT /*+ RESOURCE_GROUP(rg1) */ * FROM t limit 10; +``` + +## 关闭资源管控特性 + +1. 执行以下命令关闭资源管控特性: + + ```sql + SET GLOBAL tidb_enable_resource_control = 'OFF'; + ``` + +2. 将 TiKV 参数 [`resource-control.enabled`](/tikv-configuration-file.md#resource-control) 设为 `false`,关闭按照资源组配额调度。 + ## 监控与图表 TiDB 会定时采集资源管控的运行时信息,并在 Grafana 的 **Resource Control Dashboard** 中提供了相关指标的可视化图表。指标详情参见 [Resource Control 监控指标详解](/grafana-resource-control-dashboard.md) 。 @@ -124,16 +171,9 @@ TiKV 中也记录了来自于不同资源组的请求 QPS,详见 [TiKV监控 资源管控目前为实验特性,不影响数据导入导出以及其他同步工具的正常使用,BR、TiDB Lightning、TiCDC 等工具不支持对资源管控相关 DDL 的处理,这些工具的资源消耗也不受资源管控的限制。 -## 使用限制 - -目前,资源管控特性具有以下限制: - -* 暂时只支持对前台客户发起的读写请求做限流和调度,不支持对 DDL 以及 Auto Analyze 等后台任务的限流和调度。 -* 资源管控将带来额外的调度开销。因此,开启该特性后,性能可能会有轻微下降。 - ## 另请参阅 * [CREATE RESOURCE GROUP](/sql-statements/sql-statement-create-resource-group.md) * [ALTER RESOURCE GROUP](/sql-statements/sql-statement-alter-resource-group.md) * [DROP RESOURCE GROUP](/sql-statements/sql-statement-drop-resource-group.md) -* [RESOURCE GROUP RFC](https://docs.google.com/document/d/1sV5EVv8Cdpc6aBCDihc2akpE0iuantPf/) +* [RESOURCE GROUP RFC](https://github.com/pingcap/tidb/blob/master/docs/design/2022-11-25-global-resource-control.md) diff --git a/tiflash-620-upgrade-guide.md b/tiflash-620-upgrade-guide.md index 8cf448698223..75172d918f5e 100644 --- a/tiflash-620-upgrade-guide.md +++ b/tiflash-620-upgrade-guide.md @@ -14,7 +14,7 @@ summary: 了解升级 TiFlash 至 v6.2 时的注意事项。 > **注意:** > -> - v6.2.0 新增了一项名为 [FastScan](/develop/dev-guide-use-fastscan.md) 的实验功能。该实验功能在牺牲强一致性保证的前提下可以大幅提升扫表性能。相关实验功能的形态和使用方式有可能在后续版本中发生变化。 +> - v6.2.0 新增了一项名为 [FastScan](/tiflash/use-fastscan.md) 的实验功能,该功能在 v7.0.0 GA。FastScan 在牺牲强一致性保证的前提下可以大幅提升扫表性能。 > > - 不推荐跨主干版本升级包含 TiFlash 的 TiDB 集群,如从 v4.x 升级至 v6.x,请先升级至 v5.x,然后再升级至 v6.x。 > diff --git a/tiflash-performance-tuning-methods.md b/tiflash-performance-tuning-methods.md new file mode 100644 index 000000000000..ac500597c623 --- /dev/null +++ b/tiflash-performance-tuning-methods.md @@ -0,0 +1,113 @@ +--- +title: TiFlash 性能分析和优化方法 +summary: 本文介绍了 Performance Overview 面板中 TiFlash 部分,帮助你了解和监控 TiFlash 的工作负载。 +--- + +# TiFlash 性能分析和优化方法 + +本文介绍 TiFlash 资源使用率和关键的性能指标。你可以通过 Performance Overview 面板中的 [TiFlash 面板](/grafana-performance-overview-dashboard.md#tiflash),来监控和评估 TiFlash 集群的性能。 + +## TiFlash 集群资源利用率 + +通过以下三个指标,你可以快速判断 TiFlash 集群的资源使用率: + +- CPU:每个 TiFlash 实例的 CPU 使用率 +- Memory:每个 TiFlash 实例内存的使用情况 +- IO utilization:每个 TiFlash 实例的 IO 使用率 + +示例:[CH-benCHmark 负载](/benchmark/benchmark-tidb-using-ch.md)资源使用率 + +该 TiFlash 集群包含两个节点,每个节点配置均为 16 核、48G 内存。当 CH-benCHmark 负载运行时,CPU 利用率最高可达到 1500%,内存占用最大可达 20 GB,IO 利用率达到 91%。这表明 TiFlash 节点资源接近饱和状态。 + +![CH-TiFlash-MPP](/media/performance/tiflash/ch-2tiflash-op.png) + +## TiFlash 关键性能指标 + +### 吞吐指标 + +通过以下指标,你可以了解 TiFlash 的吞吐情况: + +- MPP Query count:每个 TiFlash 实例 MPP 查询数量的瞬时值,表示当前 TiFlash 实例需要处理的 MPP 查询数量(包括正在处理的以及还没被调度到的)。 +- Request QPS:所有 TiFlash 实例收到的 coprocessor 请求数量。 + - `run_mpp_task`、`dispatch_mpp_task` 和 `mpp_establish_conn` 为 MPP 请求。 + - `batch`:batch 请求数量。 + - `cop`:直接通过 coprocessor 接口发送的 coprocessor 请求数量。 + - `cop_execution`:正在执行的 coprocessor 请求数量。 + - `remote_read`、`remote_read_constructed` 和 `remote_read_sent` 为 remote read 相关指标,remote read 增多一般意味着系统出现了问题。 +- Executor QPS:所有 TiFlash 实例收到的请求中,每种 dag 算子的数量,其中 `table_scan` 是扫表算子,`selection` 是过滤算子,`aggregation` 是聚合算子,`top_n` 是 TopN 算子,`limit` 是 limit 算子,`join` 为关联算子,`exchange_sender` 和 `exchange_receiver` 为数据发送和接收算子。 + +### 延迟指标 + +通过以下指标,你可以了解 TiFlash 的延迟处理情况: + +- Request Duration Overview:每秒所有 TiFlash 实例处理所有请求类型的总时长堆叠图。 + + - 如果请求类型为 `run_mpp_task`、`dispatch_mpp_task` 或 `mpp_establish_conn`,说明 SQL 语句的执行已经部分或者完全下推到 TiFlash 上进行,通常包含 join 和数据分发的操作,这是 TiFlash 最常见的服务类型。 + - 如果请求类型为 `cop`,说明整个语句并没有完全下推到 TiFlash,通常 TiDB 会将全表扫描算子下推到 TiFlash 上进行数据访问和过滤。在堆叠图中,如果 `cop` 占据主导地位,需要仔细权衡是否合理。 + + - 如果 SQL 访问的数据量很大,优化器可能根据成本模型估算 TiFlash 全表扫描的成本更低。 + - 如果表结构缺少合适的索引,即使访问的数据量很少,优化器也只能将查询下推到 TiFlash 进行全表扫描。在这种情况下,创建合适的索引,通过 TiKV 访问数据更加高效。 + +- Request Duration:所有 TiFlash 实例每种 MPP 和 coprocessor 请求类型的总处理时间,包含平均和 P99 处理延迟。 +- Request Handle Duration:指 `cop` 和 `batch cop` 从开始执行到执行结束的时间,不包括等待时间,只包含 `cop` 和 `batch cop` 两种类型,包含平均和 P99 延迟。 + +示例 1 :TiFlash MPP 请求处理时间概览 + +如下图所示,在此负载中,`run_mpp_task` 和 `mpp_establish_conn` 请求的处理时间占比最高,表明大部分请求都是完全下推到 TiFlash 上执行的 MPP 任务。 + +而 `cop` 请求处理时间占比较小,说明存在一部分请求是通过 coprocessor 下推到 TiFlash 上进行数据访问和过滤的。 + +![CH-TiFlash-MPP](/media/performance/tiflash/ch-2tiflash-op.png) + +示例 2 :TiFlash `cop` 请求处理时间占比高 + +如下图所示,在此负载中,`cop` 请求的处理时间占比最高,可以通过查看 SQL 执行计划来确认 `cop` 请求产生的原因。 + +![Cop](/media/performance/tiflash/tiflash_request_duration_by_type.png) + +### Raft 相关指标 + +通过以下指标,你可以了解 TiFlash 的 Raft 同步情况: + +- Raft Wait Index Duration:所有 TiFlash 实例等待本地 Region index >= read_index 所花费的时间,即进行 wait_index 操作的延迟。如果 Wait Index 延迟过高,说明 TiKV 和 TiFlash 之间数据同步存在明显的延迟,可能的原因包括: + + - TiKV 资源过载 + - TiFlash 资源过载,特别是 IO 资源 + - TiKV 和 TiFlash 之间存在网络瓶颈 + +- Raft Batch Read Index Duration:所有 TiFlash 实例 Read Index 的延迟。如果该指标过高,说明 TiFlash 和 TiKV 之间的交互速度较慢,可能的原因包括: + + - TiFlash 资源过载 + - TiKV 资源过载 + - TiFlash 和 TiKV 之间存在网络瓶颈 + +### IO 流量指标 + +通过以下指标,你可以了解 TiFlash 的 IO 流量情况: + +- Write Throughput By Instance:每个 TiFlash 实例写入数据的吞吐量,包括 apply Raft 数据日志以及 Raft 快照的写入吞吐量。 +- Write flow:所有 TiFlash 实例磁盘写操作的流量。 + + - File Descriptor:TiFlash 所使用的 DeltaTree 存储引擎的稳定层。 + - Page:指 Pagestore,TiFlash 所使用的 DeltaTree 存储引擎的 Delta 变更层。 + +- Read flow:所有 TiFlash 实例磁盘读操作的流量。 + + - File Descriptor:TiFlash 所使用的 DeltaTree 存储引擎的稳定层。 + - Page:指 Pagestore,TiFlash 所使用的 DeltaTree 存储引擎的 Delta 变更层。 + +你可以通过 `(Read flow + Write flow) ÷ 总的 Write Throughput By Instance` 计算出整个 TiFlash 集群的写放大倍数。 + +示例 1 :[CH-benCHmark 负载](/benchmark/benchmark-tidb-using-ch.md) OP 环境 Raft 和 IO 指标 + +如下图所示,该 TiFlash 集群的 Raft Wait Index 和 Raft Batch Read Index 99 分位数较高,分别为 3.24 秒和 753 毫秒。这是因为该集群的 TiFlash 负载较高,数据同步存在延迟。 + +该集群包含两个 TiFlash 节点,每秒 TiKV 同步到 TiFlash 的增量数据约为 28 MB。稳定层 (File Descriptor)的文件描述符最大写流量为 939 MB/s,最大读流量为 1.1 GiB/s,而 Delta 层 (Page) 最大写流量为 74 MB/s,最大读流量为 111 MB/s。该环境中的 TiFlash 使用独立的 NVME 盘,具有较强的 IO 吞吐能力。 + +![CH-2TiFlash-OP](/media/performance/tiflash/ch-2tiflash-raft-io-flow.png) + +示例 2 :[CH-benCHmark 负载](/benchmark/benchmark-tidb-using-ch.md) 公有云环境 Raft 和 IO 指标 + +如下图所示,Raft Wait Index 等待时间 99 分位数最高为 438 毫秒,Raft Batch Read Index 等待时间 99 分位数最高为 125 毫秒。该集群只有一个 TiFlash 节点,每秒 TiKV 同步到 TiFlash 的增量数据约为 5 MB。稳定层 (File Descriptor) 的最大写入流量为 78 MB/s,最大读取流量为 221 MB/s,Delta 层 (Page) 最大写入流量为8 MB/s,最大读取流量为18 MB/s。这个环境中的 TiFlash 使用的是 AWS EBS 云盘,其 IO 吞吐能力相对较弱。 + +![CH-TiFlash-MPP](/media/performance/tiflash/ch-1tiflash-raft-io-flow-cloud.png) \ No newline at end of file diff --git a/tiflash/create-tiflash-replicas.md b/tiflash/create-tiflash-replicas.md index 16f2c0102ace..0bfdd7601341 100644 --- a/tiflash/create-tiflash-replicas.md +++ b/tiflash/create-tiflash-replicas.md @@ -139,7 +139,7 @@ SELECT TABLE_NAME FROM information_schema.tables where TABLE_SCHEMA = " ```sql -- 这两个参数默认值都为 100MiB,即用于副本同步的快照最大占用的磁盘带宽不超过 100MiB/s。 - SET CONFIG tikv `server.snap-max-write-bytes-per-sec` = '300MiB'; + SET CONFIG tikv `server.snap-io-max-bytes-per-sec` = '300MiB'; SET CONFIG tiflash `raftstore-proxy.server.snap-max-write-bytes-per-sec` = '300MiB'; ``` @@ -178,7 +178,7 @@ SELECT TABLE_NAME FROM information_schema.tables where TABLE_SCHEMA = " 执行以下 SQL 语句可恢复默认的数据快照写入速度: ```sql - SET CONFIG tikv `server.snap-max-write-bytes-per-sec` = '100MiB'; + SET CONFIG tikv `server.snap-io-max-bytes-per-sec` = '100MiB'; SET CONFIG tiflash `raftstore-proxy.server.snap-max-write-bytes-per-sec` = '100MiB'; ``` diff --git a/tiflash/tiflash-configuration.md b/tiflash/tiflash-configuration.md index 8e5afb3476bb..f0af9a9911ca 100644 --- a/tiflash/tiflash-configuration.md +++ b/tiflash/tiflash-configuration.md @@ -115,10 +115,25 @@ delta_index_cache_size = 0 ## auto_tune_sec 表示自动调整的执行间隔,单位为秒。设为 0 表示关闭自动调整。 # auto_tune_sec = 5 + ## 下面的配置只针对存算分离模式生效,详细请参考 TiFlash 存算分离架构与 S3 支持文档 https://docs.pingcap.com/zh/tidb/dev/tiflash-disaggregated-and-s3 + # [storage.s3] + # endpoint: http://s3.{region}.amazonaws.com # S3 的 endpoint 地址 + # bucket: mybucket # TiFlash 的所有数据存储在这个 bucket 中 + # root: /cluster1_data # S3 bucket 中存储数据的根目录 + # access_key_id: {ACCESS_KEY_ID} # 访问 S3 的 ACCESS_KEY_ID + # secret_access_key: {SECRET_ACCESS_KEY} # 访问 S3 的 SECRET_ACCESS_KEY + + # [storage.remote.cache] + # dir: /data1/tiflash/cache # TiFlash Compute Node 的本地数据缓存目录 + # capacity: 858993459200 # 800 GiB + [flash] tidb_status_addr = tidb status 端口地址 # 多个地址以逗号分割 service_addr = TiFlash raft 服务 和 coprocessor 服务监听地址 + ## 下面的配置只针对存算分离模式生效,详情请参考 TiFlash 存算分离架构与 S3 支持文档 https://docs.pingcap.com/zh/tidb/dev/tiflash-disaggregated-and-s3 + # disaggregated_mode = tiflash_write # 可选值为 tiflash_write 或者 tiflash_compute + # 多个 TiFlash 节点会选一个 master 来负责往 PD 增删 placement rule,通过 flash.flash_cluster 中的参数控制。 [flash.flash_cluster] refresh_interval = master 定时刷新有效期 @@ -200,6 +215,15 @@ delta_index_cache_size = 0 ## 从 v6.2.0 引入,表示 PageStorage 单个数据文件中有效数据的最低比例。当某个数据文件的有效数据比例低于该值时,会触发 GC 对该文件的数据进行整理。默认为 0.5。 dt_page_gc_threshold = 0.5 + ## 从 v7.0.0 引入,表示带 group by key 的 HashAggregation 算子在触发 spill 之前的最大可用内存,超过该阈值之后 HashAggregation 会采用 spill to disk 的方式来减小内存使用。默认值为 0,表示内存使用无限制,即不会触发 spill。 + max_bytes_before_external_group_by = 0 + + ## 从 v7.0.0 引入,表示 sort/topN 算子在触发 spill 之前的最大可用内存,超过该阈值之后 sort/TopN 会采用 spill to disk 的方式来减小内存使用。默认值为 0,表示内存使用无限制,即不会触发 spill。 + max_bytes_before_external_sort = 0 + + ## 从 v7.0.0 引入,表示带等值 join 条件的 HashJoin 算子在触发 spill 之前的最大可用内存,超过该阈值之后 HashJoin 算子会采用 spill to disk 的方式来减小内存使用。默认值为 0,表示内存使用无限制,即不会触发 spill。 + max_bytes_before_external_join = 0 + ## 安全相关配置,从 v4.0.5 开始生效 [security] ## 从 v5.0 引入,控制是否开启日志脱敏 diff --git a/tiflash/tiflash-disaggregated-and-s3.md b/tiflash/tiflash-disaggregated-and-s3.md new file mode 100644 index 000000000000..3c32149b3508 --- /dev/null +++ b/tiflash/tiflash-disaggregated-and-s3.md @@ -0,0 +1,203 @@ +--- +title: TiFlash 存算分离架构与 S3 支持 +summary: 了解 TiFlash 存算分离架构与 S3 支持。 +--- + +# TiFlash 存算分离架构与 S3 支持 + +> **警告:** +> +> TiFlash 存算分离架构目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tiflash/issues) 反馈。 + +TiFlash 默认使用存算一体的架构进行部署,即 TiFlash 节点既是存储节点,也是计算节点。从 TiDB v7.0.0 开始,TiFlash 支持存算分离架构,并将数据存储在 Amazon S3 或兼容 S3 API 的对象存储中(比如 MinIO)。 + +## 架构介绍 + +![TiFlash Write and Compute Separation Architect](/media/tiflash/tiflash-s3.png) + +如图,在存算分离架构中,TiFlash 原有进程的不同部分的功能,被拆分到两种不同的节点中,分别是 Write Node 和 Compute Node。这两种节点可以分别部署,各自扩展,即你可以选择部署任意数量的 Write Node 或者 Compute Node。 + +- TiFlash Write Node + + 负责接收 TiKV 的 Raft logs 数据,将数据转换成列存格式,并每隔一小段时间将这段时间的所有数据更新打包上传到 S3 中。此外,Write Node 也负责管理 S3 上的数据,比如不断整理数据使之具有更好的查询性能,以及删除无用的数据等。 + + Write Node 利用本地磁盘(通常是 NVMe SSD)来缓存最新写入的数据,从而避免过多使用内存。 + + Write Node 比原来存算一体的 TiFlash 节点有更快的扩容和缩容速度,即增加或者删除 Write Node 后,数据能更快地在 Write Node 之间达到平衡。原理是 Write Node 把所有数据存储到了 S3,运行时只需要在本地存储很少的数据。扩容和缩容本质上是 Region Peer 在节点间的迁移。当某个 Write Node 要将某个 Region Peer 移动到自己之上管理时,它只需要从 Region Peer 所在的 Write Node 上传到 S3 的最新文件中下载少量关于此 Region 的元数据,再从 TiKV 同步最近的 Region 更新,就可以追上 Region Leader 的进度,从而完成 Region Peer 的迁移。 + +- TiFlash Compute Node + + 负责执行从 TiDB 节点发过来的查询请求。它首先访问 Write Node 以获取数据的快照 (data snapshots),然后分别从 Write Node 读取最新的数据(即尚未上传到 S3 的数据),从 S3 读取剩下的大部分数据。 + + Compute Node 利用本地磁盘(通常是 NVMe SSD)来作为数据文件的缓存,从而避免相同的数据反复从远端(Write Node 或者 S3)读取,以提高查询性能。 + + Compute Node 是无状态节点,它拥有秒级的扩容和缩容速度。你可以利用这个特性降低成本: + + - 在查询负载较低时,减少 Compute Node 的数量,从而节省成本。在没有查询时,甚至可以停掉所有 Compute Node。 + - 在查询负载变高时,快速增加 Compute Node 的数量,保证查询性能。 + +## 使用场景 + +TiFlash 存算分离架构适用于高性价比的数据分析服务的场景。在这个架构下,存储和计算资源可以单独按需扩展。在这些场景将会有较大收益: + +- 数据量虽然很大,但是只有少量数据被频繁查询;其他大部分数据属于冷数据,很少被查询。此时经常被查询的数据通常已被缓存在 Compute Node 的本地 SSD 上,可以提供较快查询性能;而其他大部分冷数据则存储在成本较低的 S3 或者其他对象存储上,从而节省存储成本。 + +- 计算资源需求有明显的波峰和波谷。比如重型的对账查询通常放在晚上执行,此时对计算资源要求较高,可以考虑临时扩展 Compute Node;其他时间可以用较少的 Compute Node 完成查询任务。 + +## 准备条件 + +1. 准备一个 S3 的 bucket,用于存储 TiFlash 数据。 + + 你也可以使用已有的 bucket,但需要为每个 TiDB 集群预留专门的 key 前缀。关于 S3 bucket 的更多信息,请参考 [AWS 文档](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/creating-buckets-s3.html)。 + + 也可以使用兼容 S3 的其他对象存储,比如 [MinIO](https://min.io/)。 + + TiFlash 使用的 S3 API 接口列表包括: + + - PutObject + - GetObject + - CopyObject + - DeleteObject + - ListObjectsV2 + - GetObjectTagging + - PutBucketLifecycle + +2. 给准备好的 S3 bucket 添加一个用于清理已删除数据的[生命周期](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/object-lifecycle-mgmt.html): + + ```shell + "ID": "tiflash-clean", + "Expiration": { + "Days": 1 + }, + "Filter": { + "And": { + "Tags": [ + { + "Value": "tiflash_deleted", + "Key": "true" + } + ] + } + } + ``` + +## 使用方式 + +默认情况下,TiUP 会将 TiFlash 部署为存算一体架构。如需将 TiFlash 部署为存算分离架构,请参考以下步骤手动进行配置: + +1. 确保 TiDB 集群中没有任何 TiFlash 节点。如果有,则需要将所有表的 TiFlash 副本数设置为 0,然后缩容掉所有 TiFlash 节点。比如: + + ```sql + SELECT * FROM INFORMATION_SCHEMA.TIFLASH_REPLICA; # 查询所有带有 TiFlash 副本的表 + ALTER TABLE table_name SET TIFLASH REPLICA 0; # 将所有表的 TiFlash 副本数设置为 0 + ``` + + ```shell + tiup cluster scale-in mycuster -R tiflash # 缩容掉所有 TiFlash 节点 + tiup cluster display mycluster # 等待所有 TiFlash 节点进入 Tombstone 状态 + tiup cluster prune mycluster # 移除所有处于 Tombstone 状态的 TiFlash 节点 + ``` + +2. 准备 TiFlash 的拓扑配置文件,比如 scale-out.topo.yaml,配置内容如下: + + ```yaml + tiflash_servers: + # TiFlash 的拓扑配置中存在 storage.s3 配置,说明部署时使用存算分离架构 + # 配置了 flash.disaggregated_mode: tiflash_compute,则节点类型是 Compute Node; + # 配置了 flash.disaggregated_mode: tiflash_write,则节点类型是 Write Node + + # 172.31.8.1~2 是 TiFlash Write Node + - host: 172.31.8.1 + config: + flash.disaggregated_mode: tiflash_write # 这是一个 Write Node + storage.s3.endpoint: http://s3.{region}.amazonaws.com # S3 的 endpoint 地址 + storage.s3.bucket: mybucket # TiFlash 的所有数据存储在这个 bucket 中 + storage.s3.root: /cluster1_data # S3 bucket 中存储数据的根目录 + storage.s3.access_key_id: {ACCESS_KEY_ID} # 访问 S3 的 ACCESS_KEY_ID + storage.s3.secret_access_key: {SECRET_ACCESS_KEY} # 访问 S3 的 SECRET_ACCESS_KEY + storage.main.dir: ["/data1/tiflash/data"] # Write Node 的本地数据目录,和存算一体的配置方式相同 + - host: 172.31.8.2 + config: + flash.disaggregated_mode: tiflash_write # 这是一个 Write Node + storage.s3.endpoint: http://s3.{region}.amazonaws.com # S3 的 endpoint 地址 + storage.s3.bucket: mybucket # TiFlash 的所有数据存储在这个 bucket 中 + storage.s3.root: /cluster1_data # S3 bucket 中存储数据的根目录 + storage.s3.access_key_id: {ACCESS_KEY_ID} # 访问 S3 的 ACCESS_KEY_ID + storage.s3.secret_access_key: {SECRET_ACCESS_KEY} # 访问 S3 的 SECRET_ACCESS_KEY + storage.main.dir: ["/data1/tiflash/data"] # Write Node 的本地数据目录,和存算一体的配置方式相同 + + # 172.31.9.1~2 是 TiFlash Compute Node + - host: 172.31.9.1 + config: + flash.disaggregated_mode: tiflash_compute # 这是一个 Compute Node + storage.s3.endpoint: http://s3.{region}.amazonaws.com # S3 的 endpoint 地址 + storage.s3.bucket: mybucket # TiFlash 的所有数据存储在这个 bucket 中 + storage.s3.root: /cluster1_data # S3 bucket 中存储数据的根目录 + storage.s3.access_key_id: {ACCESS_KEY_ID} # 访问 S3 的 ACCESS_KEY_ID + storage.s3.secret_access_key: {SECRET_ACCESS_KEY} # 访问 S3 的 SECRET_ACCESS_KEY + storage.main.dir: ["/data1/tiflash/data"] # Compute Node 的本地数据目录,和存算一体的配置方式相同 + storage.remote.cache.dir: /data1/tiflash/cache # Compute Node 的本地数据缓存目录 + storage.remote.cache.capacity: 858993459200 # 800 GiB + - host: 172.31.9.2 + config: + flash.disaggregated_mode: tiflash_compute # 这是一个 Compute Node + storage.s3.endpoint: http://s3.{region}.amazonaws.com # S3 的 endpoint 地址 + storage.s3.bucket: mybucket # TiFlash 的所有数据存储在这个 bucket 中 + storage.s3.root: /cluster1_data # S3 bucket 中存储数据的根目录 + storage.s3.access_key_id: {ACCESS_KEY_ID} # 访问 S3 的 ACCESS_KEY_ID + storage.s3.secret_access_key: {SECRET_ACCESS_KEY} # 访问 S3 的 SECRET_ACCESS_KEY + storage.main.dir: ["/data1/tiflash/data"] # Compute Node 的本地数据目录,和存算一体的配置方式相同 + storage.remote.cache.dir: /data1/tiflash/cache # Compute Node 的本地数据缓存目录 + storage.remote.cache.capacity: 858993459200 # 800 GiB + ``` + + * 注意以上 `ACCESS_KEY_ID` 和 `SECRET_ACCESS_KEY` 是直接写在配置文件中的。你也可以选择使用环境变量的方式单独配置。如果两种方式都配置了,环境变量的优先级高于配置文件。 + + 如需通过环境变量配置,请在所有部署了 TiFlash 进程的机器上,切换到启动 TiFlash 进程的用户环境(通常是 `tidb`),然后修改 `~/.bash_profile`,增加这些配置: + + ```shell + export S3_ACCESS_KEY_ID={ACCESS_KEY_ID} + export S3_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY} + ``` + + * `storage.s3.endpoint` 支持使用 `http` 模式和 `https` 模式连接 S3,可以直接通过修改 URL 来选择。比如 `https://s3.{region}.amazonaws.com`。 + +3. 执行扩容 TiFlash 节点,并重新设置 TiFlash 副本数: + + ```shell + tiup cluster scale-out mycluster ./scale-out.topo.yaml + ``` + + ```sql + ALTER TABLE table_name SET TIFLASH REPLICA 1; + ``` + +4. 修改 TiDB 配置,用存算分离的方式查询 TiFlash。 + + 1. 以编辑模式打开 TiDB 配置文件: + + ```shell + tiup cluster edit-config mycluster + ``` + + 2. 在 TiDB 配置文件中添加以下配置项: + + ```shell + server_configs: + tidb: + disaggregated-tiflash: true # 使用存算分离的方式查询 TiFlash + ``` + + 3. 重启 TiDB: + + ```shell + tiup cluster reload mycluster -R tidb + ``` + +## 使用限制 + +- TiFlash 不支持在存算一体架构和存算分离架构之间原地切换。在切换架构前,需要将原有 TiFlash 节点全部删除。 +- 从一种架构迁移到另外一种架构后,需要重新同步所有 TiFlash 的数据。 +- 同一个 TiDB 集群只允许存在相同架构的 TiFlash 节点,不允许两种架构同时存在。 +- 存算分离架构只支持使用 S3 API 的对象存储,存算一体架构只支持本地存储。 +- 使用 S3 存储的情况下,TiFlash 节点无法获取非本节点文件的密钥,因此无法启用[静态加密](/encryption-at-rest.md)功能。 diff --git a/tiflash/tiflash-late-materialization.md b/tiflash/tiflash-late-materialization.md new file mode 100644 index 000000000000..38a78b173c9f --- /dev/null +++ b/tiflash/tiflash-late-materialization.md @@ -0,0 +1,100 @@ +--- +title: TiFlash 延迟物化 +summary: 介绍通过使用 TiFlash 延迟物化的方式来加速 OLAP 场景的查询。 +--- + +# 延迟物化 + +> **警告:** +> +> 该功能目前是实验性功能,其形式和使用方法可能会在未来版本中发生变化。 + +本文档介绍通过使用 TiFlash 延迟物化的方式来加速 Online Analytical Processing (OLAP) 场景的查询。 + +默认情况下,当收到一个查询请求时,TiFlash 会先读取该查询所需列的全部数据,然后再根据查询条件对数据进行过滤、聚合等计算任务。延迟物化是一种优化方式,它支持下推部分过滤条件到 TableScan 算子,即先扫描过滤条件相关的列数据,过滤得到符合条件的行后,再扫描这些行的其他列数据,继续后续计算,从而减少 IO 扫描和数据处理的计算量。 + +如果希望提升 OLAP 场景部分查询的性能,可以在 session 级别或 global 级别开启 TiFlash 延迟物化功能。你可以通过修改变量 [`tidb_opt_enable_late_materialization`](/system-variables.md#tidb_opt_enable_late_materialization-从-v700-版本开始引入) 的值来选择是否启用 TiFlash 延迟物化功能。 + +启用 TiFlash 延迟物化功能后,TiDB 优化器会根据统计信息和查询的过滤条件,决定哪些过滤条件会被下推。优化器会优先考虑下推过滤率高的过滤条件,详细算法可以参考 [RFC 文档](https://github.com/pingcap/tidb/tree/master/docs/design/2022-12-06-support-late-materialization.md)。 + +例如: + +```sql +EXPLAIN SELECT a, b, c FROM t1 WHERE a < 1; +``` + +``` ++-------------------------+----------+--------------+---------------+-------------------------------------------------------+ +| id | estRows | task | access object | operator info | ++-------------------------+----------+--------------+---------------+-------------------------------------------------------+ +| TableReader_12 | 12288.00 | root | | MppVersion: 1, data:ExchangeSender_11 | +| └─ExchangeSender_11 | 12288.00 | mpp[tiflash] | | ExchangeType: PassThrough | +| └─TableFullScan_9 | 12288.00 | mpp[tiflash] | table:t1 | pushed down filter:lt(test.t1.a, 1), keep order:false | ++-------------------------+----------+--------------+---------------+-------------------------------------------------------+ +``` + +在此示例中,过滤条件 `a < 1` 被下推到了 TableScan 算子,TiFlash 会先读取列 `a` 的全部数据,然后根据过滤条件 `a < 1` 进行过滤,得到符合条件的行后,再读取这些行的列 `b` 和 `c` 的数据。 + +## 启用和禁用 TiFlash 延迟物化 + +默认情况下,session 和 global 级别的变量 `tidb_opt_enable_late_materialization=OFF`,即未开启 TiFlash 延迟物化功能。你可以通过以下语句来查看对应的变量信息。 + +```sql +SHOW VARIABLES LIKE 'tidb_opt_enable_late_materialization'; +``` + +``` ++--------------------------------------+-------+ +| Variable_name | Value | ++--------------------------------------+-------+ +| tidb_opt_enable_late_materialization | OFF | ++--------------------------------------+-------+ +``` + +```sql +SHOW GLOBAL VARIABLES LIKE 'tidb_opt_enable_late_materialization'; +``` + +``` ++--------------------------------------+-------+ +| Variable_name | Value | ++--------------------------------------+-------+ +| tidb_opt_enable_late_materialization | OFF | ++--------------------------------------+-------+ +``` + +变量 `tidb_opt_enable_late_materialization` 支持 session 级别和 global 级别的修改。 + +- 如果需要在当前 session 中启用 TiFlash 延迟物化功能,可以通过以下语句设置: + + ```sql + SET SESSION tidb_opt_enable_late_materialization=ON; + ``` + +- 如果需要在 global 级别启用 TiFlash 延迟物化功能,可以通过以下语句设置: + + ```sql + SET GLOBAL tidb_opt_enable_late_materialization=ON; + ``` + + 设置后,新建的会话中 session 和 global 级别 `tidb_opt_enable_late_materialization` 都将默认启用新值。 + +如需禁用 TiFlash 延迟物化功能,可以通过以下语句设置: + +```sql +SET SESSION tidb_opt_enable_late_materialization=OFF; +``` + +```sql +SET GLOBAL tidb_opt_enable_late_materialization=OFF; +``` + +## 实现机制 + +当有过滤条件下推到 TableScan 算子时,TableScan 算子的执行过程主要包括了以下步骤: + +1. 读取 `` 三列,执行多版本并发控制 (MVCC) 过滤,生成 MVCC Bitmap。 +2. 读取过滤条件相关的列,过滤满足条件的行,生成 Filter Bitmap。 +3. 将 MVCC Bitmap 和 Filter Bitmap 进行与操作 (AND),生成 Final Bitmap。 +4. 根据 Final Bitmap 读取剩余列的对应的行。 +5. 合并第 2 步和第 4 步中读取的数据,返回结果。 \ No newline at end of file diff --git a/tiflash/tiflash-spill-disk.md b/tiflash/tiflash-spill-disk.md new file mode 100644 index 000000000000..4443fda4192c --- /dev/null +++ b/tiflash/tiflash-spill-disk.md @@ -0,0 +1,78 @@ +--- +title: TiFlash 数据落盘 +summary: 介绍 TiFlash 数据落盘功能。 +--- + +# TiFlash 数据落盘 + +本文介绍 TiFlash 计算过程中的数据落盘功能。 + +从 v7.0.0 起,TiFlash 支持在计算过程中将中间数据落盘以缓解内存压力。目前支持落盘的算子有: + +* 带有等值关联条件的 Hash Join 算子 +* 带有 `GROUP BY` key 的 Hash Aggregation 算子 +* TopN 算子以及窗口函数中的 Sort 算子 + +## TiFlash 数据落盘的触发机制 + +TiDB 提供了以下系统变量,来控制各算子数据落盘的阈值。当算子使用的内存超过阈值之后,TiFlash 会触发对应算子的落盘。 + +* [`tidb_max_bytes_before_tiflash_external_group_by`](/system-variables.md#tidb_max_bytes_before_tiflash_external_group_by-从-v700-版本开始引入) +* [`tidb_max_bytes_before_tiflash_external_join`](/system-variables.md#tidb_max_bytes_before_tiflash_external_join-从-v700-版本开始引入) +* [`tidb_max_bytes_before_tiflash_external_sort`](/system-variables.md#tidb_max_bytes_before_tiflash_external_sort-从-v700-版本开始引入) + +## 示例 + +本示例构造一个占用大量内存的 SQL 语句来对 Hash Aggregation 的落盘功能进行演示: + +1. 准备数据。创建一个包含 2 个节点的 TiFlash 集群,并导入 TPCH-100 的数据。 +2. 执行以下语句。该语句不限制带 `GROUP BY` 的 Hash Aggregation 算子的内存使用量。 + + ```sql + SET tidb_max_bytes_before_tiflash_external_group_by = 0; + SELECT + l_orderkey, + MAX(L_COMMENT), + MAX(L_SHIPMODE), + MAX(L_SHIPINSTRUCT), + MAX(L_SHIPDATE), + MAX(L_EXTENDEDPRICE) + FROM lineitem + GROUP BY l_orderkey + HAVING SUM(l_quantity) > 314; + ``` + +3. 从 TiFlash 的日志中可以看到,该查询在单个 TiFlash 节点上需要消耗 29.55 GiB 内存: + + ``` + [DEBUG] [MemoryTracker.cpp:69] ["Peak memory usage (total): 29.55 GiB."] [source=MemoryTracker] [thread_id=468] + ``` + +4. 执行以下语句。该语句限制了带 `GROUP BY` 的 Hash Aggregation 算子的内存使用量,不超过 10737418240 (10 GiB)。 + + ```sql + SET tidb_max_bytes_before_tiflash_external_group_by = 10737418240; + SELECT + l_orderkey, + MAX(L_COMMENT), + MAX(L_SHIPMODE), + MAX(L_SHIPINSTRUCT), + MAX(L_SHIPDATE), + MAX(L_EXTENDEDPRICE) + FROM lineitem + GROUP BY l_orderkey + HAVING SUM(l_quantity) > 314; + ``` + +5. 从 TiFlash 的日志中可以看出,通过配置 `tidb_max_bytes_before_tiflash_external_group_by`,TiFlash 触发了中间结果落盘,显著减小了查询所需的内存。 + + ``` + [DEBUG] [MemoryTracker.cpp:69] ["Peak memory usage (total): 12.80 GiB."] [source=MemoryTracker] [thread_id=110] + ``` + +## 注意 + +* 当 Hash Aggregation 算子不带 `GROUP BY` key 时,不支持落盘。即使该 Hash Aggregation 中含有 `DISTINCT` 聚合函数,也不能触发落盘。 +* 目前阈值是针对单个算子来计算的。如果一个查询里有两个 Hash Aggregation 算子,并且阈值设置为 10 GiB,那么两个 Hash Aggregation 算子仅会在各自占用的内存超过 10 GiB 时才会触发数据落盘。 +* 目前 Hash Aggregation 与 TopN/Sort 在 restore 阶段采用的是 merge aggregation 和 merge sort 的算法,所以这两个算子只会触发一次数据落盘。如果需要的内存特别大以至于在 restore 阶段内存使用仍然超阈值,不会再次触发落盘。 +* 目前 Hash Join 采用基于分区的落盘策略,在 restore 阶段如果内存使用仍然超过阈值,会继续触发落盘。但是为了控制落盘的规模,落盘的轮数限制为三轮。如果第三轮落盘之后的 restore 阶段内存使用仍然超过阈值,则不会触发新的落盘。 diff --git a/tiflash/tiflash-supported-pushdown-calculations.md b/tiflash/tiflash-supported-pushdown-calculations.md index 41e0369d5330..b6b5b3841c8d 100644 --- a/tiflash/tiflash-supported-pushdown-calculations.md +++ b/tiflash/tiflash-supported-pushdown-calculations.md @@ -21,7 +21,7 @@ TiFlash 支持部分算子的下推,支持的算子如下: * HashJoin:该算子基于 [Hash Join](/explain-joins.md#hash-join) 算法对数据进行连接运算: * 只有在 [MPP 模式](/tiflash/use-tiflash-mpp-mode.md)下才能被下推 * 支持的 Join 类型包括 Inner Join、Left Join、Semi Join、Anti Semi Join、Left Semi Join、Anti Left Semi Join - * 对于上述类型,既支持带等值条件的连接,也支持不带等值条件的连接(即 Cartesian Join);在计算 Cartesian Join 时,只会使用 Broadcast 算法,而不会使用 Shuffle Hash Join 算法 + * 对于上述类型,既支持带等值条件的连接,也支持不带等值条件的连接(即 Cartesian Join 或者 Null-aware Semi Join);在计算 Cartesian Join 或者 Null-aware Semi Join 时,只会使用 Broadcast 算法,而不会使用 Shuffle Hash Join 算法 * [Window](/functions-and-operators/window-functions.md):当前支持下推的窗口函数包括 `ROW_NUMBER()`、`RANK()`、`DENSE_RANK()`、`LEAD()` 和 `LAG()` 在 TiDB 中,算子之间会呈现树型组织结构。一个算子能下推到 TiFlash 的前提条件,是该算子的所有子算子都能下推到 TiFlash。因为大部分算子都包含有表达式计算,当且仅当一个算子所包含的所有表达式均支持下推到 TiFlash 时,该算子才有可能下推给 TiFlash。 diff --git a/develop/dev-guide-use-fastscan.md b/tiflash/use-fastscan.md similarity index 92% rename from develop/dev-guide-use-fastscan.md rename to tiflash/use-fastscan.md index fd6487c5e119..2e8bd03b8338 100644 --- a/develop/dev-guide-use-fastscan.md +++ b/tiflash/use-fastscan.md @@ -1,14 +1,10 @@ --- -title: FastScan +title: 使用 FastScan 功能 summary: 介绍通过使用 FastScan 来加速 OLAP 场景的查询的方法。 -aliases: ['/zh/tidb/dev/sql-statement-set-tiflash-mode'] +aliases: ['/zh/tidb/dev/sql-statement-set-tiflash-mode/','/zh/tidb/dev/dev-guide-use-fastscan/'] --- -# FastScan - -> **警告:** -> -> 该功能目前是实验性功能,其形式和使用方法可能会在未来版本中发生变化。 +# 使用 FastScan 功能 本文档介绍通过使用 FastScan 来加速 Online Analytical Processing (OLAP) 场景中查询的方法。 diff --git a/tikv-configuration-file.md b/tikv-configuration-file.md index 170033cb8188..6af3e1f3709e 100644 --- a/tikv-configuration-file.md +++ b/tikv-configuration-file.md @@ -226,7 +226,7 @@ TiKV 配置文件比命令行参数支持更多的选项。你可以在 [etc/con + 默认值:60s + 最小值:1s -### `snap-max-write-bytes-per-sec` +### `snap-io-max-bytes-per-sec` + 处理 snapshot 时最大允许使用的磁盘带宽。 + 默认值:100MB @@ -281,8 +281,12 @@ TiKV 配置文件比命令行参数支持更多的选项。你可以在 [etc/con ### `max-thread-count` + 统一处理读请求的线程池最多的线程数量,即 UnifyReadPool 线程池的大小。调整该线程池的大小时,请参考 [TiKV 线程池调优](/tune-tikv-thread-performance.md#tikv-线程池调优)。 -+ 可调整范围:`[min-thread-count, MAX(4, CPU)]`。其中,`MAX(4, CPU)` 表示:如果 CPU 核心数量小于 `4`,取 `4`;如果 CPU 核心数量大于 `4`,则取 CPU 核心数量。 -+ 默认值:MAX(4, CPU * 0.8) ++ 可调整范围:`[min-thread-count, MAX(4, CPU quota * 10)]`。其中,`MAX(4, CPU quota * 10)` 表示:如果 CPU 配额乘 10 小于 `4`,取 `4`;如果 CPU 配额乘 10 大于 `4`,即 CPU 配额大于 `0.4`,则取 CPU 配额乘 10。 ++ 默认值:MAX(4, CPU quota * 0.8) + +> **注意:** +> +> 增加线程数量会导致上下文切换增多,可能会导致性能下降,因此不推荐修改此配置。 ### `stack-size` @@ -1817,6 +1821,15 @@ Raft Engine 相关的配置项。 > 仅在 [`format-version`](#format-version-从-v630-版本开始引入) 的值大于等于 2 时,该配置项才生效。 + 控制 Raft Engine 是否回收过期的日志文件。该配置项启用时,Raft Engine 将保留逻辑上被清除的日志文件,用于日志回收,减少写负载的长尾延迟。 ++ 默认值:`true` + +### `prefill-for-recycle` 从 v7.0.0 版本开始引入 + +> **注意:** +> +> 仅在 [`enable-log-recycle`](#enable-log-recycle-从-v630-版本开始引入) 的值为 `true` 时,该配置项才生效。 + ++ 控制 Raft Engine 是否自动生成空的日志文件用于日志回收。该配置项启用时,Raft Engine 将在初始化时自动填充一批空日志文件用于日志回收,保证日志回收在初始化后立即生效。 + 默认值:`false` ## security @@ -2064,7 +2077,7 @@ Raft Engine 相关的配置项。 ### `advance-ts-interval` + 定期推进 Resolved TS 的时间间隔。 -+ 默认值:1s ++ 默认值:20s ### `scan-lock-pool-size` @@ -2219,4 +2232,4 @@ Raft Engine 相关的配置项。 + 是否支持对用户前台的读写请求按照对应的资源组配额做优先级调度。有关 TiDB 资源组和资源管控的信息,请参考 [TiDB 资源管控](/tidb-resource-control.md) + 在 TiDB 侧开启 [`tidb_enable_resource_control`](/system-variables.md#tidb_enable_resource_control-从-v660-版本开始引入) 全局变量的情况下,开启这个配置项才有意义。此配置参数开启后,TiKV 会使用优先级队列对排队的用户前台读写请求做调度,调度的优先级和请求所在资源组已经消费的资源量反相关,和对应资源组的配额正相关。 -+ 默认值:false(即关闭按照资源组配额调度) ++ 默认值:true(即开启按照资源组配额调度) diff --git a/time-to-live.md b/time-to-live.md index e551d4e403e2..2182cf73d291 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -15,11 +15,6 @@ TTL 常见的使用场景: TTL 设计的目标是在不影响在线读写负载的前提下,帮助用户周期性且及时地清理不需要的数据。TTL 会以表为单位,并发地分发不同的任务到不同的 TiDB Server 节点上,进行并行删除处理。TTL 并不保证所有过期数据立即被删除,也就是说即使数据过期了,客户端仍然有可能在这之后的一段时间内读到过期的数据,直到其真正的被后台处理任务删除。 -> **警告:** -> -> 当前该功能为实验特性,不建议在生产环境中使用。 -> TTL 无法在 [Serverless Tier clusters](https://docs.pingcap.com/tidbcloud/select-cluster-tier#serverless-tier-beta) 上使用。 - ## 语法 你可以通过 [`CREATE TABLE`](/sql-statements/sql-statement-create-table.md) 或 [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md) 语句来配置表的 TTL 功能。 @@ -141,6 +136,8 @@ ALTER TABLE orders TTL_JOB_INTERVAL = '24h'; `TTL_JOB_INTERVAL` 的默认值是 `1h`。 +在执行 TTL 任务时,TiDB 会基于 Region 的数量将表拆分为最多 64 个子任务。这些子任务会被分发到不同的 TiDB 节点中执行。你可以通过设置系统变量 [`tidb_ttl_running_tasks`](/system-variables.md#tidb_ttl_running_tasks-从-v700-版本开始引入) 来限制整个集群中同时执行的 TTL 子任务数量。然而,并非所有表的 TTL 任务都可以被拆分为子任务。请参考[使用限制](#使用限制)以了解哪些表的 TTL 任务不能被拆分。 + 如果想禁止 TTL 任务的执行,除了可以设置表属性 `TTL_ENABLE='OFF'` 外,也可以通过设置全局变量 `tidb_ttl_job_enable` 关闭整个集群的 TTL 任务的执行。 ```sql @@ -215,9 +212,23 @@ TiDB 会定时采集 TTL 的运行时信息,并在 Grafana 中提供了相关 其中列 `table_id` 为分区表 ID,而 `parent_table_id` 为表的 ID,与 `infomation_schema.tables` 表中的 ID 对应。`table_schema`、`table_name`、`partition_name` 分别对应表示数据库、表名、分区名。`create_time`、`finish_time`、`ttl_expire` 分别表示 TTL 任务的创建时间、结束时间和过期时间。`expired_rows` 与 `deleted_rows` 表示过期行数与成功删除的行数。 -## 工具兼容性 +## TiDB 数据迁移工具兼容性 + +TTL 功能能够与 TiDB 的迁移、备份、恢复工具一同使用。 + +| 工具名称 | 最低兼容版本 | 说明 | +| --- | --- | --- | +| Backup & Restore (BR) | v6.6.0 | 恢复时会自动将表的 `TTL_ENABLE` 属性设置为 `OFF`,关闭 TTL。这样可以防止 TiDB 在备份恢复后立即删除过期的数据。此时你需要手动重新配置 `TTL_ENABLE` 属性来重新开启各个表的 TTL。 | +| TiDB Lightning | v6.6.0 | 导入后如果表中有 TTL 属性,会自动将表的 `TTL_ENABLE` 属性设置为 `OFF`,关闭 TTL。这样可以防止 TiDB 在导入后立即删除过期的数据。此时你需要手动重新配置 `TTL_ENABLE` 属性来重新开启各个表的 TTL。 | +| TiCDC | v7.0.0 | 上游的 TTL 删除将会同步至下游。因此,为了防止重复删除,下游表的 `TTL_ENABLE` 属性将被强制设置为 `OFF`。 | + +## 与 TiDB 其他特性的兼容性 -作为实验特性,TTL 特性暂时不兼容包括 BR、TiDB Lightning、TiCDC 在内的数据导入导出以及同步工具。 +| 特性名称 | 说明 | +| :-- | :---- | +| [`FLASHBACK TABLE`](/sql-statements/sql-statement-flashback-table.md) | `FLASHBACK TABLE` 语句会将每个表的 `TTL_ENABLE` 属性强制设置为 `OFF`。这样可以防止 TiDB 在 FLASHBACK 后立即删除过期的数据。此时你需要手动重新配置 `TTL_ENABLE` 属性来重新开启各个表的 TTL。 | +| [`FLASHBACK DATABASE`](/sql-statements/sql-statement-flashback-database.md) | `FLASHBACK DATABASE` 语句会将每个表的 `TTL_ENABLE` 属性强制设置为 `OFF`。这样可以防止 TiDB 在 FLASHBACK 后立即删除过期的数据。此时你需要手动重新配置 `TTL_ENABLE` 属性来重新开启各个表的 TTL。 | +| [`FLASHBACK CLUSTER TO TIMESTAMP`](/sql-statements/sql-statement-flashback-to-timestamp.md) | `FLASHBACK CLUSTER TO TIMESTAMP` 会将 [`TIDB_TTL_JOB_ENABLE`](/system-variables.md#tidb_ttl_job_enable-从-v650-版本开始引入) 系统变量设置为 `OFF`,同时表的 `TTL_ENABLE` 属性将保持原样。 | ## 使用限制 @@ -226,6 +237,8 @@ TiDB 会定时采集 TTL 的运行时信息,并在 Grafana 中提供了相关 * 不允许在临时表上设置 TTL 属性,包括本地临时表和全局临时表。 * 具有 TTL 属性的表不支持作为外键约束的主表被其他表引用。 * 不保证所有过期数据立即被删除,过期数据被删除的时间取决于后台清理任务的调度周期和调度窗口。 +* 对于使用[聚簇索引](/clustered-indexes.md)的表,如果主键的类型不是整数类型或二进制字符串类型,TTL 任务将无法被拆分成多个子任务。这将导致 TTL 任务只能在一个 TiDB 节点上按顺序执行。如果表中的数据量较大,TTL 任务的执行可能会变得缓慢。 +* TTL 无法在 TiDB Cloud [Serverless Tier](https://docs.pingcap.com/tidbcloud/select-cluster-tier#serverless-tier-beta) 集群上使用。 ## 常见问题 diff --git a/tiunimanager/tiunimanager-install-and-maintain.md b/tiunimanager/tiunimanager-install-and-maintain.md index 8b9a956db24b..8ea008dee2ca 100644 --- a/tiunimanager/tiunimanager-install-and-maintain.md +++ b/tiunimanager/tiunimanager-install-and-maintain.md @@ -184,7 +184,7 @@ TiUniManager 正常运行需要网络环境提供如下端口配置,管理员 默认情况下,你可以通过 TiUniManager Web 控制台**资源管理** > **导入主机**页面提供的主机资源模板填写 TiDB 资源机帐户和密码。 -如果用户环境中不允许帐号密码方式登录 TiDB 资源机,可在 `config.yaml` 文件中进行配置,以帐户密钥方式登录 TiDB 资源机。`config.yaml` 中相关配置项如下: +如果用户环境中不允许账号密码方式登录 TiDB 资源机,可在 `config.yaml` 文件中进行配置,以帐户密钥方式登录 TiDB 资源机。`config.yaml` 中相关配置项如下: | 配置描述 | 配置参数名 | 示例值 | | --- | --- | --- | diff --git a/troubleshoot-hot-spot-issues.md b/troubleshoot-hot-spot-issues.md index a9d793ef6448..1ba69cb7b1ac 100644 --- a/troubleshoot-hot-spot-issues.md +++ b/troubleshoot-hot-spot-issues.md @@ -82,9 +82,9 @@ Value: null ## 使用 SHARD_ROW_ID_BITS 处理热点表 -对于主键非整数或没有主键的表或者是联合主键,TiDB 会使用一个隐式的自增 RowID,大量 INSERT 时会把数据集中写入单个 Region,造成写入热点。 +对于非聚簇索引主键或没有主键的表,TiDB 会使用一个隐式的自增 RowID,大量 `INSERT` 时会把数据集中写入单个 Region,造成写入热点。 -通过设置 `SHARD_ROW_ID_BITS`,可以把 RowID 打散写入多个不同的 Region,缓解写入热点问题。 +通过设置 [`SHARD_ROW_ID_BITS`](/shard-row-id-bits.md),可以把 RowID 打散写入多个不同的 Region,缓解写入热点问题。 ``` SHARD_ROW_ID_BITS = 4 表示 16 个分片 diff --git a/troubleshoot-lock-conflicts.md b/troubleshoot-lock-conflicts.md index 7ceecad41b48..4c944153f6be 100644 --- a/troubleshoot-lock-conflicts.md +++ b/troubleshoot-lock-conflicts.md @@ -219,8 +219,8 @@ Txn0 完成了 Prewrite,在 Commit 的过程中 Txn1 对该 key 发起了读 * 可以使用 TiDB Control 的子命令 [decoder](/tidb-control.md#decoder-命令) 来查看指定 key 对应的行的 table id 以及 rowid: ```sh - ./tidb-ctl decoder -f table_row -k "t\x00\x00\x00\x00\x00\x00\x00\x1c_r\x00\x00\x00\x00\x00\x00\x00\xfa" - + ./tidb-ctl decoder "t\x00\x00\x00\x00\x00\x00\x00\x1c_r\x00\x00\x00\x00\x00\x00\x00\xfa" + format: table_row table_id: -9223372036854775780 row_id: -9223372036854775558 ``` @@ -309,7 +309,7 @@ err="pessimistic lock retry limit reached" 处理建议: * 如果上述报错出现的比较频繁,建议从业务的角度进行调整。 -* 如果业务中包含对同一行(同一个 key)的高并发上锁而频繁冲突,可以尝试启用系统变量 [`tidb_pessimistic_txn_aggressive_locking`](/system-variables.md#tidb_pessimistic_txn_aggressive_locking-从-v660-版本开始引入)。需要注意启用该选项可能对存在锁冲突的事务带来一定程度的吞吐下降(平均延迟上升)的代价。 +* 如果业务中包含对同一行(同一个 key)的高并发上锁而频繁冲突,可以尝试启用系统变量 [`tidb_pessimistic_txn_fair_locking`](/system-variables.md#tidb_pessimistic_txn_fair_locking-从-v700-版本开始引入)。需要注意启用该选项可能对存在锁冲突的事务带来一定程度的吞吐下降(平均延迟上升)的代价。对于新部署的集群,该选项默认启用 (`ON`) 。 ### Lock wait timeout exceeded