From 8322060db3efb38d23fcdaa070f8e2bf50746387 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Wed, 12 Mar 2025 10:33:57 +0800 Subject: [PATCH 01/51] Create release-9.0.0.md --- releases/release-9.0.0.md | 172 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 releases/release-9.0.0.md diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md new file mode 100644 index 0000000000000..509ad0a29f469 --- /dev/null +++ b/releases/release-9.0.0.md @@ -0,0 +1,172 @@ +--- +title: TiDB 9.0.0 Release Notes +summary: Learn about the new features, compatibility changes, improvements, and bug fixes in TiDB 9.0.0. +--- + +# TiDB 9.0.0 Release Notes + + + +Release date: xx xx, 2025 + +TiDB version: 9.0.0 + +Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v8.5/production-deployment-using-tiup) + +9.0.0 introduces the following key features and improvements: + + + + + + + + + + + + + + +
CategoryFeature/EnhancementDescription
+ +## Feature details + +### Scalability + + + +### Performance + + + +### Reliability + + + +### SQL + + + +### Security + + + +## Compatibility changes + +> **Note:** +> +> This section provides compatibility changes you need to know when you upgrade from v8.5.0 to the current version (v9.0.0). If you are upgrading from v8.4.0 or earlier versions to the current version, you might also need to check the compatibility changes introduced in intermediate versions. + +### Behavior changes + + + +### System variables + +| Variable name | Change type | Description | +|--------|------------------------------|------| +| | | | +| | | | +| | | | +| | | | + +### Configuration parameters + +| Configuration file or component | Configuration parameter | Change type | Description | +| -------- | -------- | -------- | -------- | +| | | | | +| | | | | + + +### Operating system and platform requirement changes + +Before upgrading TiDB, ensure that your operating system version meets the [OS and platform requirements](/hardware-and-software-requirements.md#os-and-platform-requirements). + +## Removed features + +* The following feature has been removed: + + + +* The following features are planned for removal in future versions: + + * Starting from v8.0.0, TiDB Lightning deprecates the [old version of conflict detection](/tidb-lightning/tidb-lightning-physical-import-mode-usage.md#the-old-version-of-conflict-detection-deprecated-in-v800) strategy for the physical import mode, and enables you to control the conflict detection strategy for both logical and physical import modes via the [`conflict.strategy`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) parameter. The [`duplicate-resolution`](/tidb-lightning/tidb-lightning-configuration.md) parameter for the old version of conflict detection will be removed in a future release. + +## Deprecated features + +The following features are planned for deprecation in future versions: + +* In v8.0.0, TiDB introduces the [`tidb_enable_auto_analyze_priority_queue`](/system-variables.md#tidb_enable_auto_analyze_priority_queue-new-in-v800) system variable to control whether priority queues are enabled to optimize the ordering of tasks that automatically collect statistics. In future releases, the priority queue will be the only way to order tasks for automatically collecting statistics, so this system variable will be deprecated. +* In v7.5.0, TiDB introduces the [`tidb_enable_async_merge_global_stats`](/system-variables.md#tidb_enable_async_merge_global_stats-new-in-v750) system variable. You can use it to set TiDB to use asynchronous merging of partition statistics to avoid OOM issues. In future releases, partition statistics will be merged asynchronously, so this system variable will be deprecated. +* It is planned to redesign [the automatic evolution of execution plan bindings](/sql-plan-management.md#baseline-evolution) in subsequent releases, and the related variables and behavior will change. +* In v8.0.0, TiDB introduces the [`tidb_enable_parallel_hashagg_spill`](/system-variables.md#tidb_enable_parallel_hashagg_spill-new-in-v800) system variable to control whether TiDB supports disk spill for the concurrent HashAgg algorithm. In future versions, this system variable will be deprecated. +* In v5.1, TiDB introduces the [`tidb_partition_prune_mode`](/system-variables.md#tidb_partition_prune_mode-new-in-v51) system variable to control whether to enable the dynamic pruning mode for partitioned tables. Starting from v8.5.0, a warning is returned when you set this variable to `static` or `static-only`. In future versions, this system variable will be deprecated. +* The TiDB Lightning parameter [`conflict.max-record-rows`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) is planned for deprecation in a future release and will be subsequently removed. This parameter will be replaced by [`conflict.threshold`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task), which means that the maximum number of conflicting records is consistent with the maximum number of conflicting records that can be tolerated in a single import task. +* Starting from v6.3.0, partitioned tables use [dynamic pruning mode](/partitioned-table.md#dynamic-pruning-mode) by default. Compared with static pruning mode, dynamic pruning mode supports features such as IndexJoin and plan cache with better performance. Therefore, static pruning mode will be deprecated. + +## Improvements + ++ TiDB + + + ++ TiKV + + + ++ PD + + + ++ TiFlash + + + ++ Tools + + + Backup & Restore (BR) + + + + TiDB Data Migration (DM) + + +## Bug fixes + ++ TiDB + + + ++ TiKV + + + ++ PD + + + ++ TiFlash + + + ++ Tools + + + Backup & Restore (BR) + + + + + TiCDC + + + + + TiDB Lightning + + + +## Performance test + +To learn about the performance of TiDB v9.0.0, you can refer to the [performance test reports](https://docs.pingcap.com/tidbcloud/v9.0-performance-highlights) of the TiDB Cloud Dedicated cluster. + +## Contributors + +We would like to thank the following contributors from the TiDB community: From 860aaf851f15c5c1e31f6734121925c607a4c29d Mon Sep 17 00:00:00 2001 From: Aolin Date: Mon, 24 Mar 2025 17:33:23 +0800 Subject: [PATCH 02/51] performance: update function pushdown --- releases/release-9.0.0.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 509ad0a29f469..6837744c91325 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -38,7 +38,19 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Performance +* Support pushing down the following functions to TiFlash [#59317](https://github.com/pingcap/tidb/issues/59317) @[guo-shaoge](https://github.com/guo-shaoge) **tw@Oreoxmt** + * `TRUNCATE()` + + For more information, see [documentation](/tiflash/tiflash-supported-pushdown-calculations.md). + +* Support pushing down the following date functions to TiKV [#59365](https://github.com/pingcap/tidb/issues/59365) @[gengliqi](https://github.com/gengliqi) **tw@Oreoxmt** + + * `FROM_UNIXTIME()` + * `TIMESTAMPDIFF()` + * `UNIX_TIMESTAMP()` + + For more information, see [documentation](/functions-and-operators/expressions-pushed-down.md). ### Reliability From fa6335651a3f595a1b5d8bac1887e88f7a006336 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Wed, 26 Mar 2025 09:56:15 +0800 Subject: [PATCH 03/51] Apply suggestions from code review --- releases/release-9.0.0.md | 42 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 6837744c91325..8ed6c807747d0 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -25,7 +25,19 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- - + Data Migration + Support query argument redaction in DM logs + Introduces an optional redact-info-log parameter to mask query arguments in DM logs, preventing sensitive data from appearing in logs. + + + Data Migration + Ensure Lightning compatibility with TiDB sql_require_primary_key=ON + Ensures the internal error-logging tables have primary keys if sql_require_primary_key=ON is enabled in TiDB, avoiding creation failures during data imports. + + + Data Migration + Migrated sync-diff-inspector from tidb-tools to tiflow repository + Consolidates sync-diff-inspector with other data migration and replication tools (DM and TiCDC) in the tiflow repository. Now available via TiUP and a dedicated Docker image. @@ -62,7 +74,31 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Security +### Data migration + +* Support query argument redaction in DM logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will] **tw@Oreoxmt** + + Introduces a new `redact-info-log` parameter, allowing DM to replace sensitive query arguments with `?` placeholders in DM logs. You can enable this feature by setting `redact-info-log = true` in the DM-worker configuration file or passing `--redact-info-log=true` at startup. This change only redacts query arguments (not entire SQL statements) and requires a DM-worker restart to take effect. + + For more information, see [documentation](/dm/dm-worker-configuration-file.md). + +* Ensure TiDB Lightning compatibility with TiDB `sql_require_primary_key=ON` [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716] **tw@Oreoxmt** + When `sql_require_primary_key=ON` is enabled in TiDB, tables must have a primary key. TiDB Lightning now adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`), preventing table-creation failures. If you rely on these internal tables for automation, confirm the new naming and schema changes (primary key added), as scripts referencing older table names might need updates. + +* Migrated sync-diff-inspector from `tidb-tools` to `tiflow` repository [#11672](https://github.com/pingcap/tiflow/issues/11672) @[joechenrh] **tw@Oreoxmt** + + The sync-diff-inspector tool has moved from the old [tidb-tools](https://github.com/pingcap/tidb-tools) repository to [tiflow](https://github.com/pingcap/tiflow), unifying replication and migration tools (DM, TiCDC, sync-diff-inspector) in one place. + + For TiDB v9.0.0 and later, you can install sync-diff-inspector via: + + * `tiup install sync-diff-inspector` + * `docker pull pingcap/sync-diff-inspector:latest` + * [TiDB Toolkit](/download-ecosystem-tools.md) binary + + The old [tidb-tools repo](https://github.com/pingcap/tidb-tools) is now archived. If you previously installed sync-diff-inspector from tidb-tools, switch to TiUP, Docker, or the updated binary. + + For more information, see [documentation](/sync-diff-inspector/sync-diff-inspector-overview.md). ## Compatibility changes @@ -72,7 +108,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Behavior changes - +* TiDB Lightning internal error-logging and conflict-detection tables names changed to `conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`, and now have primary keys. If you rely on these internal tables for automation, confirm the new naming and schema changes [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716] ### System variables @@ -87,7 +123,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Configuration file or component | Configuration parameter | Change type | Description | | -------- | -------- | -------- | -------- | -| | | | | +| DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | | | | | | From 24c29acaba330c167c3fdf7a06e10da16f1f6a3b Mon Sep 17 00:00:00 2001 From: Aolin Date: Wed, 26 Mar 2025 11:49:10 +0800 Subject: [PATCH 04/51] observability: add SQL cross-AZ traffic monitoring --- releases/release-9.0.0.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 8ed6c807747d0..c8253dfd53bcf 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -70,7 +70,17 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### SQL +### Observability +* SQL cross-AZ traffic monitoring [#57543](https://github.com/pingcap/tidb/issues/57543) @[nolouch](https://github.com/nolouch) @[yibin87](https://github.com/yibin87) **tw@Oreoxmt** + + Deploying TiDB clusters across Availability Zones (AZs) enhances the disaster recovery capability. However, in cloud environments, cross-AZ deployments incur additional network traffic costs. For example, AWS charges for both cross-region and cross-AZ traffic. Therefore, for TiDB clusters running on cloud services, accurately monitoring and analyzing network traffic is essential for cost control. + + Starting from v9.0.0, TiDB records the network traffic generated during SQL processing and distinguishes cross-AZ traffic. TiDB writes this data to the [`statements_summary` table](/statement-summary-tables.md) and [slow query logs](/identify-slow-queries.md). This feature helps you track major data transmission paths within TiDB clusters, analyze the sources of cross-AZ traffic, and better understand and control related costs. + + Note that the current version monitors only SQL query traffic **within the cluster** (between TiDB, TiKV, and TiFlash) and does not include DML or DDL operations. Additionally, the recorded traffic data represents unpacked traffic, which differs from actual physical traffic and cannot be used directly for network billing. + + For more information, see [documentation](/statement-summary-tables.md#statements_summary-fields-description). ### Security From d2ae0351e2919a532bc405aba16e0e359c0174e9 Mon Sep 17 00:00:00 2001 From: Aolin Date: Wed, 26 Mar 2025 12:22:54 +0800 Subject: [PATCH 05/51] update sync-diff-inspector --- releases/release-9.0.0.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index c8253dfd53bcf..99fdc2d10bf4c 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -96,17 +96,17 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- When `sql_require_primary_key=ON` is enabled in TiDB, tables must have a primary key. TiDB Lightning now adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`), preventing table-creation failures. If you rely on these internal tables for automation, confirm the new naming and schema changes (primary key added), as scripts referencing older table names might need updates. -* Migrated sync-diff-inspector from `tidb-tools` to `tiflow` repository [#11672](https://github.com/pingcap/tiflow/issues/11672) @[joechenrh] **tw@Oreoxmt** +* Migrate sync-diff-inspector from `pingcap/tidb-tools` to `pingcap/tiflow` repository [#11672](https://github.com/pingcap/tiflow/issues/11672) @[joechenrh](https://github.com/joechenrh) **tw@Oreoxmt** - The sync-diff-inspector tool has moved from the old [tidb-tools](https://github.com/pingcap/tidb-tools) repository to [tiflow](https://github.com/pingcap/tiflow), unifying replication and migration tools (DM, TiCDC, sync-diff-inspector) in one place. + Starting from v9.0.0, the sync-diff-inspector tool is moved from the [`pingcap/tidb-tools`](https://github.com/pingcap/tidb-tools) repository to [`pingcap/tiflow`](https://github.com/pingcap/tiflow). This change unifies replication and migration tools ([DM](/dm/dm-overview.md), [TiCDC](/ticdc/ticdc-overview.md), and [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md)) into a single repository. - For TiDB v9.0.0 and later, you can install sync-diff-inspector via: + For TiDB v9.0.0 and later versions, you can install sync-diff-inspector using one of the following methods: - * `tiup install sync-diff-inspector` - * `docker pull pingcap/sync-diff-inspector:latest` - * [TiDB Toolkit](/download-ecosystem-tools.md) binary + - TiUP: `tiup install sync-diff-inspector` + - Docker image: `docker pull pingcap/sync-diff-inspector:latest` + - Binary package: [TiDB Toolkit](/download-ecosystem-tools.md) - The old [tidb-tools repo](https://github.com/pingcap/tidb-tools) is now archived. If you previously installed sync-diff-inspector from tidb-tools, switch to TiUP, Docker, or the updated binary. + The [`pingcap/tidb-tools`](https://github.com/pingcap/tidb-tools) repository is now archived. If you previously installed sync-diff-inspector from `tidb-tools`, switch to TiUP, Docker, or the TiDB Toolkit. For more information, see [documentation](/sync-diff-inspector/sync-diff-inspector-overview.md). From a67f6533024ab609ad0ca3d03fa2b95aae5dfde3 Mon Sep 17 00:00:00 2001 From: Aolin Date: Wed, 26 Mar 2025 12:23:29 +0800 Subject: [PATCH 06/51] add Offline package changes --- releases/release-9.0.0.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 99fdc2d10bf4c..4ea3f3413b736 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -136,6 +136,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | | | | | | +### Offline package changes + +Starting from v9.0.0, the offline package location of the [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) tool in the `TiDB-community-toolkit` [binary package](/binary-package.md) is changed from `sync_diff_inspector` to `tiflow-{version}-linux-{arch}.tar.gz`. ### Operating system and platform requirement changes From f9c52510b37d08ed1cf609d690cd24240736b914 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Wed, 26 Mar 2025 16:37:09 +0800 Subject: [PATCH 07/51] Apply suggestions from code review --- releases/release-9.0.0.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 4ea3f3413b736..1a6cd14138220 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -50,6 +50,13 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Performance +* In scenarios with hundreds of thousands to millions of users, the performance of creating and modifying users has improved by 77 times [#55563](https://github.com/pingcap/tidb/issues/55563) @[tiancaiamao](https://github.com/tiancaiamao) tw@hfxsd + + In previous versions, when the number of users in a cluster exceeded 200,000, the QPS for creating and modifying users drops to 1. In certain SaaS environments, if there is a need to create millions of users and periodically update user passwords in bulk, it can take up to 2 days or more, which is unacceptable for some SaaS businesses. + + TiDB v9.0.0 optimizes the performance of these DCL (Data Control Language) operations, allowing 2 million users to be created in just 37 minutes. This greatly enhances the execution performance of DCL statements and improves the user experience of TiDB in such SaaS scenarios. + + For more information, see [documentation](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900). * Support pushing down the following functions to TiFlash [#59317](https://github.com/pingcap/tidb/issues/59317) @[guo-shaoge](https://github.com/guo-shaoge) **tw@Oreoxmt** * `TRUNCATE()` @@ -64,9 +71,21 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/functions-and-operators/expressions-pushed-down.md). +### Availability + +* TiProxy officially supports the traffic replay feature (GA) [#642](https://github.com/pingcap/tiproxy/issues/642) @[djshow832](https://github.com/djshow832) tw@hfxsd + + In TiProxy v1.3.0, the traffic replay feature is released as an experimental feature. In TiProxy v1.4.0, the traffic replay feature becomes generally available (GA). TiProxy provides specialized SQL commands for traffic capture and replay. This feature lets you easily capture access traffic from TiDB production clusters and replay it at a specified rate in test clusters, facilitating business validation. + + For more information, see [documentation](/tiproxy/tiproxy-traffic-replay.md). + ### Reliability +* Introduce a new system variable `MAX_USER_CONNECTIONS` to limit the number of connections that different users can establish [#59203](https://github.com/pingcap/tidb/issues/59203) @[joccau](https://github.com/joccau) tw@hfxsd + Starting from v9.0.0, you can use the `MAX_USER_CONNECTIONS` system variable to limit the number of connections a single user can establish to a single TiDB node. This helps prevent issues where excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user causes delays in responding to requests from other users. + + For more information, see [documentation](/system-variables.md/#max_user_connections-new-in-v900) ### SQL @@ -82,6 +101,13 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/statement-summary-tables.md#statements_summary-fields-description). +* Optimize the `execution info` in the output of `EXPLAIN ANALYZE` [#56232](https://github.com/pingcap/tidb/issues/56232) @[yibin87](https://github.com/yibin87) tw@hfxsd + + [`EXPLAIN ANALYZE`](https://github.com/sql-statements/sql-statement-explain-analyze.md) executes SQL statements and records execution details in the `execution info` column. The same information is captured in the [slow query log](https://github.com/identify-slow-queries.md). These details are crucial for analyzing and understanding the time spent on SQL execution. + + In v9.0.0, the `execution info` output is optimized for clearer representation of each metric. For example, `time` now refers to the wall-clock time for operator execution, `loops` indicates how many times the current operator is called by its parent operator, and `total_time` represents the sum of all concurrent execution times. These optimizations help you better understand the SQL execution process and devise more targeted optimization strategies. + + For more information, see [documentation](/sql-statements/sql-statement-explain-analyze.md). ### Security ### Data migration From 86af83633c2ae40f17501eb34e06c3386cd3004f Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Thu, 27 Mar 2025 09:16:44 +0800 Subject: [PATCH 08/51] Update releases/release-9.0.0.md --- releases/release-9.0.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 1a6cd14138220..9d2d854adce30 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -57,6 +57,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- TiDB v9.0.0 optimizes the performance of these DCL (Data Control Language) operations, allowing 2 million users to be created in just 37 minutes. This greatly enhances the execution performance of DCL statements and improves the user experience of TiDB in such SaaS scenarios. For more information, see [documentation](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900). + * Support pushing down the following functions to TiFlash [#59317](https://github.com/pingcap/tidb/issues/59317) @[guo-shaoge](https://github.com/guo-shaoge) **tw@Oreoxmt** * `TRUNCATE()` From 3b1290a6f7a6e1b70f3a0a509b616cc7ae0b8fd9 Mon Sep 17 00:00:00 2001 From: qiancai Date: Thu, 27 Mar 2025 09:36:04 +0800 Subject: [PATCH 09/51] add English translation for 3 features --- releases/release-9.0.0.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 9d2d854adce30..9001d32109bea 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -64,6 +64,16 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/tiflash/tiflash-supported-pushdown-calculations.md). +* Support pushing down window functions that contain the following aggregation functions to TiFlash [#7376](https://github.com/pingcap/tiflash/issues/7376) @[xzhangxian1008](https://github.com/xzhangxian1008) **tw@qiancai** + + * `MAX` + * `MIN` + * `COUNT` + * `SUM` + * `AVG` + + For more information, see [documentation](/tiflash/tiflash-supported-pushdown-calculations.md). + * Support pushing down the following date functions to TiKV [#59365](https://github.com/pingcap/tidb/issues/59365) @[gengliqi](https://github.com/gengliqi) **tw@Oreoxmt** * `FROM_UNIXTIME()` @@ -72,6 +82,14 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/functions-and-operators/expressions-pushed-down.md). +* TiFlash supports a new storage format to improve the scanning efficiency of string types [#9673](https://github.com/pingcap/tiflash/issues/9673) @[JinheLin](https://github.com/JinheLin) **tw@qiancai** + + Before v9.0.0, TiFlash stores string data in a format that requires reading each row when scanning the data, which is inefficient for string data with a small length. In v9.0.0, TiFlash introduced a new storage format that optimizes the storage of strings whose length is less than 64 bytes, improving scanning efficiency without affecting the storage and scanning performance of other data. To enable the new storage format, you can set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. + + Before upgrading TiFlash, make sure to read the [TiFlash upgrade guide](/tiflash-upgrade-guide.md) first. + + For more information, see [user documentation](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file). + ### Availability * TiProxy officially supports the traffic replay feature (GA) [#642](https://github.com/pingcap/tiproxy/issues/642) @[djshow832](https://github.com/djshow832) tw@hfxsd @@ -90,6 +108,12 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### SQL +* Support creating global indexes on non-unique columns of partitioned tables [#58650](https://github.com/pingcap/tidb/issues/58650) @[Defined2014](https://github.com/Defined2014) @[mjonss](https://github.com/mjonss) **tw@qiancai** + + Starting from v8.3.0, TiDB supports creating global indexes on unique columns of partitioned tables to improve query performance, but does not support creating global indexes on non-unique columns yet. Starting from v9.0.0, TiDB removes this restriction, enabling you to create global indexes on non-unique columns of partitioned tables, improving the usability of global indexes. + + For more information, see [documentation](/partitioned-table.md#global-index). + ### Observability * SQL cross-AZ traffic monitoring [#57543](https://github.com/pingcap/tidb/issues/57543) @[nolouch](https://github.com/nolouch) @[yibin87](https://github.com/yibin87) **tw@Oreoxmt** From 606a4170af96e19192e033f331820b12f79c924a Mon Sep 17 00:00:00 2001 From: qiancai Date: Thu, 27 Mar 2025 09:48:11 +0800 Subject: [PATCH 10/51] update the descriptions for two features --- releases/release-9.0.0.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 9001d32109bea..379c58ca78110 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -82,9 +82,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/functions-and-operators/expressions-pushed-down.md). -* TiFlash supports a new storage format to improve the scanning efficiency of string types [#9673](https://github.com/pingcap/tiflash/issues/9673) @[JinheLin](https://github.com/JinheLin) **tw@qiancai** +* TiFlash supports a new storage format to improve the scanning efficiency of string data [#9673](https://github.com/pingcap/tiflash/issues/9673) @[JinheLin](https://github.com/JinheLin) **tw@qiancai** - Before v9.0.0, TiFlash stores string data in a format that requires reading each row when scanning the data, which is inefficient for string data with a small length. In v9.0.0, TiFlash introduced a new storage format that optimizes the storage of strings whose length is less than 64 bytes, improving scanning efficiency without affecting the storage and scanning performance of other data. To enable the new storage format, you can set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. + Before v9.0.0, TiFlash stores string data in a format that requires to read each row individually when scanning the data, which is inefficient for short strings. In v9.0.0, TiFlash introduced a new storage format that optimizes the storage of strings shorter than 64 bytes, improving scanning efficiency without affecting the storage and scanning performance of other data. To enable the new storage format, set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. Before upgrading TiFlash, make sure to read the [TiFlash upgrade guide](/tiflash-upgrade-guide.md) first. @@ -110,7 +110,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * Support creating global indexes on non-unique columns of partitioned tables [#58650](https://github.com/pingcap/tidb/issues/58650) @[Defined2014](https://github.com/Defined2014) @[mjonss](https://github.com/mjonss) **tw@qiancai** - Starting from v8.3.0, TiDB supports creating global indexes on unique columns of partitioned tables to improve query performance, but does not support creating global indexes on non-unique columns yet. Starting from v9.0.0, TiDB removes this restriction, enabling you to create global indexes on non-unique columns of partitioned tables, improving the usability of global indexes. + Starting from v8.3.0, you can create global indexes on unique columns of partitioned tables in TiDB to improve query performance. However, creating global indexes on non-unique columns was not supported. Starting from v9.0.0, TiDB removes this restriction, enabling you to create global indexes on non-unique columns of partitioned tables, enhancing the usability of global indexes. For more information, see [documentation](/partitioned-table.md#global-index). From 4712417a471d45c4449d47c9e70b77706d3dbab3 Mon Sep 17 00:00:00 2001 From: qiancai Date: Fri, 28 Mar 2025 10:51:37 +0800 Subject: [PATCH 11/51] update the feature description for #9673 --- releases/release-9.0.0.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 379c58ca78110..d5d64b68eb3f8 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -84,11 +84,14 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * TiFlash supports a new storage format to improve the scanning efficiency of string data [#9673](https://github.com/pingcap/tiflash/issues/9673) @[JinheLin](https://github.com/JinheLin) **tw@qiancai** - Before v9.0.0, TiFlash stores string data in a format that requires to read each row individually when scanning the data, which is inefficient for short strings. In v9.0.0, TiFlash introduced a new storage format that optimizes the storage of strings shorter than 64 bytes, improving scanning efficiency without affecting the storage and scanning performance of other data. To enable the new storage format, set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. + Before v9.0.0, TiFlash stores string data in a format that requires to read each row individually when scanning the data, which is inefficient for short strings. In v9.0.0, TiFlash introduces a new storage format that optimizes the storage of strings, improving the scanning efficiency of strings shorter than 64 bytes without affecting the storage and scanning performance of other data. - Before upgrading TiFlash, make sure to read the [TiFlash upgrade guide](/tiflash-upgrade-guide.md) first. + - For newly deployed TiDB clusters with v9.0.0 or a later version, TiFlash uses the new storage format by default. + - For TiDB clusters upgraded to v9.0.0 or a later version, it is recommended to read [TiFlash upgrade guide](/tiflash-upgrade-guide.md) before the upgrade. + - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is not specified for TiFlash before the upgrade, TiFlash uses the new storage format by default after the upgrade. + - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is specified for TiFlash before the upgrade, the value of `format_version` remains unchanged after the upgrade, and TiFlash continues to use the storage format specified by `format_version`. To enable the new storage format in this case, set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. - For more information, see [user documentation](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file). + For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). ### Availability From 119eecfb2ce1aecd2197f2312db66a8e0386aa60 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Thu, 27 Mar 2025 15:55:22 +0800 Subject: [PATCH 12/51] Update release-9.0.0.md --- releases/release-9.0.0.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index d5d64b68eb3f8..dcfed629915d2 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -119,7 +119,36 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Observability -* SQL cross-AZ traffic monitoring [#57543](https://github.com/pingcap/tidb/issues/57543) @[nolouch](https://github.com/nolouch) @[yibin87](https://github.com/yibin87) **tw@Oreoxmt** +* Add the TiDB Workload Repository feature to support persisting historical workload data into TiKV [#58247](https://github.com/pingcap/tidb/issues/58247) @[xhebox](https://github.com/xhebox) @[henrybw](https://github.com/henrybw) @[wddevries](https://github.com/wddevries) **tw@lilin90** + + Many frequently updated workload metrics and status information are maintained in the memory of the instance. Such historical workload data can be persisted as part of the database for the following purposes: + + * **Troubleshooting:** when diagnosing issues, it is necessary to review historical activities and events. Persisted workload data can help you revisit the state changes during a specific time period, identify anomalies, or precisely locate the specific behavior of a database session or SQL statement at a particular moment. + * **Automated operations:** database autonomy is an inevitable trend to enhance user experience and lower usage barriers. Achieving automated database tuning requires historical data. Based on persisted historical workload data, TiDB can gradually move towards automated operations, such as Index Advisor, Statistics Advisor, and SQL Binding Advisor. + + In v9.0.0, you can enable the Workload Repository by setting the [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900) system variable. TiDB continuously writes snapshots of certain in-memory tables into the `workload_schema`, persisting them in TiKV. This feature is disabled by default. By persisting historical workload data, TiDB can better facilitate troubleshooting and optimization recommendations. In the future, a series of automated tools based on historical workload data will be introduced to enhance the user experience in database operations and diagnostics. The persisted in-memory tables are categorized into two types: + + - **In-memory tables storing cumulative metrics**: these tables are larger in size, and their snapshots and storage costs are relatively high. Snapshots are taken in batches based on the [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) setting, with a minimum interval of 15 minutes. By comparing the changes between any two snapshots, you can calculate the incremental metrics over a specific period. These tables include: + + - [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) + - [`INFORMATION_SCHEMA.TIDB_STATEMENTS_STATS`](/statement-summary-tables.md) (Derived from `STATEMENTS_SUMMARY`, planned to replace it in the future.) + - [`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_HOST`](/information-schema/client-errors-summary-by-host.md) + - [`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER`](/information-schema/client-errors-summary-by-user.md) + - [`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_GLOBAL`](/information-schema/client-errors-summary-global.md) + + - **In-memory tables storing real-time states**: these tables are refreshed frequently and are usually smaller in size. Snapshots with very short intervals are necessary for them to be effective. You can specify the interval using the [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) system variable, which defaults to 5 seconds. Setting it to `0` disables snapshots for this type of table. These tables include: + + - [`INFORMATION_SCHEMA.PROCESSLIST`](/information-schema/information-schema-processlist.md) + - [`INFORMATION_SCHEMA.DATA_LOCK_WAITS`](/information-schema/information-schema-data-lock-waits.md) + - [`INFORMATION_SCHEMA.TIDB_TRX`](/information-schema/information-schema-tidb-trx.md) + - [`INFORMATION_SCHEMA.MEMORY_USAGE`](/information-schema/information-schema-memory-usage.md) + - [`INFORMATION_SCHEMA.DEADLOCKS`](/information-schema/information-schema-deadlocks.md) + + Data in the Workload Repository is automatically cleaned up, with a default retention period of 7 days. You can modify the retention period by setting the [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) system variable. + + For more information, see [documentation](/workloadrepo.md). + + * SQL cross-AZ traffic monitoring [#57543](https://github.com/pingcap/tidb/issues/57543) @[nolouch](https://github.com/nolouch) @[yibin87](https://github.com/yibin87) **tw@Oreoxmt** Deploying TiDB clusters across Availability Zones (AZs) enhances the disaster recovery capability. However, in cloud environments, cross-AZ deployments incur additional network traffic costs. For example, AWS charges for both cross-region and cross-AZ traffic. Therefore, for TiDB clusters running on cloud services, accurately monitoring and analyzing network traffic is essential for cost control. @@ -136,6 +165,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- In v9.0.0, the `execution info` output is optimized for clearer representation of each metric. For example, `time` now refers to the wall-clock time for operator execution, `loops` indicates how many times the current operator is called by its parent operator, and `total_time` represents the sum of all concurrent execution times. These optimizations help you better understand the SQL execution process and devise more targeted optimization strategies. For more information, see [documentation](/sql-statements/sql-statement-explain-analyze.md). + ### Security ### Data migration From b13989224aa73d156dc782c177c1f3db1111e1b3 Mon Sep 17 00:00:00 2001 From: Aolin Date: Fri, 28 Mar 2025 11:07:01 +0800 Subject: [PATCH 13/51] Apply suggestions from code review --- releases/release-9.0.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index dcfed629915d2..bf4ebfbd5054b 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -176,9 +176,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/dm/dm-worker-configuration-file.md). -* Ensure TiDB Lightning compatibility with TiDB `sql_require_primary_key=ON` [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716] **tw@Oreoxmt** +* TiDB Lightning supports compatibility with `sql_require_primary_key=ON` in TiDB [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716](https://github.com/lance6716) **tw@Oreoxmt** - When `sql_require_primary_key=ON` is enabled in TiDB, tables must have a primary key. TiDB Lightning now adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`), preventing table-creation failures. If you rely on these internal tables for automation, confirm the new naming and schema changes (primary key added), as scripts referencing older table names might need updates. + When you enable the system variable [`sql_require_primary_key`](/system-variables.md#sql_require_primary_key-new-in-v630) in TiDB, tables must have a primary key. To prevent table creation failures, TiDB Lightning adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`). If you have automation scripts that use these internal tables, update them to accommodate the new schema, which includes the primary key. * Migrate sync-diff-inspector from `pingcap/tidb-tools` to `pingcap/tiflow` repository [#11672](https://github.com/pingcap/tiflow/issues/11672) @[joechenrh](https://github.com/joechenrh) **tw@Oreoxmt** From 923a72bcc07899916bb1e600f932ca560408ed34 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Mon, 31 Mar 2025 12:29:22 +0800 Subject: [PATCH 14/51] Apply suggestions from code review --- releases/release-9.0.0.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index bf4ebfbd5054b..acde735a92397 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -103,9 +103,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Reliability -* Introduce a new system variable `MAX_USER_CONNECTIONS` to limit the number of connections that different users can establish [#59203](https://github.com/pingcap/tidb/issues/59203) @[joccau](https://github.com/joccau) tw@hfxsd +* Introduce a new system variable `max_user_connections` to limit the number of connections that different users can establish [#59203](https://github.com/pingcap/tidb/issues/59203) @[joccau](https://github.com/joccau) tw@hfxsd - Starting from v9.0.0, you can use the `MAX_USER_CONNECTIONS` system variable to limit the number of connections a single user can establish to a single TiDB node. This helps prevent issues where excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user causes delays in responding to requests from other users. + Starting from v9.0.0, you can use the `max_user_connections` system variable to limit the number of connections a single user can establish to a single TiDB node. This helps prevent issues where excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user causes delays in responding to requests from other users. For more information, see [documentation](/system-variables.md/#max_user_connections-new-in-v900) @@ -208,7 +208,14 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Variable name | Change type | Description | |--------|------------------------------|------| -| | | | +| `txn_scope` | Deleted | Starting from v9.0.0, this variable is removed. | +| [`max_user_connections`](/system-variables.md/#max_user_connections-new-in-v900) | Newly added | Controls the number of connections a single user can establish to a single TiDB node, preventing excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user from delaying responses to other users' requests. | +| [`tidb_accelerate_user_creation_update`](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900)| Newly added | Improves the performance of creating and modifying users in scenarios with hundreds of thousands to millions of users. | +| [`tidb_max_dist_task_nodes`](/system-variables.md/#tidb_max_dist_task_nodes-new-in-v900)| Newly added | Controls the maximum number of TiDB nodes available for distributed framework tasks. The default value is `-1`, which enables automatic mode. In this mode, the system automatically selects an appropriate number of nodes. | +| [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Time-based Sampling Process. | +| [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900)| Newly added | Controls the destination of the [Workload Repository](/workloadrepo.md. The default value is `''`, which means to disable the workload repository. The value `'table'` enables the workload repository to write data into TiKV.| +| [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) | Newly added | Controls the number of days that [Workload Repository](/workloadrepo.md) data is retained. | +| [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Snapshot Sampling Process. | | | | | | | | | | | | | @@ -218,6 +225,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Configuration file or component | Configuration parameter | Change type | Description | | -------- | -------- | -------- | -------- | | DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | +| BR | [`--checkpoint-storage`](br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | | | | | | ### Offline package changes From cb81735628cf7d1d54cdb1a3e924d12a6fa53b72 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Mon, 7 Apr 2025 09:54:05 +0800 Subject: [PATCH 15/51] Apply suggestions from code review Co-authored-by: Roger Song --- releases/release-9.0.0.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index acde735a92397..a64351a2e1683 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -124,11 +124,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Many frequently updated workload metrics and status information are maintained in the memory of the instance. Such historical workload data can be persisted as part of the database for the following purposes: * **Troubleshooting:** when diagnosing issues, it is necessary to review historical activities and events. Persisted workload data can help you revisit the state changes during a specific time period, identify anomalies, or precisely locate the specific behavior of a database session or SQL statement at a particular moment. - * **Automated operations:** database autonomy is an inevitable trend to enhance user experience and lower usage barriers. Achieving automated database tuning requires historical data. Based on persisted historical workload data, TiDB can gradually move towards automated operations, such as Index Advisor, Statistics Advisor, and SQL Binding Advisor. + * **Automation:** database autonomy is an inevitable trend to enhance user experience and lower usage barriers. Achieving automated database tuning requires historical data. Based on persisted historical workload data, TiDB can gradually move towards intelligent recommendations, such as Index Advisor, Statistics Advisor, and SQL Binding Advisor. - In v9.0.0, you can enable the Workload Repository by setting the [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900) system variable. TiDB continuously writes snapshots of certain in-memory tables into the `workload_schema`, persisting them in TiKV. This feature is disabled by default. By persisting historical workload data, TiDB can better facilitate troubleshooting and optimization recommendations. In the future, a series of automated tools based on historical workload data will be introduced to enhance the user experience in database operations and diagnostics. The persisted in-memory tables are categorized into two types: + In v9.0.0, you can enable the Workload Repository by setting the [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900) system variable. TiDB continuously writes snapshots of certain memory tables into the `workload_schema`, persisting them in TiKV. This feature is disabled by default. By persisting historical workload data, TiDB can better facilitate troubleshooting and recommendations. In the future, a series of automated tools based on historical workload data will be introduced to enhance the user experience in database operations and diagnostics. The persisted memory tables are categorized into two types: - - **In-memory tables storing cumulative metrics**: these tables are larger in size, and their snapshots and storage costs are relatively high. Snapshots are taken in batches based on the [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) setting, with a minimum interval of 15 minutes. By comparing the changes between any two snapshots, you can calculate the incremental metrics over a specific period. These tables include: + - **Memory tables storing cumulative metrics**: these tables are larger in size, and their snapshots and storage costs are relatively high. Snapshots are taken in batches based on the [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) setting, with a minimum interval of 15 minutes. By comparing the changes between any two snapshots, you can calculate the incremental metrics over a specific period. These tables include: - [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) - [`INFORMATION_SCHEMA.TIDB_STATEMENTS_STATS`](/statement-summary-tables.md) (Derived from `STATEMENTS_SUMMARY`, planned to replace it in the future.) @@ -136,7 +136,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- - [`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER`](/information-schema/client-errors-summary-by-user.md) - [`INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_GLOBAL`](/information-schema/client-errors-summary-global.md) - - **In-memory tables storing real-time states**: these tables are refreshed frequently and are usually smaller in size. Snapshots with very short intervals are necessary for them to be effective. You can specify the interval using the [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) system variable, which defaults to 5 seconds. Setting it to `0` disables snapshots for this type of table. These tables include: + - **Memory tables storing real-time states**: these tables are updated frequently and are usually smaller in size. Snapshots with very short intervals are necessary for them to be effective. You can specify the interval using the [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) system variable, which defaults to 5 seconds. Setting it to `0` disables snapshots for this type of tables. These tables include: - [`INFORMATION_SCHEMA.PROCESSLIST`](/information-schema/information-schema-processlist.md) - [`INFORMATION_SCHEMA.DATA_LOCK_WAITS`](/information-schema/information-schema-data-lock-waits.md) @@ -154,7 +154,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Starting from v9.0.0, TiDB records the network traffic generated during SQL processing and distinguishes cross-AZ traffic. TiDB writes this data to the [`statements_summary` table](/statement-summary-tables.md) and [slow query logs](/identify-slow-queries.md). This feature helps you track major data transmission paths within TiDB clusters, analyze the sources of cross-AZ traffic, and better understand and control related costs. - Note that the current version monitors only SQL query traffic **within the cluster** (between TiDB, TiKV, and TiFlash) and does not include DML or DDL operations. Additionally, the recorded traffic data represents unpacked traffic, which differs from actual physical traffic and cannot be used directly for network billing. + Note that the current version includes only **query** traffic **within the cluster** (between TiDB, TiKV, and TiFlash) and does not include DML or DDL operations. Additionally, the recorded traffic data represents unpacked bytes, which differs from the actual physical bytes transmitted and cannot be used for billing purpose. For more information, see [documentation](/statement-summary-tables.md#statements_summary-fields-description). @@ -162,7 +162,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- [`EXPLAIN ANALYZE`](https://github.com/sql-statements/sql-statement-explain-analyze.md) executes SQL statements and records execution details in the `execution info` column. The same information is captured in the [slow query log](https://github.com/identify-slow-queries.md). These details are crucial for analyzing and understanding the time spent on SQL execution. - In v9.0.0, the `execution info` output is optimized for clearer representation of each metric. For example, `time` now refers to the wall-clock time for operator execution, `loops` indicates how many times the current operator is called by its parent operator, and `total_time` represents the sum of all concurrent execution times. These optimizations help you better understand the SQL execution process and devise more targeted optimization strategies. + In v9.0.0, the `execution info` output is optimized for clearer representation of each metric. For example, `time` now refers to the wall-clock time for operator execution, `loops` indicates how many times the current operator is called by its parent operator, and `total_time` represents the cumulative duration of all concurrent executions. These optimizations help you better understand the SQL execution process and devise more targeted optimization strategies. For more information, see [documentation](/sql-statements/sql-statement-explain-analyze.md). @@ -226,6 +226,8 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | -------- | -------- | -------- | -------- | | DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | | BR | [`--checkpoint-storage`](br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | +| TiProxy | [`enable-traffic-replay`](/tiproxy/tiproxy-configuration.md#enable-traffic-replay) | Newly added | Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. | +| TiProxy | [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path) | Newly added | Specifies the file path of the key used to encrypt the traffic files during traffic capture. | | | | | | ### Offline package changes From cefed67931c4733f440be74ed27c044b7aa27a3b Mon Sep 17 00:00:00 2001 From: qiancai Date: Mon, 7 Apr 2025 17:28:31 +0800 Subject: [PATCH 16/51] add compatibility changes --- releases/release-9.0.0.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index a64351a2e1683..97b499357f129 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -203,6 +203,8 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Behavior changes * TiDB Lightning internal error-logging and conflict-detection tables names changed to `conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`, and now have primary keys. If you rely on these internal tables for automation, confirm the new naming and schema changes [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716] +* Starting from v9.0.0, TiFlash changes the storage format of string data to optimize the string read and write performance. Therefore, after TiFlash is upgraded to v9.0.0 or a later version, in-place downgrading to the original version is not supported. For more information, see [TiFlash upgrade guide](/tiflash-upgrade-guide.md). +* Starting from v9.0.0, TiCDC introduces a [security mechanism](/ticdc/ticdc-manage-changefeed.md#security-mechanism) to prevent users from accidentally configuring the same TiDB cluster as both the upstream and downstream for data replication, which could lead to circular replication and data anomalies. When creating, updating, or resuming a replication task, TiCDC automatically checks whether the upstream and downstream TiDB clusters have the same `cluster_id`. If TiCDC detects the same `cluster_id` for both the upstream and downstream, it will reject the task. ### System variables @@ -210,6 +212,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- |--------|------------------------------|------| | `txn_scope` | Deleted | Starting from v9.0.0, this variable is removed. | | [`max_user_connections`](/system-variables.md/#max_user_connections-new-in-v900) | Newly added | Controls the number of connections a single user can establish to a single TiDB node, preventing excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user from delaying responses to other users' requests. | +| [`mpp_version`](/system-variables.md#mpp_version-new-in-v660) | Newly added | Adds the `3` option, which enables the new string data exchange format for TiFlash. When this variable is not specified, TiDB automatically selects the latest version `3` of the MPP execution plan to improve the serialization and deserialization efficiency of strings, thereby enhancing query performance. | +| [`pd_enable_follower_handle_region`](/system-variables.md#pd_enable_follower_handle_region-new-in-v760) | Newly added | Changes the default value from `OFF` to `ON`. When it is `ON`, TiDB evenly distributes Region information requests to all PD servers, so PD followers can also handle Region requests, reducing the CPU pressure on the PD leader. Starting from v9.0.0, Region information requests from TiDB Lightning are also evenly sent to all PD nodes when the value is `ON`. | +| [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) | Newly added | Controls the resource usage policy for [Pipelined DML](/pipelined-dml.md). It takes effect only when [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `bulk`. | | [`tidb_accelerate_user_creation_update`](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900)| Newly added | Improves the performance of creating and modifying users in scenarios with hundreds of thousands to millions of users. | | [`tidb_max_dist_task_nodes`](/system-variables.md/#tidb_max_dist_task_nodes-new-in-v900)| Newly added | Controls the maximum number of TiDB nodes available for distributed framework tasks. The default value is `-1`, which enables automatic mode. In this mode, the system automatically selects an appropriate number of nodes. | | [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Time-based Sampling Process. | @@ -224,6 +229,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Configuration file or component | Configuration parameter | Change type | Description | | -------- | -------- | -------- | -------- | +| TiKV | [`storage.max-ts.action-on-invalid-update`](/tikv-configuration-file.md#action-on-invalid-update-new-in-v900) | Newly added | Determines how TiKV handles invalid `max-ts` update requests. The default value is `"panic"`, which means that TiKV panics when it detects invalid `max-ts` update requests. | +| TiKV | [`storage.max-ts.cache-sync-interval`](/tikv-configuration-file.md#cache-sync-interval-new-in-v900) | Newly added | Controls the interval at which TiKV updates its local PD TSO cache. The default value is `"15s"`. | +| TiKV | [`storage.max-ts.max-drift`](/tikv-configuration-file.md#max-drift-new-in-v900) | Newly added | Specifies the maximum time by which the timestamp of a read or write request can exceed the PD TSO cached in TiKV. The default value is `"60s"`. | +| TiFlash| [`format_version`](/tiflash/tiflash-configuration.md#format_version) | Modified | Changes the default value from `7` to `8`, which means the default DTFile file format for v9.0.0 or a later version is `8`. This new format supports a new string serialization scheme that improves string read and write performance. | +| TiCDC | [`newarch`](/ticdc/ticdc-server-config.md#newarch) | Newly added | Controls whether to enable the [TiCDC new architecture](/ticdc/ticdc-new-arch.md). By default, `newarch` is not specified, indicating that the old architecture is used. `newarch` applies only to the new architecture. If `newarch` is added to the configuration file of the TiCDC old architecture, it might cause parsing failures. | | DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | | BR | [`--checkpoint-storage`](br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | | TiProxy | [`enable-traffic-replay`](/tiproxy/tiproxy-configuration.md#enable-traffic-replay) | Newly added | Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. | @@ -234,6 +244,12 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Starting from v9.0.0, the offline package location of the [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) tool in the `TiDB-community-toolkit` [binary package](/binary-package.md) is changed from `sync_diff_inspector` to `tiflow-{version}-linux-{arch}.tar.gz`. +### System table changes + +| System table | Change type | Description | +| -------- | -------- | -------- | +| [`mysql.tidb`](/mysql-schema/mysql-schema.md#cluster-status-system-tables) | Modified | Adds the `cluster_id` field, which represents the unique identifier of a TiDB cluster. Note that `cluster_id` is read-only and cannot be modified. | + ### Operating system and platform requirement changes Before upgrading TiDB, ensure that your operating system version meets the [OS and platform requirements](/hardware-and-software-requirements.md#os-and-platform-requirements). From 7064fcdc5348982864b3b64245ed7bcc97e46889 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Tue, 8 Apr 2025 14:27:41 +0800 Subject: [PATCH 17/51] Update releases/release-9.0.0.md --- releases/release-9.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 97b499357f129..ffab684fc6355 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -216,7 +216,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | [`pd_enable_follower_handle_region`](/system-variables.md#pd_enable_follower_handle_region-new-in-v760) | Newly added | Changes the default value from `OFF` to `ON`. When it is `ON`, TiDB evenly distributes Region information requests to all PD servers, so PD followers can also handle Region requests, reducing the CPU pressure on the PD leader. Starting from v9.0.0, Region information requests from TiDB Lightning are also evenly sent to all PD nodes when the value is `ON`. | | [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) | Newly added | Controls the resource usage policy for [Pipelined DML](/pipelined-dml.md). It takes effect only when [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `bulk`. | | [`tidb_accelerate_user_creation_update`](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900)| Newly added | Improves the performance of creating and modifying users in scenarios with hundreds of thousands to millions of users. | -| [`tidb_max_dist_task_nodes`](/system-variables.md/#tidb_max_dist_task_nodes-new-in-v900)| Newly added | Controls the maximum number of TiDB nodes available for distributed framework tasks. The default value is `-1`, which enables automatic mode. In this mode, the system automatically selects an appropriate number of nodes. | +| [`tidb_max_dist_task_nodes`](/system-variables.md/#tidb_max_dist_task_nodes-new-in-v900)| Newly added | Controls the maximum number of TiDB nodes available for the Distributed eXecution Framework (DXF) tasks. The default value is `-1`, which enables automatic mode. In this mode, the system automatically selects an appropriate number of nodes. | | [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Time-based Sampling Process. | | [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900)| Newly added | Controls the destination of the [Workload Repository](/workloadrepo.md. The default value is `''`, which means to disable the workload repository. The value `'table'` enables the workload repository to write data into TiKV.| | [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) | Newly added | Controls the number of days that [Workload Repository](/workloadrepo.md) data is retained. | From 462ddaa308d9d0fefc5d1a1a134c13bdd0965b37 Mon Sep 17 00:00:00 2001 From: Aolin Date: Mon, 14 Apr 2025 15:42:27 +0800 Subject: [PATCH 18/51] add DB operations --- releases/release-9.0.0.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index ffab684fc6355..89de1c2e5ffd6 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -117,6 +117,16 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/partitioned-table.md#global-index). +### DB operations + +* TiDB Index Advisor [#12303](https://github.com/pingcap/tidb/issues/12303) @[qw4990](https://github.com/qw4990) **tw@Oreoxmt** + + Index design is essential for database performance optimization. Starting from v8.5.0, TiDB introduces the Index Advisor feature and continues to improve and enhance it. This feature analyzes high-frequency query patterns, recommends optimal indexing strategies, helps you tune performance more efficiently, and lowers the barrier to entry. + + You can use the [`RECOMMEND INDEX`](/index-advisor.md#recommend-indexes-using-the-recommend-index-statement) SQL statement to generate index recommendations for a single query or automatically analyze high-frequency SQL statements from historical workloads for batch recommendations. The recommendation results are stored in the `mysql.index_advisor_results` table. You can query this table to view the recommended indexes. + + For more information, see [documentation](/index-advisor.md). + ### Observability * Add the TiDB Workload Repository feature to support persisting historical workload data into TiKV [#58247](https://github.com/pingcap/tidb/issues/58247) @[xhebox](https://github.com/xhebox) @[henrybw](https://github.com/henrybw) @[wddevries](https://github.com/wddevries) **tw@lilin90** From 64be9539ee164a85e1b415b78bfb130ccd7b4692 Mon Sep 17 00:00:00 2001 From: Aolin Date: Mon, 14 Apr 2025 16:08:07 +0800 Subject: [PATCH 19/51] update DM log redaction --- releases/release-9.0.0.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 89de1c2e5ffd6..2adc9ea5e51e8 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -180,11 +180,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Data migration -* Support query argument redaction in DM logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will] **tw@Oreoxmt** +* Support query argument redaction in DM logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will](https://github.com/db-will) **tw@Oreoxmt** - Introduces a new `redact-info-log` parameter, allowing DM to replace sensitive query arguments with `?` placeholders in DM logs. You can enable this feature by setting `redact-info-log = true` in the DM-worker configuration file or passing `--redact-info-log=true` at startup. This change only redacts query arguments (not entire SQL statements) and requires a DM-worker restart to take effect. + Starting from v9.0.0, you can use the `redact-info-log` configuration item to enable the DM log redaction feature. When enabled, query arguments that contain sensitive data in DM logs are replaced with the `?` placeholder. To enable this feature, set `redact-info-log` to `true` in the DM-worker configuration file or pass `--redact-info-log=true` when starting DM. This feature only desensitizes query arguments, not the entire SQL statement, and requires a DM-worker restart to take effect. - For more information, see [documentation](/dm/dm-worker-configuration-file.md). + For more information, see [documentation](/dm/dm-worker-configuration-file.md#redact-info-log-new-in-v900). * TiDB Lightning supports compatibility with `sql_require_primary_key=ON` in TiDB [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716](https://github.com/lance6716) **tw@Oreoxmt** From 7290c8f46baff32d2c42c8789af63b125204179a Mon Sep 17 00:00:00 2001 From: Aolin Date: Mon, 14 Apr 2025 16:24:02 +0800 Subject: [PATCH 20/51] Compatibility changes: add tidb_hash_join_version, hashagg_use_magic_hash, and redact-info-log --- releases/release-9.0.0.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 2adc9ea5e51e8..86c333c225d74 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -221,6 +221,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Variable name | Change type | Description | |--------|------------------------------|------| | `txn_scope` | Deleted | Starting from v9.0.0, this variable is removed. | +| [`tidb_hash_join_version`](/system-variables.md#tidb_hash_join_version-new-in-v840) | Modified | Changes the default value from `legacy` to `optimized` after further tests, meaning that TiDB uses the [optimized version of hash join](/sql-statements/sql-statement-explain-analyze.md#hashjoinv2) to execute hash join for better performance. | | [`max_user_connections`](/system-variables.md/#max_user_connections-new-in-v900) | Newly added | Controls the number of connections a single user can establish to a single TiDB node, preventing excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user from delaying responses to other users' requests. | | [`mpp_version`](/system-variables.md#mpp_version-new-in-v660) | Newly added | Adds the `3` option, which enables the new string data exchange format for TiFlash. When this variable is not specified, TiDB automatically selects the latest version `3` of the MPP execution plan to improve the serialization and deserialization efficiency of strings, thereby enhancing query performance. | | [`pd_enable_follower_handle_region`](/system-variables.md#pd_enable_follower_handle_region-new-in-v760) | Newly added | Changes the default value from `OFF` to `ON`. When it is `ON`, TiDB evenly distributes Region information requests to all PD servers, so PD followers can also handle Region requests, reducing the CPU pressure on the PD leader. Starting from v9.0.0, Region information requests from TiDB Lightning are also evenly sent to all PD nodes when the value is `ON`. | @@ -239,13 +240,14 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | Configuration file or component | Configuration parameter | Change type | Description | | -------- | -------- | -------- | -------- | +| TiKV | [`hashagg_use_magic_hash`](/tikv-configuration-file.md#hashagg_use_magic_hash-new-in-v900) | Newly added | Controls the hash function TiFlash uses for aggregation. | | TiKV | [`storage.max-ts.action-on-invalid-update`](/tikv-configuration-file.md#action-on-invalid-update-new-in-v900) | Newly added | Determines how TiKV handles invalid `max-ts` update requests. The default value is `"panic"`, which means that TiKV panics when it detects invalid `max-ts` update requests. | | TiKV | [`storage.max-ts.cache-sync-interval`](/tikv-configuration-file.md#cache-sync-interval-new-in-v900) | Newly added | Controls the interval at which TiKV updates its local PD TSO cache. The default value is `"15s"`. | | TiKV | [`storage.max-ts.max-drift`](/tikv-configuration-file.md#max-drift-new-in-v900) | Newly added | Specifies the maximum time by which the timestamp of a read or write request can exceed the PD TSO cached in TiKV. The default value is `"60s"`. | | TiFlash| [`format_version`](/tiflash/tiflash-configuration.md#format_version) | Modified | Changes the default value from `7` to `8`, which means the default DTFile file format for v9.0.0 or a later version is `8`. This new format supports a new string serialization scheme that improves string read and write performance. | | TiCDC | [`newarch`](/ticdc/ticdc-server-config.md#newarch) | Newly added | Controls whether to enable the [TiCDC new architecture](/ticdc/ticdc-new-arch.md). By default, `newarch` is not specified, indicating that the old architecture is used. `newarch` applies only to the new architecture. If `newarch` is added to the configuration file of the TiCDC old architecture, it might cause parsing failures. | -| DM | [--redact-info-log](/dm/dm-command-line-flags/#--redact-info-log) | Newly added | Controls whether DM replaces sensitive query arguments with ? placeholders in logs. The default value is false. When set to true, query arguments in DM logs are redacted. This parameter only redacts query arguments (not entire SQL statements), and requires a DM-worker restart to take effect. | | BR | [`--checkpoint-storage`](br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | +| DM | [`redact-info-log`](/dm/dm-worker-configuration-file.md#redact-info-log-new-in-v900) | Newly added | Controls whether to enable DM log redaction. | | TiProxy | [`enable-traffic-replay`](/tiproxy/tiproxy-configuration.md#enable-traffic-replay) | Newly added | Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. | | TiProxy | [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path) | Newly added | Specifies the file path of the key used to encrypt the traffic files during traffic capture. | | | | | | From f0382ae9ad0ac72623fcda1fd73da3d5dda4302e Mon Sep 17 00:00:00 2001 From: Aolin Date: Tue, 15 Apr 2025 15:29:18 +0800 Subject: [PATCH 21/51] Apply suggestions from code review Co-authored-by: Grace Cai --- releases/release-9.0.0.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 86c333c225d74..03b4d35030b04 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -58,7 +58,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900). -* Support pushing down the following functions to TiFlash [#59317](https://github.com/pingcap/tidb/issues/59317) @[guo-shaoge](https://github.com/guo-shaoge) **tw@Oreoxmt** +* Support pushing down the following function to TiFlash [#59317](https://github.com/pingcap/tidb/issues/59317) @[guo-shaoge](https://github.com/guo-shaoge) **tw@Oreoxmt** * `TRUNCATE()` @@ -121,7 +121,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * TiDB Index Advisor [#12303](https://github.com/pingcap/tidb/issues/12303) @[qw4990](https://github.com/qw4990) **tw@Oreoxmt** - Index design is essential for database performance optimization. Starting from v8.5.0, TiDB introduces the Index Advisor feature and continues to improve and enhance it. This feature analyzes high-frequency query patterns, recommends optimal indexing strategies, helps you tune performance more efficiently, and lowers the barrier to entry. + Index design is essential for database performance optimization. Starting from v8.5.0, TiDB introduces the Index Advisor feature and continues to improve and enhance it. This feature analyzes high-frequency query patterns, recommends optimal indexing strategies, helps you tune performance more efficiently, and lowers the barrier to index design. You can use the [`RECOMMEND INDEX`](/index-advisor.md#recommend-indexes-using-the-recommend-index-statement) SQL statement to generate index recommendations for a single query or automatically analyze high-frequency SQL statements from historical workloads for batch recommendations. The recommendation results are stored in the `mysql.index_advisor_results` table. You can query this table to view the recommended indexes. @@ -164,7 +164,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Starting from v9.0.0, TiDB records the network traffic generated during SQL processing and distinguishes cross-AZ traffic. TiDB writes this data to the [`statements_summary` table](/statement-summary-tables.md) and [slow query logs](/identify-slow-queries.md). This feature helps you track major data transmission paths within TiDB clusters, analyze the sources of cross-AZ traffic, and better understand and control related costs. - Note that the current version includes only **query** traffic **within the cluster** (between TiDB, TiKV, and TiFlash) and does not include DML or DDL operations. Additionally, the recorded traffic data represents unpacked bytes, which differs from the actual physical bytes transmitted and cannot be used for billing purpose. + Note that the current version includes only **query** traffic **within the cluster** (between TiDB, TiKV, and TiFlash) and does not include traffic caused by DML or DDL operations. Additionally, the recorded traffic data reflects unpacked bytes rather than the actual physical bytes transmitted, so it cannot be used for billing purposes. For more information, see [documentation](/statement-summary-tables.md#statements_summary-fields-description). @@ -180,19 +180,19 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Data migration -* Support query argument redaction in DM logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will](https://github.com/db-will) **tw@Oreoxmt** +* Support query argument redaction in Data Migration (DM) logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will](https://github.com/db-will) **tw@Oreoxmt** - Starting from v9.0.0, you can use the `redact-info-log` configuration item to enable the DM log redaction feature. When enabled, query arguments that contain sensitive data in DM logs are replaced with the `?` placeholder. To enable this feature, set `redact-info-log` to `true` in the DM-worker configuration file or pass `--redact-info-log=true` when starting DM. This feature only desensitizes query arguments, not the entire SQL statement, and requires a DM-worker restart to take effect. + Starting from v9.0.0, you can use the `redact-info-log` configuration item to enable the DM log redaction feature. When enabled, query arguments that contain sensitive data in DM logs are replaced with the `?` placeholder. To enable this feature, set `redact-info-log` to `true` in the DM-worker configuration file or pass `--redact-info-log=true` when starting DM. This feature only redacts query arguments, not the entire SQL statement, and requires a DM-worker restart to take effect. For more information, see [documentation](/dm/dm-worker-configuration-file.md#redact-info-log-new-in-v900). * TiDB Lightning supports compatibility with `sql_require_primary_key=ON` in TiDB [#57479](https://github.com/pingcap/tidb/issues/57479) @[lance6716](https://github.com/lance6716) **tw@Oreoxmt** - When you enable the system variable [`sql_require_primary_key`](/system-variables.md#sql_require_primary_key-new-in-v630) in TiDB, tables must have a primary key. To prevent table creation failures, TiDB Lightning adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`). If you have automation scripts that use these internal tables, update them to accommodate the new schema, which includes the primary key. + When the system variable [`sql_require_primary_key`](/system-variables.md#sql_require_primary_key-new-in-v630) is enabled in TiDB, tables are required to have a primary key. To avoid table creation failures, TiDB Lightning adds a default primary key to its internal error-logging and conflict-detection tables (`conflict_error_v4`, `type_error_v2`, and `conflict_records_v2`). If you have automation scripts that depend on these internal tables, update them to accommodate the new schema, which now includes a primary key. * Migrate sync-diff-inspector from `pingcap/tidb-tools` to `pingcap/tiflow` repository [#11672](https://github.com/pingcap/tiflow/issues/11672) @[joechenrh](https://github.com/joechenrh) **tw@Oreoxmt** - Starting from v9.0.0, the sync-diff-inspector tool is moved from the [`pingcap/tidb-tools`](https://github.com/pingcap/tidb-tools) repository to [`pingcap/tiflow`](https://github.com/pingcap/tiflow). This change unifies replication and migration tools ([DM](/dm/dm-overview.md), [TiCDC](/ticdc/ticdc-overview.md), and [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md)) into a single repository. + Starting from v9.0.0, the sync-diff-inspector tool is moved from the [`pingcap/tidb-tools`](https://github.com/pingcap/tidb-tools) repository to [`pingcap/tiflow`](https://github.com/pingcap/tiflow). With this change, sync-diff-inspector is now maintained in the same repository as [DM](/dm/dm-overview.md) and [TiCDC](/ticdc/ticdc-overview.md), which unifies the management of these replication and migration tools. For TiDB v9.0.0 and later versions, you can install sync-diff-inspector using one of the following methods: From 2be9e036b7647b0eb324568a5419a29f501ec64d Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 16 Apr 2025 14:26:16 +0800 Subject: [PATCH 22/51] minor format updates --- releases/release-9.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 03b4d35030b04..dc2d0b293ec33 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -91,7 +91,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is not specified for TiFlash before the upgrade, TiFlash uses the new storage format by default after the upgrade. - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is specified for TiFlash before the upgrade, the value of `format_version` remains unchanged after the upgrade, and TiFlash continues to use the storage format specified by `format_version`. To enable the new storage format in this case, set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. - For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). + For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). ### Availability From d19e1946ac4683c9eee22f1d39da0d56af0175c5 Mon Sep 17 00:00:00 2001 From: Lilian Lee Date: Thu, 17 Apr 2025 14:52:46 +0800 Subject: [PATCH 23/51] Update a doc link --- releases/release-9.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index dc2d0b293ec33..d510ded21004e 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -156,7 +156,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Data in the Workload Repository is automatically cleaned up, with a default retention period of 7 days. You can modify the retention period by setting the [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) system variable. - For more information, see [documentation](/workloadrepo.md). + For more information, see [documentation](/workload-repository.md). * SQL cross-AZ traffic monitoring [#57543](https://github.com/pingcap/tidb/issues/57543) @[nolouch](https://github.com/nolouch) @[yibin87](https://github.com/yibin87) **tw@Oreoxmt** From dfe43537bcdcc8b8c76153278a206b7486938a48 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Mon, 21 Apr 2025 11:41:34 +0800 Subject: [PATCH 24/51] Revert "Merge remote-tracking branch 'upstream/master' into rn-9.0.0" This reverts commit 04c337e4d62c0cef112f0db758f7e337861b91cc, reversing changes made to 1a05ab85c02a0d5c0370c55a473121de8bc0456f. --- .github/workflows/doc_review.yml | 2 +- TOC.md | 68 +++-- _index.md | 2 +- basic-features.md | 2 +- benchmark/benchmark-tidb-using-tpcc.md | 2 +- best-practices/java-app-best-practices.md | 48 +--- .../three-nodes-hybrid-deployment.md | 2 +- br/backup-and-restore-storages.md | 6 +- br/br-checkpoint-restore.md | 72 +---- br/br-pitr-manual.md | 22 -- cached-tables.md | 2 +- dashboard/dashboard-access.md | 2 +- dashboard/dashboard-diagnostics-report.md | 2 +- dashboard/dashboard-faq.md | 2 +- ddl-introduction.md | 2 +- deploy-monitoring-services.md | 4 +- develop/dev-guide-build-cluster-in-cloud.md | 2 +- develop/dev-guide-create-table.md | 2 +- develop/dev-guide-gui-datagrip.md | 2 +- develop/dev-guide-gui-navicat.md | 6 +- develop/dev-guide-index-best-practice.md | 2 +- ...dev-guide-sql-development-specification.md | 2 +- develop/dev-guide-use-subqueries.md | 2 +- dm/dm-continuous-data-validation.md | 2 +- dm/dm-webui-guide.md | 2 +- dm/maintain-dm-using-tiup.md | 2 +- ecosystem-tool-user-guide.md | 4 +- enable-tls-between-components.md | 32 +-- encryption-at-rest.md | 2 +- .../json-functions/json-functions-validate.md | 4 +- functions-and-operators/locking-functions.md | 2 +- functions-and-operators/string-functions.md | 2 +- geo-distributed-deployment-topology.md | 2 +- identify-slow-queries.md | 2 +- .../client-errors-summary-by-user.md | 2 +- .../information-schema-sql-diagnostics.md | 2 +- .../information-schema-statistics.md | 2 +- .../information-schema-tables.md | 2 +- literal-values.md | 2 +- media/tiproxy/tiproxy-balance-label.png | Bin 98047 -> 86358 bytes optimizer-fix-controls.md | 2 +- optimizer-hints.md | 2 +- pipelined-dml.md | 8 - privilege-management.md | 22 -- releases/release-6.0.0-dmr.md | 2 +- releases/release-8.4.0.md | 6 +- security-compatibility-with-mysql.md | 2 +- sql-statements/sql-statement-admin.md | 24 -- .../sql-statement-cancel-traffic-jobs.md | 73 ----- sql-statements/sql-statement-commit.md | 2 +- sql-statements/sql-statement-drop-view.md | 2 +- sql-statements/sql-statement-rollback.md | 2 +- .../sql-statement-show-placement-for.md | 2 +- .../sql-statement-show-placement.md | 2 +- .../sql-statement-show-traffic-jobs.md | 77 ----- .../sql-statement-traffic-capture.md | 67 ----- .../sql-statement-traffic-replay.md | 71 ----- stale-read.md | 2 +- statement-summary-tables.md | 11 - statistics.md | 4 +- system-variable-reference.md | 29 +- system-variables.md | 156 ++-------- ...e-data-centers-in-two-cities-deployment.md | 2 +- ticdc/ticdc-avro-protocol.md | 1 - ticdc/ticdc-canal-json.md | 1 - ticdc/ticdc-csv.md | 1 - ticdc/ticdc-glossary.md | 2 +- ticdc/ticdc-manage-changefeed.md | 2 +- ticdc/ticdc-open-protocol.md | 1 - ticdc/ticdc-simple-protocol.md | 1 - ticdc/ticdc-sink-to-cloud-storage.md | 8 +- ticdc/ticdc-sink-to-mysql.md | 2 +- tidb-cloud/high-availability-with-multi-az.md | 2 +- tidb-cloud/integrate-tidbcloud-with-n8n.md | 2 +- tidb-cloud/limited-sql-features.md | 1 + tidb-cloud/ticloud-config-edit.md | 2 +- ...troubleshoot-import-access-denied-error.md | 2 +- tidb-configuration-file.md | 4 +- tidb-control.md | 2 +- tidb-monitoring-framework.md | 8 +- tidb-resource-control-ru-groups.md | 10 +- tidb-troubleshooting-map.md | 2 +- tiflash-upgrade-guide.md | 6 +- tiflash/tiflash-overview.md | 2 +- tikv-configuration-file.md | 2 +- tiproxy/tiproxy-command-line-flags.md | 51 ++-- tiproxy/tiproxy-configuration.md | 24 +- tiproxy/tiproxy-load-balance.md | 40 +-- tiproxy/tiproxy-traffic-replay.md | 269 +++++------------- tiup/tiup-cluster-topology-reference.md | 2 +- tiup/tiup-cluster.md | 2 +- tiup/tiup-command-mirror-rotate.md | 2 +- tiup/tiup-command-mirror-sign.md | 2 +- tiup/tiup-component-cluster-enable.md | 2 +- tiup/tiup-component-cluster-patch.md | 2 +- tiup/tiup-component-dm-patch.md | 2 +- tiup/tiup-component-dm.md | 2 +- tune-operating-system.md | 2 +- vector-search/vector-search-index.md | 4 +- ...vector-search-integrate-with-llamaindex.md | 2 +- workload-repository.md | 117 -------- wrong-index-solution.md | 2 +- 102 files changed, 272 insertions(+), 1213 deletions(-) delete mode 100644 sql-statements/sql-statement-cancel-traffic-jobs.md delete mode 100644 sql-statements/sql-statement-show-traffic-jobs.md delete mode 100644 sql-statements/sql-statement-traffic-capture.md delete mode 100644 sql-statements/sql-statement-traffic-replay.md delete mode 100644 workload-repository.md diff --git a/.github/workflows/doc_review.yml b/.github/workflows/doc_review.yml index 79614b63b3d24..091e286fd640b 100644 --- a/.github/workflows/doc_review.yml +++ b/.github/workflows/doc_review.yml @@ -76,7 +76,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} API_PROVIDER: "openai" # or "openai" if you want to use OpenAI OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - OPENAI_API_MODEL: "gpt-4o" + OPENAI_API_MODEL: "gpt-4" exclude: "**/*.json" # Optional: exclude patterns separated by commas REVIEW_MODE: ${{ steps.extract.outputs.REVIEW_MODE || 'default' }} COMMIT_SHA: ${{ steps.extract.outputs.COMMIT_SHA || '' }} diff --git a/TOC.md b/TOC.md index c862fcd2083dd..4b220ca8f39c4 100644 --- a/TOC.md +++ b/TOC.md @@ -280,37 +280,6 @@ - [Monitoring API](/tidb-monitoring-api.md) - [Deploy Monitoring Services](/deploy-monitoring-services.md) - [Upgrade Monitoring Services](/upgrade-monitoring-services.md) - - TiDB Dashboard - - [Overview](/dashboard/dashboard-intro.md) - - Maintain - - [Deploy](/dashboard/dashboard-ops-deploy.md) - - [Reverse Proxy](/dashboard/dashboard-ops-reverse-proxy.md) - - [User Management](/dashboard/dashboard-user.md) - - [Secure](/dashboard/dashboard-ops-security.md) - - [Access](/dashboard/dashboard-access.md) - - [Overview Page](/dashboard/dashboard-overview.md) - - [Cluster Info Page](/dashboard/dashboard-cluster-info.md) - - [Top SQL Page](/dashboard/top-sql.md) - - [Key Visualizer Page](/dashboard/dashboard-key-visualizer.md) - - [Metrics Relation Graph](/dashboard/dashboard-metrics-relation.md) - - SQL Statements Analysis - - [SQL Statements Page](/dashboard/dashboard-statement-list.md) - - [SQL Details Page](/dashboard/dashboard-statement-details.md) - - [Slow Queries Page](/dashboard/dashboard-slow-query.md) - - Cluster Diagnostics - - [Access Cluster Diagnostics Page](/dashboard/dashboard-diagnostics-access.md) - - [View Diagnostics Report](/dashboard/dashboard-diagnostics-report.md) - - [Use Diagnostics](/dashboard/dashboard-diagnostics-usage.md) - - [Monitoring Page](/dashboard/dashboard-monitoring.md) - - [Search Logs Page](/dashboard/dashboard-log-search.md) - - [Resource Manager Page](/dashboard/dashboard-resource-manager.md) - - Instance Profiling - - [Manual Profiling](/dashboard/dashboard-profiling.md) - - [Continuous Profiling](/dashboard/continuous-profiling.md) - - Session Management and Configuration - - [Share Session](/dashboard/dashboard-session-share.md) - - [Configure SSO](/dashboard/dashboard-session-sso.md) - - [FAQ](/dashboard/dashboard-faq.md) - [Export Grafana Snapshots](/exporting-grafana-snapshots.md) - [TiDB Cluster Alert Rules](/alert-rules.md) - [TiFlash Alert Rules](/tiflash/tiflash-alert-rules.md) @@ -808,7 +777,6 @@ - [`BEGIN`](/sql-statements/sql-statement-begin.md) - [`CALIBRATE RESOURCE`](/sql-statements/sql-statement-calibrate-resource.md) - [`CANCEL IMPORT JOB`](/sql-statements/sql-statement-cancel-import-job.md) - - [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) - [`COMMIT`](/sql-statements/sql-statement-commit.md) - [`CREATE BINDING`](/sql-statements/sql-statement-create-binding.md) - [`CREATE DATABASE`](/sql-statements/sql-statement-create-database.md) @@ -915,7 +883,6 @@ - [`SHOW TABLE REGIONS`](/sql-statements/sql-statement-show-table-regions.md) - [`SHOW TABLE STATUS`](/sql-statements/sql-statement-show-table-status.md) - [`SHOW TABLES`](/sql-statements/sql-statement-show-tables.md) - - [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) - [`SHOW VARIABLES`](/sql-statements/sql-statement-show-variables.md) - [`SHOW WARNINGS`](/sql-statements/sql-statement-show-warnings.md) - [`SHUTDOWN`](/sql-statements/sql-statement-shutdown.md) @@ -923,8 +890,6 @@ - [`START TRANSACTION`](/sql-statements/sql-statement-start-transaction.md) - [`TABLE`](/sql-statements/sql-statement-table.md) - [`TRACE`](/sql-statements/sql-statement-trace.md) - - [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) - - [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) - [`TRUNCATE`](/sql-statements/sql-statement-truncate.md) - [`UNLOCK STATS`](/sql-statements/sql-statement-unlock-stats.md) - [`UPDATE`](/sql-statements/sql-statement-update.md) @@ -1069,12 +1034,43 @@ - [Metadata Lock](/metadata-lock.md) - [TiDB Accelerated Table Creation](/accelerated-table-creation.md) - [Schema Cache](/schema-cache.md) + - UI + - TiDB Dashboard + - [Overview](/dashboard/dashboard-intro.md) + - Maintain + - [Deploy](/dashboard/dashboard-ops-deploy.md) + - [Reverse Proxy](/dashboard/dashboard-ops-reverse-proxy.md) + - [User Management](/dashboard/dashboard-user.md) + - [Secure](/dashboard/dashboard-ops-security.md) + - [Access](/dashboard/dashboard-access.md) + - [Overview Page](/dashboard/dashboard-overview.md) + - [Cluster Info Page](/dashboard/dashboard-cluster-info.md) + - [Top SQL Page](/dashboard/top-sql.md) + - [Key Visualizer Page](/dashboard/dashboard-key-visualizer.md) + - [Metrics Relation Graph](/dashboard/dashboard-metrics-relation.md) + - SQL Statements Analysis + - [SQL Statements Page](/dashboard/dashboard-statement-list.md) + - [SQL Details Page](/dashboard/dashboard-statement-details.md) + - [Slow Queries Page](/dashboard/dashboard-slow-query.md) + - Cluster Diagnostics + - [Access Cluster Diagnostics Page](/dashboard/dashboard-diagnostics-access.md) + - [View Diagnostics Report](/dashboard/dashboard-diagnostics-report.md) + - [Use Diagnostics](/dashboard/dashboard-diagnostics-usage.md) + - [Monitoring Page](/dashboard/dashboard-monitoring.md) + - [Search Logs Page](/dashboard/dashboard-log-search.md) + - [Resource Manager Page](/dashboard/dashboard-resource-manager.md) + - Instance Profiling + - [Manual Profiling](/dashboard/dashboard-profiling.md) + - [Continuous Profiling](/dashboard/continuous-profiling.md) + - Session Management and Configuration + - [Share Session](/dashboard/dashboard-session-share.md) + - [Configure SSO](/dashboard/dashboard-session-sso.md) + - [FAQ](/dashboard/dashboard-faq.md) - [Telemetry](/telemetry.md) - [Error Codes](/error-codes.md) - [Table Filter](/table-filter.md) - [Schedule Replicas by Topology Labels](/schedule-replicas-by-topology-labels.md) - [URI Formats of External Storage Services](/external-storage-uri.md) - - [TiDB Workload Repository](/workload-repository.md) - FAQs - [FAQ Summary](/faq/faq-overview.md) - [TiDB FAQs](/faq/tidb-faq.md) diff --git a/_index.md b/_index.md index 3b27a7d54a932..cdea814494b77 100644 --- a/_index.md +++ b/_index.md @@ -82,7 +82,7 @@ summary: TiDB is an open-source distributed SQL database that supports Hybrid Tr -[Use Prometheus, Grafana, and TiDB Dashboard](https://docs.pingcap.com/tidb/dev/tidb-monitoring-framework) +[Use Prometheus and Grafana](https://docs.pingcap.com/tidb/dev/tidb-monitoring-framework) [Monitoring API](https://docs.pingcap.com/tidb/dev/tidb-monitoring-api) diff --git a/basic-features.md b/basic-features.md index a32b3d0e3379a..dfb8e228332ae 100644 --- a/basic-features.md +++ b/basic-features.md @@ -28,7 +28,7 @@ You can try out TiDB features on [TiDB Playground](https://play.tidbcloud.com/?u | [Date and time types](/data-type-date-and-time.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [String types](/data-type-string.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [JSON type](/data-type-json.md) | Y | Y | Y | Y | Y | E | E | E | E | E | -| [Vector types](/vector-search/vector-search-data-types.md) | E | N | N | N | N | N | N | N | N | N | +| [Vectort types](/vector-search/vector-search-data-types.md) | E | N | N | N | N | N | N | N | N | N | | [Control flow functions](/functions-and-operators/control-flow-functions.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [String functions](/functions-and-operators/string-functions.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [Numeric functions and operators](/functions-and-operators/numeric-functions-and-operators.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | diff --git a/benchmark/benchmark-tidb-using-tpcc.md b/benchmark/benchmark-tidb-using-tpcc.md index 22a77bc9899cb..72a3c270f1d1c 100644 --- a/benchmark/benchmark-tidb-using-tpcc.md +++ b/benchmark/benchmark-tidb-using-tpcc.md @@ -24,7 +24,7 @@ Before testing, TPC-C Benchmark specifies the initial state of the database, whi * The `DISTRICT` table has W \* 10 records (Each warehouse provides services to 10 districts) * The `CUSTOMER` table has W \* 10 \* 3,000 records (Each district has 3,000 customers) * The `HISTORY` table has W \* 10 \* 3,000 records (Each customer has one transaction history) -* The `ORDER` table has W \* 10 \* 3,000 records (Each district has 3,000 orders and the last 900 orders generated are added to the `NEW-ORDER` table. Each order randomly generates 5 ~ 15 ORDER-LINE records.) +* The `ORDER` table has W \* 10 \* 3,000 records (Each district has 3,000 orders and the last 900 orders generated are added to the `NEW-ORDER` table. Each order randomly generates 5 ~ 15 ORDER-LINE records. In this document, the testing uses 1,000 warehouses as an example to test TiDB. diff --git a/best-practices/java-app-best-practices.md b/best-practices/java-app-best-practices.md index c864ecd120ffd..abfa24b600a1f 100644 --- a/best-practices/java-app-best-practices.md +++ b/best-practices/java-app-best-practices.md @@ -204,62 +204,26 @@ Through monitoring, you might notice that although the application only performs After it is configured, you can check the monitoring to see a decreased number of `SELECT` statements. -> **Note:** -> -> Enabling `useConfigs=maxPerformance` requires MySQL Connector/J version 8.0.33 or later. For more details, see [MySQL JDBC Bug](/develop/dev-guide-third-party-tools-compatibility.md#mysql-jdbc-bugs). - #### Timeout-related parameters TiDB provides two MySQL-compatible parameters that controls the timeout: `wait_timeout` and `max_execution_time`. These two parameters respectively control the connection idle timeout with the Java application and the timeout of the SQL execution in the connection; that is to say, these parameters control the longest idle time and the longest busy time for the connection between TiDB and the Java application. The default value of both parameters is `0`, which by default allows the connection to be infinitely idle and infinitely busy (an infinite duration for one SQL statement to execute). However, in an actual production environment, idle connections and SQL statements with excessively long execution time negatively affect databases and applications. To avoid idle connections and SQL statements that are executed for too long, you can configure these two parameters in your application's connection string. For example, set `sessionVariables=wait_timeout=3600` (1 hour) and `sessionVariables=max_execution_time=300000` (5 minutes). -#### Typical JDBC connection string parameters - -Combining the preceding parameter values, the JDBC connection string configuration is as follows: - -``` -jdbc:mysql://:/?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true -``` - -> **Note:** -> -> If you are connecting over a public network, you need to set `useSSL=true` and [enable TLS between TiDB clients and servers](/enable-tls-between-clients-and-servers.md). - ## Connection pool Building TiDB (MySQL) connections is relatively expensive (for OLTP scenarios at least), because in addition to building a TCP connection, connection authentication is also required. Therefore, the client usually saves the TiDB (MySQL) connections to the connection pool for reuse. -TiDB supports the following Java connection pools: - -- [HikariCP](https://github.com/brettwooldridge/HikariCP) -- [tomcat-jdbc](https://tomcat.apache.org/tomcat-10.1-doc/jdbc-pool) -- [druid](https://github.com/alibaba/druid) -- [c3p0](https://www.mchange.com/projects/c3p0/) -- [dbcp](https://commons.apache.org/proper/commons-dbcp/) +Java has many connection pool implementations such as [HikariCP](https://github.com/brettwooldridge/HikariCP), [tomcat-jdbc](https://tomcat.apache.org/tomcat-10.1-doc/jdbc-pool.html), [druid](https://github.com/alibaba/druid), [c3p0](https://www.mchange.com/projects/c3p0/), and [dbcp](https://commons.apache.org/proper/commons-dbcp/). TiDB does not limit which connection pool you use, so you can choose whichever you like for your application. -In practice, some connection pools might persistently use specific active sessions. Although the total number of connections appears evenly distributed across TiDB compute nodes, uneven distribution of active connections can lead to actual load imbalance. In distributed scenarios, it is recommended to use HikariCP, which manages connection lifecycles effectively and helps prevent active connections from being fixed on certain nodes, achieving balanced load distribution. +### Configure the number of connections -### Typical connection pool configuration - -The following is an example configuration for HikariCP: - -```yaml -hikari: - maximumPoolSize: 20 - poolName: hikariCP - connectionTimeout: 30000 - maxLifetime: 1200000 - keepaliveTime: 120000 -``` +It is a common practice that the connection pool size is well adjusted according to the application's own needs. Take HikariCP as an example: -The parameter explanations are as follows. For more details, refer to the [official HikariCP documentation](https://github.com/brettwooldridge/HikariCP/blob/dev/README.md). +- `maximumPoolSize`: The maximum number of connections in the connection pool. If this value is too large, TiDB consumes resources to maintain useless connections. If this value is too small, the application gets slow connections. So configure this value for your own good. For details, see [About Pool Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing). +- `minimumIdle`: The minimum number of idle connections in the connection pool. It is mainly used to reserve some connections to respond to sudden requests when the application is idle. You can also configure it according to your application needs. -- `maximumPoolSize`: the maximum number of connections in the pool. The default value is `10`. In containerized environments, it is recommended to set this to 4–10 times the number of CPU cores available to the Java application. Setting this value too high can lead to resource wastage, while setting it too low can slow down connection acquisition. See [About Pool Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing) for more details. -- `minimumIdle`: HikariCP recommends not setting this parameter. The default value is equal to the value of `maximumPoolSize`, which disables connection pool scaling. This ensures that connections are readily available during traffic spikes and avoids delays caused by connection creation. -- `connectionTimeout`: the maximum time (in milliseconds) that an application waits to acquire a connection from the pool. The default value is `30000` milliseconds (30 seconds). If no available connection is obtained within this time, a `SQLException` exception occurs. -- `maxLifetime`: the maximum lifetime (in milliseconds) of a connection in the pool. The default value is `1800000` milliseconds (30 minutes). Connections in use are not affected. After the connection is closed, it will be removed according to this setting. Setting this value too low can cause frequent reconnections. If you are using [`graceful-wait-before-shutdown`](/tidb-configuration-file.md#graceful-wait-before-shutdown-new-in-v50), ensure this value is less than the wait time. -- `keepaliveTime`: the interval (in milliseconds) between keepalive operations on connections in the pool. This setting helps prevent disconnections caused by database or network idle timeouts. The default value is `120000` milliseconds (2 minutes). The pool prefers using the JDBC4 `isValid()` method to keep idle connections alive. +The application needs to return the connection after finishing using it. It is also recommended that the application use the corresponding connection pool monitoring (such as `metricRegistry`) to locate the connection pool issue in time. ### Probe configuration diff --git a/best-practices/three-nodes-hybrid-deployment.md b/best-practices/three-nodes-hybrid-deployment.md index cbd698c50de28..9c6cb82d7bcb8 100644 --- a/best-practices/three-nodes-hybrid-deployment.md +++ b/best-practices/three-nodes-hybrid-deployment.md @@ -69,7 +69,7 @@ In this test, the value of this parameter is set to `2`. Observe the **gRPC poll #### `storage.scheduler-worker-pool-size` -When TiKV detects that the CPU core number of the machine is greater than or equal to `16`, this parameter value defaults to `8`. When the CPU core number is smaller than `16`, the parameter value defaults to `4`. This parameter is used when TiKV converts complex transaction requests to simple key-value reads or writes, but the scheduler thread pool does not perform any writes. +When TiKV detects that the CPU core number of the machine is greater than or equal to `16`, this parameter value defaults to `8`. When the CPU core number is smaller than `16`, the parameter value defaults to `4`. This parameter is used when TiKV converts complex transaction requests to simple key-value reads or writes, but the scheduler thread pool does not performs any writes. Ideally, the usage rate of the scheduler thread pool is kept between 50% and 75%. Similar to the gRPC thread pool, the `storage.scheduler-worker-pool-size` parameter defaults to a larger value during the hybrid deployment, which makes resource usage insufficient. In this test, the value of this parameter is set to `2`, which is in line with the best practices, a conclusion drawn by observing the corresponding metrics in the **Scheduler worker CPU** panel. diff --git a/br/backup-and-restore-storages.md b/br/backup-and-restore-storages.md index 767dd887c6836..9c6aa083d8bbe 100644 --- a/br/backup-and-restore-storages.md +++ b/br/backup-and-restore-storages.md @@ -10,9 +10,9 @@ TiDB supports storing backup data to Amazon S3, Google Cloud Storage (GCS), Azur ## Send credentials to TiKV -| CLI parameter | Description | Default value | -|:-----------------------------|:-------------------------------------------------------------|:--------------| -| `--send-credentials-to-tikv` | Controls whether to send credentials obtained by BR to TiKV. | `true` | +| CLI parameter | Description | Default value +|:----------|:-------|:-------| +| `--send-credentials-to-tikv` | Controls whether to send credentials obtained by BR to TiKV. | `true`| By default, BR sends a credential to each TiKV node when using Amazon S3, GCS, or Azure Blob Storage as the storage system. This behavior simplifies the configuration and is controlled by the parameter `--send-credentials-to-tikv`(or `-c` in short). diff --git a/br/br-checkpoint-restore.md b/br/br-checkpoint-restore.md index 8a734e98c46c7..b94ecc47361a4 100644 --- a/br/br-checkpoint-restore.md +++ b/br/br-checkpoint-restore.md @@ -15,7 +15,7 @@ If your TiDB cluster is large and cannot afford to restore again after a failure ## Implementation principles -The implementation of checkpoint restore is divided into two parts: snapshot restore and log restore. For more information, see [Implementation details: store checkpoint data in the downstream cluster](#implementation-details-store-checkpoint-data-in-the-downstream-cluster) and [Implementation details: store checkpoint data in the external storage](#implementation-details-store-checkpoint-data-in-the-external-storage). +The implementation of checkpoint restore is divided into two parts: snapshot restore and log restore. For more information, see [Implementation details](#implementation-details). ### Snapshot restore @@ -65,11 +65,7 @@ After a restore failure, avoid writing, deleting, or creating tables in the clus Cross-major-version checkpoint recovery is not recommended. For clusters where `br` recovery fails using the Long-Term Support (LTS) versions prior to v8.5.0, recovery cannot be continued with v8.5.0 or later LTS versions, and vice versa. -## Implementation details: store checkpoint data in the downstream cluster - -> **Note:** -> -> Starting from v9.0.0, BR stores checkpoint data in the downstream cluster by default. You can specify an external storage for checkpoint data using the `--checkpoint-storage` parameter. +## Implementation details Checkpoint restore operations are divided into two parts: snapshot restore and PITR restore. @@ -85,70 +81,8 @@ If the restore fails and you try to restore backup data with different checkpoin [PITR (Point-in-time recovery)](/br/br-pitr-guide.md) consists of snapshot restore and log restore phases. -During the initial restore, `br` first enters the snapshot restore phase. BR records the checkpoint data, the upstream cluster ID, BackupTS of the backup data (that is, the start time point `start-ts` of log restore) and the restored time point `restored-ts` of log restore in the `__TiDB_BR_Temporary_Snapshot_Restore_Checkpoint` database. If restore fails during this phase, you cannot adjust the `start-ts` and `restored-ts` of log restore when resuming checkpoint restore. +During the initial restore, `br` first enters the snapshot restore phase. This phase follows the same process as the preceding [snapshot restore](#snapshot-restore-1): BR records the checkpoint data, the upstream cluster ID, and BackupTS of the backup data (that is, the start time point `start-ts` of log restore) in the `__TiDB_BR_Temporary_Snapshot_Restore_Checkpoint` database. If restore fails during this phase, you cannot adjust the `start-ts` of log restore when resuming checkpoint restore. When entering the log restore phase during the initial restore, `br` creates a `__TiDB_BR_Temporary_Log_Restore_Checkpoint` database in the target cluster. This database records checkpoint data, the upstream cluster ID, and the restore time range (`start-ts` and `restored-ts`). If restore fails during this phase, you need to specify the same `start-ts` and `restored-ts` as recorded in the checkpoint database when retrying. Otherwise, `br` will report an error and prompt that the current specified restore time range or upstream cluster ID is different from the checkpoint record. If the restore cluster has been cleaned, you can manually delete the `__TiDB_BR_Temporary_Log_Restore_Checkpoint` database and retry with a different backup. Before entering the log restore phase during the initial restore, `br` constructs a mapping of upstream and downstream cluster database and table IDs at the `restored-ts` time point. This mapping is persisted in the system table `mysql.tidb_pitr_id_map` to prevent duplicate allocation of database and table IDs. Deleting data from `mysql.tidb_pitr_id_map` might lead to inconsistent PITR restore data. - -## Implementation details: store checkpoint data in the external storage - -> **Note:** -> -> Starting from v9.0.0, BR stores checkpoint data in the downstream cluster by default. You can specify an external storage for checkpoint data using the `--checkpoint-storage` parameter. For example: -> -> ```shell -> ./br restore full -s "s3://backup-bucket/backup-prefix" --checkpoint-storage "s3://temp-bucket/checkpoints" -> ``` - -In the external storage, the directory structure of the checkpoint data is as follows: - -- Root path `restore-{downstream-cluster-ID}` uses the downstream cluster ID `{downstream-cluster-ID}` to distinguish between different restore clusters. -- Path `restore-{downstream-cluster-ID}/log` stores log file checkpoint data during the log restore phase. -- Path `restore-{downstream-cluster-ID}/sst` stores checkpoint data of the SST files that are not backed up by log backup during the log restore phase. -- Path `restore-{downstream-cluster-ID}/snapshot` stores checkpoint data during the snapshot restore phase. - -``` -. -`-- restore-{downstream-cluster-ID} - |-- log - | |-- checkpoint.meta - | |-- data - | | |-- {uuid}.cpt - | | |-- {uuid}.cpt - | | `-- {uuid}.cpt - | |-- ingest_index.meta - | `-- progress.meta - |-- snapshot - | |-- checkpoint.meta - | |-- checksum - | | |-- {uuid}.cpt - | | |-- {uuid}.cpt - | | `-- {uuid}.cpt - | `-- data - | |-- {uuid}.cpt - | |-- {uuid}.cpt - | `-- {uuid}.cpt - `-- sst - `-- checkpoint.meta -``` - -Checkpoint restore operations are divided into two parts: snapshot restore and PITR restore. - -### Snapshot restore - -During the initial restore, `br` creates a `restore-{downstream-cluster-ID}/snapshot` path in the target cluster. The path records checkpoint data, the upstream cluster ID, and the BackupTS of the backup data. - -If the restore fails, you can retry it using the same command. `br` will automatically read the checkpoint information from the specified external storage path and resume from the last restore point. - -If the restore fails and you try to restore backup data with different checkpoint information to the same cluster, `br` reports an error. It indicates that the current upstream cluster ID or BackupTS is different from the checkpoint record. If the restore cluster has been cleaned, you can manually clean up the checkpoint data in the external storage or specify another external storage path to store checkpoint data, and retry with a different backup. - -### PITR restore - -[PITR (Point-in-time recovery)](/br/br-pitr-guide.md) consists of snapshot restore and log restore phases. - -During the initial restore, `br` first enters the snapshot restore phase. BR records the checkpoint data, the upstream cluster ID, BackupTS of the backup data (that is, the start time point `start-ts` of log restore) and the restored time point `restored-ts` of log restore in the `restore-{downstream-cluster-ID}/snapshot` path. If restore fails during this phase, you cannot adjust the `start-ts` and `restored-ts` of log restore when resuming checkpoint restore. - -When entering the log restore phase during the initial restore, `br` creates a `restore-{downstream-cluster-ID}/log` path in the target cluster. This path records checkpoint data, the upstream cluster ID, and the restore time range (`start-ts` and `restored-ts`). If restore fails during this phase, you need to specify the same `start-ts` and `restored-ts` as recorded in the checkpoint database when retrying. Otherwise, `br` will report an error and prompt that the current specified restore time range or upstream cluster ID is different from the checkpoint record. If the restore cluster has been cleaned, you can manually clean up the checkpoint data in the external storage or specify another external storage path to store checkpoint data, and retry with a different backup. - -Before entering the log restore phase during the initial restore, `br` constructs a mapping of the database and table IDs in the upstream and downstream clusters at the `restored-ts` time point. This mapping is persisted in the system table `mysql.tidb_pitr_id_map` to prevent duplicate allocation of database and table IDs. Deleting data from `mysql.tidb_pitr_id_map` might lead to inconsistent PITR restore data. diff --git a/br/br-pitr-manual.md b/br/br-pitr-manual.md index b3f007c8976a1..e36d345c3384e 100644 --- a/br/br-pitr-manual.md +++ b/br/br-pitr-manual.md @@ -495,25 +495,3 @@ tiup br restore point --pd="${PD_IP}:2379" --master-key-crypter-method aes128-ctr --master-key "local:///path/to/master.key" ``` - -### Compatibility between ongoing log backup and snapshot restore - -Starting from v9.0.0, when a log backup task is running, if all of the following conditions are met, you can still perform snapshot restore (`br restore [full|database|table]`) and allow the restored data to be properly recorded by the ongoing log backup (hereinafter referred to as "log backup"): - -- The node performing backup and restore operations has the following necessary permissions: - - Read access to the external storage containing the backup source, for snapshot restore - - Write access to the target external storage used by the log backup -- The target external storage for the log backup is Amazon S3 (`s3://`), Google Cloud Storage (`gcs://`), or Azure Blob Storage (`azblob://`). -- The data to be restored uses the same type of external storage as the target storage for the log backup. -- Neither the data to be restored nor the log backup has enabled local encryption. For details, see [log backup encryption](#encrypt-the-log-backup-data) and [snapshot backup encryption](/br/br-snapshot-manual.md#encrypt-the-backup-data). - -If any of the above conditions are not met, or if you need to perform a point-in-time recovery, while a log backup task is running, BR refuses to proceed with the data recovery. In this case, you can complete the recovery by following these steps: - -1. [Stop the log backup task](#stop-a-log-backup-task). -2. Perform the data restore. -3. After the restore is complete, perform a new snapshot backup. -4. [Restart the log backup task](#restart-a-log-backup-task). - -> **Note:** -> -> When restoring a log backup that contains records of snapshot (full) restore data, you must use BR v9.0.0 or later. Otherwise, restoring the recorded full restore data might fail. \ No newline at end of file diff --git a/cached-tables.md b/cached-tables.md index 67a5ce8671b40..f0609a3b92931 100644 --- a/cached-tables.md +++ b/cached-tables.md @@ -15,7 +15,7 @@ The cached table feature is suitable for tables with the following characteristi - The data volume of the table is small, for example, less than 4 MiB. - The table is read-only or rarely updated, for example, with a write QPS (queries per second) of less than 10 times per minute. -- The table is frequently accessed, and you expect a better read performance, for example, when encountering hotspots on small tables during direct reads from TiKV. +- The table is frequently accessed, and you expect a better read performance, for example, when encountering hotspots on small tables during direct reads from from TiKV. When the data volume of the table is small but the data is frequently accessed, the data is concentrated on a Region in TiKV and makes it a hotspot Region, which affects the performance. Therefore, the typical usage scenarios of cached tables are as follows: diff --git a/dashboard/dashboard-access.md b/dashboard/dashboard-access.md index 35f6e74038eab..7169be86f219e 100644 --- a/dashboard/dashboard-access.md +++ b/dashboard/dashboard-access.md @@ -14,7 +14,7 @@ To access TiDB Dashboard, visit via your brows ## Access TiDB Dashboard when multiple PD instances are deployed -When multiple PD instances are deployed in your cluster and you can directly access **every** PD instance and port, you can simply replace `127.0.0.1:2379` in the address with **any** PD instance address and port. +When multiple multiple PD instances are deployed in your cluster and you can directly access **every** PD instance and port, you can simply replace `127.0.0.1:2379` in the address with **any** PD instance address and port. > **Note:** > diff --git a/dashboard/dashboard-diagnostics-report.md b/dashboard/dashboard-diagnostics-report.md index 85232f994ba58..defe049f2682c 100644 --- a/dashboard/dashboard-diagnostics-report.md +++ b/dashboard/dashboard-diagnostics-report.md @@ -33,7 +33,7 @@ In this report, some small buttons are described as follows: All monitoring metrics basically correspond to those on the TiDB Grafana monitoring dashboard. After a module is found to be abnormal, you can view more monitoring information on the TiDB Grafana. -In addition, the `TOTAL_TIME` and `TOTAL_COUNT` metrics in this report are monitoring data read from Prometheus, so calculation inaccuracy might exist in their statistics. +In addition, the `TOTAL_TIME` and `TOTAL_COUNT` metrics in this report are monitoring data read from Prometheus, so calculation inaccuracy might exits in their statistics. Each part of this report is introduced as follows. diff --git a/dashboard/dashboard-faq.md b/dashboard/dashboard-faq.md index ab0f5d7b25b93..361451200ac17 100644 --- a/dashboard/dashboard-faq.md +++ b/dashboard/dashboard-faq.md @@ -30,7 +30,7 @@ If you have deployed TiDB using the `tiup cluster` or `tiup playground` command, The **QPS** and **Latency** sections on the **Overview** page require a cluster with Prometheus deployed. Otherwise, the error is shown. You can solve this problem by deploying a Prometheus instance in the cluster. -If you still encounter this problem when the Prometheus instance has been deployed, the possible reason is that your deployment tool is out of date (TiUP or TiDB Operator), and your tool does not automatically report metrics addresses, which makes TiDB Dashboard unable to query metrics. You can upgrade your deployment tool to the latest version and try again. +If you still encounter this problem when the Prometheus instance has been deployed, the possible reason is that your deployment tool is out of date (TiUP or TiDB Operator), and your tool does not automatically report metrics addresses, which makes TiDB Dashboard unable to query metrics. You can upgrade you deployment tool to the latest version and try again. If your deployment tool is TiUP, take the following steps to solve this problem. For other deployment tools, refer to the corresponding documents of those tools. diff --git a/ddl-introduction.md b/ddl-introduction.md index 07710780c7bf1..83ba6d7fffe71 100644 --- a/ddl-introduction.md +++ b/ddl-introduction.md @@ -86,7 +86,7 @@ To improve the user experience of DDL execution, starting from v6.2.0, TiDB enab + DDL statements to be performed on the same table are mutually blocked. + `DROP DATABASE` and DDL statements that affect all objects in the database are mutually blocked. + Adding indexes and column type changes on different tables can be executed concurrently. -+ Starting from v8.2.0, [logical DDL statements](/ddl-introduction.md#types-of-ddl-statements) for different tables can be executed in parallel. ++ A logical DDL statement must wait for the previous logical DDL statement to be executed before it can be executed. + In other cases, DDL can be executed based on the level of availability for concurrent DDL execution. Specifically, TiDB 6.2.0 has enhanced the DDL execution framework in the following aspects: diff --git a/deploy-monitoring-services.md b/deploy-monitoring-services.md index b124889bb8cd7..188027ff3457d 100644 --- a/deploy-monitoring-services.md +++ b/deploy-monitoring-services.md @@ -6,7 +6,9 @@ aliases: ['/docs/dev/deploy-monitoring-services/','/docs/dev/how-to/monitor/moni # Deploy Monitoring Services for the TiDB Cluster -This document is intended for users who want to manually deploy TiDB monitoring and alert services. If you deploy the TiDB cluster using TiUP, the monitoring and alert services are automatically deployed, and no manual deployment is needed. [TiDB Dashboard](/dashboard/dashboard-intro.md) is built into the PD component and does not require an independent deployment. +This document is intended for users who want to manually deploy TiDB monitoring and alert services. + +If you deploy the TiDB cluster using TiUP, the monitoring and alert services are automatically deployed, and no manual deployment is needed. ## Deploy Prometheus and Grafana diff --git a/develop/dev-guide-build-cluster-in-cloud.md b/develop/dev-guide-build-cluster-in-cloud.md index f6cfcb08303bb..249c57f3307bc 100644 --- a/develop/dev-guide-build-cluster-in-cloud.md +++ b/develop/dev-guide-build-cluster-in-cloud.md @@ -176,7 +176,7 @@ Expected output: +-------------------+ ``` -If your actual output is similar to the expected output, congratulations, you have successfully executed a SQL statement on TiDB Cloud. +If your actual output is similar to the expected output, congratulations, you have successfully execute a SQL statement on TiDB Cloud. ## Need help? diff --git a/develop/dev-guide-create-table.md b/develop/dev-guide-create-table.md index 8d8722cbba835..be32bfb337687 100644 --- a/develop/dev-guide-create-table.md +++ b/develop/dev-guide-create-table.md @@ -5,7 +5,7 @@ summary: Learn the definitions, rules, and guidelines in table creation. # Create a Table -This document introduces how to create tables using the SQL statement and the related best practices. An example of the TiDB-based [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application is provided to illustrate the best practices. +This document introduces how to create tables using the SQL statement and the related best practices. An example of the TiDB-based [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application) is provided to illustrate the best practices. ## Before you start diff --git a/develop/dev-guide-gui-datagrip.md b/develop/dev-guide-gui-datagrip.md index f3089d4e05921..99a8bf7b7d827 100644 --- a/develop/dev-guide-gui-datagrip.md +++ b/develop/dev-guide-gui-datagrip.md @@ -82,7 +82,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you've sele 8. Click **Test Connection** to validate the connection to the TiDB Cloud Serverless cluster. - ![Test the connection to a TiDB Cloud Serverless cluster](/media/develop/datagrip-test-connection.jpg) + ![Test the connection to a TiDB Cloud Serverless clustser](/media/develop/datagrip-test-connection.jpg) 9. Click **OK** to save the connection configuration. diff --git a/develop/dev-guide-gui-navicat.md b/develop/dev-guide-gui-navicat.md index a6f0e2295ef8b..1bd675599a5c2 100644 --- a/develop/dev-guide-gui-navicat.md +++ b/develop/dev-guide-gui-navicat.md @@ -62,7 +62,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se > > If you have created a password before, you can either use the original password or click **Reset Password** to generate a new one. -5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. +5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) @@ -99,7 +99,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se 4. Click **CA cert** to download the CA certificate. -5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. +5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) @@ -124,7 +124,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se
-1. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. +1. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) diff --git a/develop/dev-guide-index-best-practice.md b/develop/dev-guide-index-best-practice.md index efb3db870c936..a088c91fc5d0f 100644 --- a/develop/dev-guide-index-best-practice.md +++ b/develop/dev-guide-index-best-practice.md @@ -32,7 +32,7 @@ CREATE TABLE `books` ( - Create an appropriate index based on your application. In principle, create indexes only on the columns to be used in queries to improve performance. The following cases are suitable for creating an index: - Columns with a high distinction degree can significantly reduce the number of filtered rows. For example, it is recommended to create an index on the personal ID number, but not on the gender. - - Use combined indexes when querying with multiple conditions. Note that columns with equivalent conditions need to be placed in the front of the combined index. Here is an example: if the `select* from t where c1 = 10 and c2 = 100 and c3 > 10` query is frequently used, consider creating a combined index `Index cidx (c1, c2, c3)`, so that an index prefix can be constructed to scan by query conditions. + - Use combined indexes when querying with multiple conditions. Note that columns with equivalent conditions need to be placed in the front of the combined index. Here is an example: if the `select* from t where c1 = 10 and c2 = 100 and c3 > 10` query is frequently used, consider creating a combined index `Index cidx (c1, c2, c3)`, so that a index prefix can be constructed to scan by query conditions. - Name your secondary index meaningfully, and it is recommended to follow the table naming conventions of your company or organization. If such naming conventions do not exist, follow the rules in [Index Naming Specification](/develop/dev-guide-object-naming-guidelines.md). diff --git a/develop/dev-guide-sql-development-specification.md b/develop/dev-guide-sql-development-specification.md index c19f431c97150..729f3d955feb5 100644 --- a/develop/dev-guide-sql-development-specification.md +++ b/develop/dev-guide-sql-development-specification.md @@ -48,7 +48,7 @@ This document introduces some general development specifications for using SQL. - Replace `OR` with `IN` or `UNION`. The number of `IN` must be less than `300`. - Avoid using the `%` prefix for fuzzy prefix queries. - If the application uses **Multi Statements** to execute SQL, that is, multiple SQLs are joined with semicolons and sent to the client for execution at once, TiDB only returns the result of the first SQL execution. -- When you use expressions, check if the expressions support computing push-down to the storage layer (TiKV or TiFlash). If not, you should expect more memory consumption and even OOM at the TiDB layer. Computing that can be pushed down to the storage layer is as follows: +- When you use expressions, check if the expressions support computing push-down to the storage layer (TiKV or TiFlash). If not, you should expect more memory consumption and even OOM at the TiDB layer. Computing that can be pushe down the storage layer is as follows: - [TiFlash supported push-down calculations](/tiflash/tiflash-supported-pushdown-calculations.md). - [TiKV - List of Expressions for Pushdown](/functions-and-operators/expressions-pushed-down.md). - [Predicate push down](/predicate-push-down.md). diff --git a/develop/dev-guide-use-subqueries.md b/develop/dev-guide-use-subqueries.md index 9e6fe2c86b23d..ae7dde78d44f0 100644 --- a/develop/dev-guide-use-subqueries.md +++ b/develop/dev-guide-use-subqueries.md @@ -9,7 +9,7 @@ This document introduces subquery statements and categories in TiDB. ## Overview -A subquery is a query within another SQL query. With subquery, the query result can be used in another query. +An subquery is a query within another SQL query. With subquery, the query result can be used in another query. The following takes the [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application as an example to introduce subquery. diff --git a/dm/dm-continuous-data-validation.md b/dm/dm-continuous-data-validation.md index d42748d50ecd4..1507761b1e76f 100644 --- a/dm/dm-continuous-data-validation.md +++ b/dm/dm-continuous-data-validation.md @@ -282,7 +282,7 @@ The lifecycle of continuous data validation is as follows: The detailed implementation of continuous data validation is as follows: 1. The validator pulls a binlog event from the upstream and gets the changed rows: - - The validator only checks an event that has been incrementally migrated by the syncer. If the event has not been processed by the syncer, the validator pauses and waits for the syncer to complete processing. + - The validator only checks a event that has been incrementally migrated by the syncer. If the event has not been processed by the syncer, the validator pauses and waits for the syncer to complete processing. - If the event has been processed by the syncer, the validator moves on to the following steps. 2. The validator parses the binlog event and filters out the rows based on the block and allow lists, the table filters, and table routing. After that, the validator submits the changed rows to the validation worker that runs in the background. 3. The validation worker merges the changed rows that affect the same table and the same primary key to avoid validating "expired" data. The changed rows are cached in memory. diff --git a/dm/dm-webui-guide.md b/dm/dm-webui-guide.md index fcf02fd95b3a4..847d7dd40fbd8 100644 --- a/dm/dm-webui-guide.md +++ b/dm/dm-webui-guide.md @@ -39,7 +39,7 @@ When [OpenAPI](/dm/dm-open-api.md#maintain-dm-clusters-using-openapi) is enabled Before creating a migration task, you need to create the data source information of the upstream for the replication task. You can create the upstream configuration in the **Source** page. When creating sources, pay attention to the following items: -- If there is an auto failover between primary and secondary instance, enable GTID in the upstream MySQL and set GTID to `True` when creating the upstream configuration; otherwise, the migration task will be interrupted during the failover (except for AWS Aurora). +- If there is a auto failover between primary and secondary instance, enable GTID in the upstream MySQL and set GTID to `True` when creating the upstream configuration; otherwise, the migration task will be interrupted during the failover (except for AWS Aurora). - If a MySQL instance needs to be temporarily offline, you can disable the instance. However, when the MySQL instance is being disabled, other MySQL instances running migration tasks should not execute DDL operations; otherwise, the disabled instance cannot properly migrate data after it is enabled. - When multiple migration tasks use the same upstream, it might cause additional stress. Enabling relay log can reduce the impact on the upstream, so it is recommended to enable relay log. diff --git a/dm/maintain-dm-using-tiup.md b/dm/maintain-dm-using-tiup.md index 0e8ff6302c583..0fcc68b1bb1f3 100644 --- a/dm/maintain-dm-using-tiup.md +++ b/dm/maintain-dm-using-tiup.md @@ -389,7 +389,7 @@ tiup dmctl --master-addr master1:8261 operate-source create /tmp/source1.yml All operations above performed on the cluster machine use the SSH client embedded in TiUP to connect to the cluster and execute commands. However, in some scenarios, you might also need to use the SSH client native to the control machine system to perform such cluster operations. For example: -- To use an SSH plug-in for authentication +- To use a SSH plug-in for authentication - To use a customized SSH client Then you can use the `--native-ssh` command-line flag to enable the system-native command-line tool: diff --git a/ecosystem-tool-user-guide.md b/ecosystem-tool-user-guide.md index f1a9f1fbc9b81..3eb8661818bdd 100644 --- a/ecosystem-tool-user-guide.md +++ b/ecosystem-tool-user-guide.md @@ -75,7 +75,7 @@ The following are the basics of Dumpling: > **Note:** > -> PingCAP previously maintained a fork of the [mydumper project](https://github.com/maxbube/mydumper) with enhancements specific to TiDB. Starting from v7.5.0, [Mydumper](https://docs-archive.pingcap.com/tidb/v4.0/mydumper-overview/) is deprecated and most of its features have been replaced by [Dumpling](/dumpling-overview.md). It is strongly recommended that you use Dumpling instead of mydumper. +> PingCAP previously maintained a fork of the [mydumper project](https://github.com/maxbube/mydumper) with enhancements specific to TiDB. Starting from v7.5.0, [Mydumper](https://docs.pingcap.com/tidb/v4.0/mydumper-overview) is deprecated and most of its features have been replaced by [Dumpling](/dumpling-overview.md). It is strongly recommended that you use Dumpling instead of mydumper. ### Full data import - TiDB Lightning @@ -135,4 +135,4 @@ The following are the basics of sync-diff-inspector: ## OLAP Query tool - TiSpark -[TiSpark](/tispark-overview.md) is a product developed by PingCAP to address the complexity of OLAP queries. It combines strengths of Spark, and the features of distributed TiKV clusters and TiDB to provide a one-stop Hybrid Transactional and Analytical Processing (HTAP) solution. +[TiSpark](/tispark-overview.md) is a product developed by PingCAP to address the complexiy of OLAP queries. It combines strengths of Spark, and the features of distributed TiKV clusters and TiDB to provide a one-stop Hybrid Transactional and Analytical Processing (HTAP) solution. diff --git a/enable-tls-between-components.md b/enable-tls-between-components.md index 9e604a6e2b218..d7b87cf4d7981 100644 --- a/enable-tls-between-components.md +++ b/enable-tls-between-components.md @@ -128,23 +128,11 @@ Currently, it is not supported to only enable encrypted transmission of some spe cdc server --pd=https://127.0.0.1:2379 --log-file=ticdc.log --addr=0.0.0.0:8301 --advertise-addr=127.0.0.1:8301 --ca=/path/to/ca.pem --cert=/path/to/ticdc-cert.pem --key=/path/to/ticdc-key.pem ``` - - TiProxy - - Configure in the configuration file, and set the corresponding URL to `https`: - - ```toml - [security] - [server-http-tls] - ca = "/path/to/ca.pem" - cert = "/path/to/tiproxy-server.pem" - key = "/path/to/tiproxy-server-key.pem" - ``` - Now, encrypted transmission among TiDB components is enabled. > **Note:** > - > After enabling encrypted transmission in a TiDB cluster, if you need to connect to the cluster using tidb-ctl, tikv-ctl, pd-ctl, or tiproxyctl, specify the client certificate. For example: + > After enabling encrypted transmission in a TiDB cluster, if you need to connect to the cluster using tidb-ctl, tikv-ctl, or pd-ctl, specify the client certificate. For example: {{< copyable "shell-regular" >}} @@ -181,7 +169,7 @@ To verify the caller's identity for a component, you need to mark the certificat ```toml [security] - cluster-verify-cn = ["tidb", "tiproxy", "test-client", "prometheus"] + cluster-verify-cn = ["tidb", "test-client", "prometheus"] ``` - TiKV @@ -199,7 +187,7 @@ To verify the caller's identity for a component, you need to mark the certificat ```toml [security] - cert-allowed-cn = ["tidb", "pd", "tikv", "tiflash", "tiproxy", "test-client", "prometheus"] + cert-allowed-cn = ["tidb", "pd", "tikv", "tiflash", "test-client", "prometheus"] ``` - TiFlash (New in v4.0.5) @@ -218,21 +206,11 @@ To verify the caller's identity for a component, you need to mark the certificat cert-allowed-cn = ["tidb", "tikv", "tiflash", "prometheus"] ``` -- TiProxy (New in v1.4.0) - - Configure in the configuration file: - - ```toml - [security] - [server-http-tls] - cert-allowed-cn = ["tiproxy", "tidb", "test-client", "prometheus"] - ``` - ## Reload certificates -- If your TiDB cluster is deployed in a local data center, to reload the certificates and keys, TiDB, PD, TiKV, TiFlash, TiCDC, TiProxy, and all kinds of clients reread the current certificates and key files each time a new connection is created, without restarting the TiDB cluster. +- If your TiDB cluster is deployed in a local data center, to reload the certificates and keys, TiDB, PD, TiKV, TiFlash, TiCDC, and all kinds of clients reread the current certificates and key files each time a new connection is created, without restarting the TiDB cluster. -- If your TiDB cluster is deployed on your own managed cloud, make sure that the issuance of TLS certificates is integrated with the certificate management service of the cloud provider. The TLS certificates of the TiDB, PD, TiKV, TiFlash, TiCDC, and TiProxy components can be automatically rotated without restarting the TiDB cluster. +- If your TiDB cluster is deployed on your own managed cloud, make sure that the issuance of TLS certificates is integrated with the certificate management service of the cloud provider. The TLS certificates of the TiDB, PD, TiKV, TiFlash, and TiCDC components can be automatically rotated without restarting the TiDB cluster. ## Certificate validity diff --git a/encryption-at-rest.md b/encryption-at-rest.md index d8276dad349e9..b7f0a3bcc7af5 100644 --- a/encryption-at-rest.md +++ b/encryption-at-rest.md @@ -32,7 +32,7 @@ SM4 encryption is only supported in v6.3.0 and later versions of TiKV. TiKV vers ### TiFlash -TiFlash supports encryption at rest. Data keys are generated by TiFlash. All files (including data files, schema files, and temporary files) written into TiFlash (including TiFlash Proxy) are encrypted using the current data key. The encryption algorithms, the encryption configuration (in the [`tiflash-learner.toml` file](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file) supported by TiFlash), and the meanings of monitoring metrics are consistent with those of TiKV. +TiFlash supports encryption at rest. Data keys are generated by TiFlash. All files (including data files, schema files, and temporary files) written into TiFlash (including TiFlash Proxy) are encrypted using the current data key. The encryption algorithms, the encryption configuration (in the [`tiflash-learner.toml` file](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file) supported by TiFlash, and the meanings of monitoring metrics are consistent with those of TiKV. If you have deployed TiFlash with Grafana, you can check the **TiFlash-Proxy-Details** -> **Encryption** panel. diff --git a/functions-and-operators/json-functions/json-functions-validate.md b/functions-and-operators/json-functions/json-functions-validate.md index fc27127ebd694..a01a47c362c4d 100644 --- a/functions-and-operators/json-functions/json-functions-validate.md +++ b/functions-and-operators/json-functions/json-functions-validate.md @@ -130,7 +130,7 @@ SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables"]}',@j); 1 row in set (0.00 sec) ``` -In the preceding output, you can see that the validation of the presence of the `fruits` and `vegetables` attributes succeeds. +In the preceding output, you can see that see that validation of the presence of the `fruits` and `vegetables` attributes succeeds. ```sql SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j); @@ -145,7 +145,7 @@ SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j); 1 row in set (0.00 sec) ``` -In the preceding output, you can see that the validation of the presence of the `fruits`, `vegetables` and `grains` attributes fails because `grains` is not present. +In the preceding output, you can see that see that validation of the presence of the `fruits`, `vegetables` and `grains` attributes fails because `grains` is not present. Now validate that `fruits` is an array. diff --git a/functions-and-operators/locking-functions.md b/functions-and-operators/locking-functions.md index 14238fefa62aa..08a261cfa241c 100644 --- a/functions-and-operators/locking-functions.md +++ b/functions-and-operators/locking-functions.md @@ -20,6 +20,6 @@ TiDB supports most of the user-level [locking functions](https://dev.mysql.com/d ## MySQL compatibility * The minimum timeout permitted by TiDB is 1 second, and the maximum timeout is 1 hour (3600 seconds). This differs from MySQL, where both 0 second and unlimited timeouts (`timeout=-1`) are permitted. TiDB will automatically convert out-of-range values to the nearest permitted value and convert `timeout=-1` to 3600 seconds. -* TiDB does not automatically detect deadlocks caused by user-level locks. Deadlocked sessions will time out after a maximum of 1 hour, but can also be manually resolved by using [`KILL`](/sql-statements/sql-statement-kill.md) on one of the affected sessions. You can also prevent deadlocks by always acquiring user-level locks in the same order. +* TiDB does not automatically detect deadlocks caused by user-level locks. Deadlocked sessions will timeout after a maximum of 1 hour, but can also be manually resolved by using [`KILL`](/sql-statements/sql-statement-kill.md) on one of the affected sessions. You can also prevent deadlocks by always acquiring user-level locks in the same order. * Locks take effect on all TiDB servers in the cluster. This differs from MySQL Cluster and Group Replication where locks are local to a single server. * `IS_USED_LOCK()` returns `1` if it is called from another session and is unable to return the ID of the process that is holding the lock. diff --git a/functions-and-operators/string-functions.md b/functions-and-operators/string-functions.md index 9f1ef27a07c0d..f671ee9d853be 100644 --- a/functions-and-operators/string-functions.md +++ b/functions-and-operators/string-functions.md @@ -134,7 +134,7 @@ SELECT CustomerName, BIT_LENGTH(CustomerName) AS BitLengthOfName FROM Customers; ### [`CHAR()`](https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_char) -The `CHAR()` function is used to get the corresponding character of a specific ASCII value. It performs the opposite operation of `ASCII()`, which returns the ASCII value of a specific character. If multiple arguments are supplied, the function works on all arguments and are then concatenated together. +The `CHAR()` function is used to get the corresponding character of a specific ASCII value. It performs the opposite operation of `ASCII()`, which returns the ASCII value of a specific character. If multiple arguments are supplied, the function works on all arguments and are then concaternated together. Examples: diff --git a/geo-distributed-deployment-topology.md b/geo-distributed-deployment-topology.md index 2003c653c42f8..2a227cc467cfc 100644 --- a/geo-distributed-deployment-topology.md +++ b/geo-distributed-deployment-topology.md @@ -67,7 +67,7 @@ This section describes the key parameter configuration of the TiDB geo-distribut > **Note:** > -> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks` before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. +> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks' before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. #### PD parameters diff --git a/identify-slow-queries.md b/identify-slow-queries.md index ff2304f737f25..0962505d3ea8d 100644 --- a/identify-slow-queries.md +++ b/identify-slow-queries.md @@ -593,7 +593,7 @@ ADMIN SHOW SLOW TOP [internal | all] N ADMIN SHOW SLOW recent 10 ``` -`top N` shows the slowest N query records recently (within a few days). If the `internal` option is provided, the returned results would be the inner SQL executed by the system; If the `all` option is provided, the returned results would be the user's SQL combined with inner SQL; Otherwise, this command would only return the slow query records from the user's SQL. +`top N` shows the slowest N query records recently (within a few days). If the `internal` option is provided, the returned results would be the inner SQL executed by the system; If the `all` option is provided, the returned results would be the user's SQL combinated with inner SQL; Otherwise, this command would only return the slow query records from the user's SQL. {{< copyable "sql" >}} diff --git a/information-schema/client-errors-summary-by-user.md b/information-schema/client-errors-summary-by-user.md index b0cf4bb59e7aa..797897bae8502 100644 --- a/information-schema/client-errors-summary-by-user.md +++ b/information-schema/client-errors-summary-by-user.md @@ -13,7 +13,7 @@ The table `CLIENT_ERRORS_SUMMARY_BY_USER` provides a summary of SQL errors and w * Permission errors. * A table that does not exist. -Client errors are returned to the client via the MySQL server protocol, where applications are expected to take appropriate action. The `INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER` table provides a useful method to inspect errors in the scenario where applications are not correctly handling (or logging) errors returned by the TiDB server. +Client errors are returned to the client via the MySQL server protocol, where applications are expected to take appropriate action. The `INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER` table provides an useful method to inspect errors in the scenario where applications are not correctly handling (or logging) errors returned by the TiDB server. Because `CLIENT_ERRORS_SUMMARY_BY_USER` summarizes the errors on a per-user basis, it can be useful to diagnose scenarios where one user server is generating more errors than other servers. Possible scenarios include: diff --git a/information-schema/information-schema-sql-diagnostics.md b/information-schema/information-schema-sql-diagnostics.md index 5ce5342e38df6..ab65d80a104df 100644 --- a/information-schema/information-schema-sql-diagnostics.md +++ b/information-schema/information-schema-sql-diagnostics.md @@ -19,7 +19,7 @@ The SQL diagnostic system has the following advantages: The SQL diagnostic system consists of three major parts: -+ **Cluster information table**: The SQL diagnostics system introduces cluster information tables that provide a unified way to get the discrete information of each instance. This system fully integrates the cluster topology, hardware information, software information, kernel parameters, monitoring, system information, slow queries, statements, and logs of the entire cluster into the table. So you can query this information using SQL statements. ++ **Cluster information table**: The SQL diagnostics system introduces cluster information tables that provide a unified way to get the discrete information of each instance. This system fully integrates the cluster topology, hardware information, software information, kernel parameters, monitoring, system information, slow queries, statements, and logs of the entire cluster into the table. So you can query these information using SQL statements. + **Cluster monitoring table**: The SQL diagnostic system introduces cluster monitoring tables. All of these tables are in `metrics_schema`, and you can query monitoring information using SQL statements. Compared to the visualized monitoring before v4.0, you can use this SQL-based method to perform correlated queries on all the monitoring information of the entire cluster, and compare the results of different time periods to quickly identify performance bottlenecks. Because the TiDB cluster has many monitoring metrics, the SQL diagnostic system also provides monitoring summary tables, so you can find abnormal monitoring items more easily. diff --git a/information-schema/information-schema-statistics.md b/information-schema/information-schema-statistics.md index b353f7a5fbc0e..2b02a35794522 100644 --- a/information-schema/information-schema-statistics.md +++ b/information-schema/information-schema-statistics.md @@ -58,7 +58,7 @@ Fields in the `STATISTICS` table are described as follows: * `INDEX_TYPE`: The type of the index. * `COMMENT`: Other information related to the index. * `INDEX_COMMENT`: Any comment with comment attribute provided for the index when creating the index. -* `IS_VISIBLE`: Whether this index is visible or not. See also [Invisible index](/sql-statements/sql-statement-create-index.md#invisible-index). +* `IS_VISIBLE`: Whether the optimizer can use this index. * `Expression` For the index key of the non-expression part, this value is `NULL`; for the index key of the expression part, this value is the expression itself. Refer to [Expression Index](/sql-statements/sql-statement-create-index.md#expression-index). The following statements are equivalent: diff --git a/information-schema/information-schema-tables.md b/information-schema/information-schema-tables.md index 8ae5df9a46bf1..d3d3613f2f25f 100644 --- a/information-schema/information-schema-tables.md +++ b/information-schema/information-schema-tables.md @@ -106,7 +106,7 @@ The description of columns in the `TABLES` table is as follows: * `MAX_DATA_LENGTH`: The maximum data length. The value is currently `0`, which means the data length has no upper limit. * `INDEX_LENGTH`: The index length. `INDEX_LENGTH` = `TABLE_ROWS` \* the sum of lengths of the columns in the index tuple. The replicas of TiKV are not taken into account. * `DATA_FREE`: Data fragment. The value is currently `0`. -* `AUTO_INCREMENT`: The current step of the auto-increment primary key. +* `AUTO_INCREMENT`: The current step of the auto- increment primary key. * `CREATE_TIME`: The time at which the table is created. * `UPDATE_TIME`: The time at which the table is updated. * `CHECK_TIME`: The time at which the table is checked. diff --git a/literal-values.md b/literal-values.md index d2ca476cb11b5..f0048492460a6 100644 --- a/literal-values.md +++ b/literal-values.md @@ -94,7 +94,7 @@ Date and time literal values can be represented in several formats, such as quot TiDB supports the following date formats: -* `'YYYY-MM-DD'` or `'YY-MM-DD'`: The `-` delimiter here is not strict. It can be any punctuation. For example, `'2017-08-24'`, `'2017&08&24'`, `'2012@12^31'` are all valid date formats. The only special punctuation is '.', which is treated as a decimal point to separate the integer and fractional parts. Date and time can be separated by `T` or a white space. For example, `2017-8-24 10:42:00` and `2017-8-24T10:42:00` represents the same date and time. +* `'YYYY-MM-DD'` or `'YY-MM-DD'`: The `-` delimiter here is not strict. It can be any punctuation. For example, `'2017-08-24'`, `'2017&08&24'`, `'2012@12^31'` are all valid date formats. The only special punctuation is '.', which is is treated as a decimal point to separate the integer and fractional parts. Date and time can be separated by `T` or a white space. For example, `2017-8-24 10:42:00` and `2017-8-24T10:42:00` represents the same date and time. * `'YYYYMMDDHHMMSS'` or `'YYMMDDHHMMSS'`: For example, `'20170824104520'` and `'170824104520'` are regarded as `'2017-08-24 10:45:20'`. However, if you provide a value out of range, such as `'170824304520'`, it is not treated as a valid date. Note that incorrect formats such as `YYYYMMDD HHMMSS`, `YYYYMMDD HH:MM:DD`, or `YYYY-MM-DD HHMMSS` will fail to insert. * `YYYYMMDDHHMMSS` or `YYMMDDHHMMSS`: Note that these formats have no single or double quotes, but a number. For example, `20170824104520` is interpreted as `'2017-08-24 10:45:20'`. diff --git a/media/tiproxy/tiproxy-balance-label.png b/media/tiproxy/tiproxy-balance-label.png index 44fee918cdcc6a8607a1ec848c205345da1a5cee..c291c40ba05ce5f4e2dc38cc3d5f87d8680d836d 100644 GIT binary patch literal 86358 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˾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 literal 98047 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 in v8.3.0 +### [`54337`](https://github.com/pingcap/tidb/issues/54337) New in v8.2.0 - Default value: `OFF` - Possible values: `ON`, `OFF` diff --git a/optimizer-hints.md b/optimizer-hints.md index b54f012db7815..4c26637579bcb 100644 --- a/optimizer-hints.md +++ b/optimizer-hints.md @@ -497,7 +497,7 @@ SELECT /*+ LIMIT_TO_COP() */ * FROM t WHERE a = 1 AND b > 10 ORDER BY c LIMIT 1; ### READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]]) -The `READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]])` hint tells the optimizer to read specific table(s) from specific storage engine(s). Currently, this hint supports two storage engine parameters - `TIKV` and `TIFLASH`. If a table has an alias, use the alias as the parameter of `READ_FROM_STORAGE()`; if the table does not have an alias, use the table's original name as the parameter. For example: +The `READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]])` hint tells the optimizer to read specific table(s) from specific storage engine(s). Currently, this hint supports two storage engine parameters - `TIKV` and `TIFLASH`. If a table has an alias, use the alias as the parameter of `READ_FROM_STORAGE()`; if the table does not has an alias, use the table's original name as the parameter. For example: {{< copyable "sql" >}} diff --git a/pipelined-dml.md b/pipelined-dml.md index 7b3c0a1ea6854..858cae7b27ae9 100644 --- a/pipelined-dml.md +++ b/pipelined-dml.md @@ -102,10 +102,6 @@ If the `pipelined` field in the output is `true`, it indicates that Pipelined DM - The [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) system variable controls whether Pipelined DML is enabled at the session level. -- The [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) system variable controls the resource usage policy for Pipelined DML. When the following resource contention occurs, consider setting this variable to `conservative` to reduce the impact of Pipelined DML on cluster performance: - - TiKV nodes experience write hotspots and high load. - - The request latency of OLTP applications significantly increases. - - The write throughput of the cluster significantly decreases. - When [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `"bulk"`, the [`pessimistic-auto-commit`](/tidb-configuration-file.md#pessimistic-auto-commit-new-in-v600) configuration item behaves as if it is set to `false`. - Transactions executed using Pipelined DML are not subject to the size limit specified by the TiDB configuration item [`txn-total-size-limit`](/tidb-configuration-file.md#txn-total-size-limit). - For large transactions executed using Pipelined DML, transaction duration might increase. In such cases, the maximum TTL for the transaction lock is the larger value of [`max-txn-ttl`](/tidb-configuration-file.md#max-txn-ttl) or 24 hours. @@ -116,10 +112,6 @@ If the `pipelined` field in the output is `true`, it indicates that Pipelined DM - The [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) system variable controls whether Pipelined DML is enabled at the session level. -- The [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) system variable controls the resource usage policy for Pipelined DML. When the following resource contention occurs, consider setting this variable to `conservative` to reduce the impact of Pipelined DML on cluster performance: - - TiKV nodes experience write hotspots and high load. - - The request latency of OLTP applications significantly increases. - - The write throughput of the cluster significantly decreases. - When [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `"bulk"`, the [`pessimistic-auto-commit`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#pessimistic-auto-commit-new-in-v600) configuration item behaves as if it is set to `false`. - Transactions executed using Pipelined DML are not subject to the size limit specified by the TiDB configuration item [`txn-total-size-limit`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#txn-total-size-limit). - For large transactions executed using Pipelined DML, transaction duration might increase. In such cases, the maximum TTL for the transaction lock is the larger value of [`max-txn-ttl`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#max-txn-ttl) or 24 hours. diff --git a/privilege-management.md b/privilege-management.md index c0b1bb3df426c..e9525983fa2cf 100644 --- a/privilege-management.md +++ b/privilege-management.md @@ -282,8 +282,6 @@ Dynamic privileges include: * `RESTRICTED_USER_ADMIN` prohibits privilege owners to have their access revoked by SUPER users when SEM is enabled. * `RESTRICTED_CONNECTION_ADMIN` allows privilege owners to kill connections of `RESTRICTED_USER_ADMIN` users. This privilege affects `KILL` and `KILL TIDB` statements. * `RESTRICTED_REPLICA_WRITER_ADMIN` allows privilege owners to perform write or update operations without being affected when the read-only mode is enabled in the TiDB cluster. For details, see [`tidb_restricted_read_only`](/system-variables.md#tidb_restricted_read_only-new-in-v520). -* `TRAFFIC_CAPTURE_ADMIN` allows privilege owners to create, view, and cancel traffic capture jobs. For details, see [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md). -* `TRAFFIC_REPLAY_ADMIN` allows privilege owners to create, view, and cancel traffic replay jobs. For details, see [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md). To see the full set of dynamic privileges, execute the `SHOW PRIVILEGES` statement. Because plugins are permitted to add new privileges, the list of privileges that are assignable might differ based on your TiDB installation. @@ -500,26 +498,6 @@ Requires `SUPER` or `RESOURCE_GROUP_ADMIN` privilege. When the system variable [`tidb_resource_control_strict_mode`](/system-variables.md#tidb_resource_control_strict_mode-new-in-v820) is set to `ON`, you need to have the `SUPER` or `RESOURCE_GROUP_ADMIN` or `RESOURCE_GROUP_USER` privilege to execute this statement. -### TRAFFIC CAPTURE - -Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege. - -### TRAFFIC REPLAY - -Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege. - -### CANCEL TRAFFIC JOBS - -Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege to cancel traffic capture jobs. - -Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege to cancel traffic replay jobs. - -### SHOW TRAFFIC JOBS - -Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege to view traffic capture jobs. - -Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege to view traffic replay jobs. - ## Implementation of the privilege system ### Privilege table diff --git a/releases/release-6.0.0-dmr.md b/releases/release-6.0.0-dmr.md index 8ceb69dcc9b65..ff848e7df7941 100644 --- a/releases/release-6.0.0-dmr.md +++ b/releases/release-6.0.0-dmr.md @@ -556,7 +556,7 @@ TiDB v6.0.0 is a DMR, and its version is 6.0.0-DMR. - A `loader..on-duplicate` parameter is added. The default value is `replace`, which means using the new data to replace the existing data. If you want to keep the previous behavior, you can set the value to `error`. This parameter only controls the behavior during the full import phase. - To use DM, you should use the corresponding version of `dmctl` - Due to internal mechanism changes, after upgrading DM to v6.0.0, you should also upgrade `dmctl` to v6.0.0. -- For v5.4 and earlier versions, TiDB allows incorrect values for some noop system variables. Starting from v6.0.0, TiDB disallows setting incorrect values for system variables. [#31538](https://github.com/pingcap/tidb/issues/31538) +- In v5.4 (v5.4 only), TiDB allows incorrect values for some noop system variables. Since v6.0.0, TiDB disallows setting incorrect values for system variables. [#31538](https://github.com/pingcap/tidb/issues/31538) ## Improvements diff --git a/releases/release-8.4.0.md b/releases/release-8.4.0.md index 6bffd4b467d21..b99d71e6be2fc 100644 --- a/releases/release-8.4.0.md +++ b/releases/release-8.4.0.md @@ -54,7 +54,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.4/quick-start-with- Concurrent automatic statistics collection - Introduce the system variable tidb_auto_analyze_concurrency to control the number of concurrent auto-analyze operations within a TiDB cluster. TiDB automatically determines the concurrency of scanning tasks based on node scale and hardware specifications. This improves statistics collection efficiency by fully utilizing system resources, reduces manual tuning, and ensures stable cluster performance. + You can set the concurrency within a single automatic statistics collection task using the system variable tidb_auto_analyze_concurrency. TiDB automatically determines the concurrency of scanning tasks based on node scale and hardware specifications. This improves statistics collection efficiency by fully utilizing system resources, reduces manual tuning, and ensures stable cluster performance. SQL @@ -290,7 +290,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.4/quick-start-with- | [`tidb_opt_prefer_range_scan`](/system-variables.md#tidb_opt_prefer_range_scan-new-in-v50) | Modified | Changes the default value from `OFF` to `ON`. For tables with no statistics (pseudo-statistics) or empty tables (zero statistics), the optimizer prefers interval scans over full table scans. | | [`tidb_scatter_region`](/system-variables.md#tidb_scatter_region) | Modified | Before v8.4.0, its type is boolean, it only supports `ON` and `OFF`, and the Region of the newly created table only supports table level scattering after it is enabled. Starting from v8.4.0, the `SESSION` scope is added, the type is changed from boolean to enumeration, the default value is changed from `OFF` to null, and the optional values `TABLE` and `GLOBAL` are added. In addition, it now supports cluster-level scattering policy to avoid the TiKV OOM issues caused by uneven distribution of regions during fast table creation in batches.| | [`tidb_schema_cache_size`](/system-variables.md#tidb_schema_cache_size-new-in-v800) | Modified | Changes the default value from `0` to `536870912` (512 MiB), indicating that this feature is enabled by default. The minimum value allowed is set to `67108864` (64 MiB). | -| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840)| Newly added | Sets the concurrency for auto-analyze operations within a TiDB cluster. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. | +| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840)| Newly added | Sets the concurrency within a single automatic statistics collection task. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. | | [`tidb_enable_instance_plan_cache`](/system-variables.md#tidb_enable_instance_plan_cache-new-in-v840)| Newly added | Controls whether to enable the Instance Plan Cache feature. | | [`tidb_enable_stats_owner`](/system-variables.md#tidb_enable_stats_owner-new-in-v840)| Newly added | Controls whether the corresponding TiDB instance can run automatic statistics update tasks. | | [`tidb_hash_join_version`](/system-variables.md#tidb_hash_join_version-new-in-v840) | Newly added | Controls whether TiDB uses an optimized version of the Hash Join operator. The default value of `legacy` means that the optimized version is not used. If you set it to `optimized`, TiDB uses the optimized version of the Hash Join operator when executing it to improve Hash Join performance. | @@ -375,7 +375,7 @@ The following features are planned for deprecation in future versions: - Add write control to the [`mysql.tidb_runaway_queries`](/mysql-schema/mysql-schema.md#system-tables-related-to-runaway-queries) log table to reduce overhead caused by a large number of concurrent writes [#54434](https://github.com/pingcap/tidb/issues/54434) @[HuSharp](https://github.com/HuSharp) - Support Index Join by default when the inner table has `Selection`, `Projection`, or `Aggregation` operators on it [#47233](https://github.com/pingcap/tidb/issues/47233) @[winoros](https://github.com/winoros) - Reduce the number of column details fetched from TiKV for `DELETE` operations in certain scenarios, lowering the resource overhead of these operations [#38911](https://github.com/pingcap/tidb/issues/38911) @[winoros](https://github.com/winoros) - - Support setting the concurrency for auto-analyze operations within a TiDB cluster using the system variable `tidb_auto_analyze_concurrency` [#53460](https://github.com/pingcap/tidb/issues/53460) @[hawkingrei](https://github.com/hawkingrei) + - Support setting the concurrency within a single automatic statistics collection task using the system variable `tidb_auto_analyze_concurrency` [#53460](https://github.com/pingcap/tidb/issues/53460) @[hawkingrei](https://github.com/hawkingrei) - Optimize the logic of an internal function to improve performance when querying tables with numerous columns [#52112](https://github.com/pingcap/tidb/issues/52112) @[Rustin170506](https://github.com/Rustin170506) - Simplify filter conditions like `a = 1 AND (a > 1 OR (a = 1 AND b = 2))` to `a = 1 AND b = 2` [#56005](https://github.com/pingcap/tidb/issues/56005) @[ghazalfamilyusa](https://github.com/ghazalfamilyusa) - Increase the cost of table scans in the cost model for scenarios with a high risk of suboptimal execution plans, making the optimizer prefer indexes [#56012](https://github.com/pingcap/tidb/issues/56012) @[terry1purcell](https://github.com/terry1purcell) diff --git a/security-compatibility-with-mysql.md b/security-compatibility-with-mysql.md index de39791eac0da..7daed60607a32 100644 --- a/security-compatibility-with-mysql.md +++ b/security-compatibility-with-mysql.md @@ -190,7 +190,7 @@ Signature is used to sign the Header and Payload data. > **Warning:** > > - The encoding of the Header and Payload in base64 is reversible. Do **Not** attach any sensitive information to them. -> - The `tidb_auth_token` authentication method requires clients to support the [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in plain text. Therefore, you need to [enable TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`. +> - The `tidb_auth_token` authentication method requires clients to support the [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in plain text. Therefore, you need to [enale TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`. #### Usage diff --git a/sql-statements/sql-statement-admin.md b/sql-statements/sql-statement-admin.md index e25d07d3e5d6e..e89b62104bd66 100644 --- a/sql-statements/sql-statement-admin.md +++ b/sql-statements/sql-statement-admin.md @@ -14,7 +14,6 @@ This statement is a TiDB extension syntax, used to view the status of TiDB and c - [`ADMIN REPAIR`](#admin-repair-statement) - [`ADMIN SHOW NEXT_ROW_ID`](#admin-show-next_row_id-statement) - [`ADMIN SHOW SLOW`](#admin-show-slow-statement) -- [`ADMIN CREATE WORKLOAD SNAPSHOT`](#admin-create-workload-snapshot-statement) ## DDL related statement @@ -150,28 +149,6 @@ For details, refer to [`ADMIN SHOW SLOW` command](/identify-slow-queries.md#admi -## `ADMIN CREATE WORKLOAD SNAPSHOT` statement - - - -> **Note:** -> -> This TiDB statement is not applicable to TiDB Cloud. - - - - - -The following SQL statement will trigger a manual snapshot in the [Workload Repository](/workload-repository.md): - - - -```sql -ADMIN CREATE WORKLOAD SNAPSHOT; -``` - -Note that the Workload Repository must be enabled for this statement to take effect. Otherwise, it will generate an error. - ## Synopsis ```ebnf+diagram @@ -209,7 +186,6 @@ AdminStmt ::= | 'FLUSH' ('SESSION' | 'INSTANCE') 'PLAN_CACHE' | 'SET' 'BDR' 'ROLE' ( 'PRIMARY' | 'SECONDARY' ) | 'UNSET' 'BDR' 'ROLE' - | 'CREATE' 'WORKLOAD' 'SNAPSHOT' ) NumList ::= diff --git a/sql-statements/sql-statement-cancel-traffic-jobs.md b/sql-statements/sql-statement-cancel-traffic-jobs.md deleted file mode 100644 index dc630ec64dc78..0000000000000 --- a/sql-statements/sql-statement-cancel-traffic-jobs.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: CANCEL TRAFFIC JOBS -summary: An overview of the usage of CANCEL TRAFFIC JOBS for the TiDB database. ---- - -# CANCEL TRAFFIC JOBS - -TiDB v9.0.0 introduces the `CANCEL TRAFFIC JOBS` syntax, which is used to cancel all traffic capture or replay jobs being executed by [TiProxy](/tiproxy/tiproxy-overview.md) in the cluster. This operation requires the following privileges: - -- To cancel traffic capture jobs, you need the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. -- To cancel traffic replay jobs, you need the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - -## Synopsis - -```ebnf+diagram -TrafficStmt ::= - "CANCEL" "TRAFFIC" "JOBS" -``` - -## Examples - -Assume that there are currently two TiProxy instances capturing traffic: - -```sql -SHOW TRAFFIC JOBS; -``` - -``` -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -2 rows in set (0.01 sec) -``` - -Cancel the current jobs: - -```sql -CANCEL TRAFFIC JOBS; -``` - -``` -Query OK, 0 rows affected (0.13 sec) -``` - -Check the jobs again and it shows that the jobs have been canceled: - -```sql -SHOW TRAFFIC JOBS; -``` - -``` -+----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ -| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | -+----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ -| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.10:3080 | capture | 45% | canceled | manually stopped | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.11:3080 | capture | 45% | canceled | manually stopped | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -+----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ -2 rows in set (0.01 sec) -``` - -## MySQL compatibility - -This statement is a TiDB extension to MySQL syntax. - -## See also - -* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) -* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) -* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) -* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) diff --git a/sql-statements/sql-statement-commit.md b/sql-statements/sql-statement-commit.md index 7e051fd9edc4c..a608592bd3a26 100644 --- a/sql-statements/sql-statement-commit.md +++ b/sql-statements/sql-statement-commit.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-commit/','/docs/dev/reference/ # COMMIT -This statement commits a transaction inside of the TiDB server. +This statement commits a transaction inside of the TIDB server. In the absence of a `BEGIN` or `START TRANSACTION` statement, the default behavior of TiDB is that every statement will be its own transaction and autocommit. This behavior ensures MySQL compatibility. diff --git a/sql-statements/sql-statement-drop-view.md b/sql-statements/sql-statement-drop-view.md index 7ee75dae73eb3..6201a03ddf301 100644 --- a/sql-statements/sql-statement-drop-view.md +++ b/sql-statements/sql-statement-drop-view.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-drop-view/','/docs/dev/referen # DROP VIEW -This statement drops a view object from the currently selected database. It does not affect any base tables that a view references. +This statement drops an view object from the currently selected database. It does not effect any base tables that a view references. ## Synopsis diff --git a/sql-statements/sql-statement-rollback.md b/sql-statements/sql-statement-rollback.md index cfcca4cf8364c..5a08335a17243 100644 --- a/sql-statements/sql-statement-rollback.md +++ b/sql-statements/sql-statement-rollback.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-rollback/','/docs/dev/referenc # ROLLBACK -This statement reverts all changes in the current transaction inside of TiDB. It is the opposite of a `COMMIT` statement. +This statement reverts all changes in the current transaction inside of TIDB. It is the opposite of a `COMMIT` statement. ## Synopsis diff --git a/sql-statements/sql-statement-show-placement-for.md b/sql-statements/sql-statement-show-placement-for.md index 9df40d6b3665d..99b49e33ef7b8 100644 --- a/sql-statements/sql-statement-show-placement-for.md +++ b/sql-statements/sql-statement-show-placement-for.md @@ -13,7 +13,7 @@ summary: The usage of SHOW PLACEMENT FOR in TiDB. The statement returns a result set in which the `Scheduling_State` field indicates the current progress that the Placement Driver (PD) has made in scheduling the placement: -* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores that are candidates for followers. +* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores that are candidates for followers. * `INPROGRESS`: The PD is currently scheduling the placement. * `SCHEDULED`: The PD has successfully scheduled the placement. diff --git a/sql-statements/sql-statement-show-placement.md b/sql-statements/sql-statement-show-placement.md index 289b5842aabeb..628fb8d2b4e97 100644 --- a/sql-statements/sql-statement-show-placement.md +++ b/sql-statements/sql-statement-show-placement.md @@ -13,7 +13,7 @@ summary: The usage of SHOW PLACEMENT in TiDB. The statement returns a result set in which the `Scheduling_State` field indicates the current progress that the Placement Driver (PD) has made in scheduling the placement: -* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores which are candidates for followers. +* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores which are candidates for followers. * `INPROGRESS`: The PD is currently scheduling the placement. * `SCHEDULED`: The PD has successfully scheduled the placement. diff --git a/sql-statements/sql-statement-show-traffic-jobs.md b/sql-statements/sql-statement-show-traffic-jobs.md deleted file mode 100644 index 0173a05499ade..0000000000000 --- a/sql-statements/sql-statement-show-traffic-jobs.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: SHOW TRAFFIC JOBS -summary: An overview of the usage of SHOW TRAFFIC JOBS for the TiDB database. ---- - -# SHOW TRAFFIC JOBS - -TiDB v9.0.0 introduces the `SHOW TRAFFIC JOBS` syntax, which is used to show all traffic capture or replay jobs executed by [TiProxy](/tiproxy/tiproxy-overview.md) in the cluster. In the output, each row represents a job of a TiProxy instance. Each TiProxy instance stores up to 10 most recent jobs. - -The shown results vary depending on the privileges the current user has. - -- A user with the [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege can view traffic capture jobs. -- A user with the [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege can view traffic replay jobs. -- A user with the `SUPER` privilege or both preceding privileges can view both traffic capture and traffic replay jobs at the same time. - -The `SHOW TRAFFIC JOBS` statement returns the following columns: - -| Column name | Description | -| :-------- | :------------- | -| `START_TIME` | The start time of the job | -| `END_TIME` | The end time if the job has completed. Otherwise, it is empty. | -| `INSTANCE` | The address of the TiProxy instance | -| `TYPE` | The job type. `capture` indicates a traffic capture job, `replay` indicates a traffic replay job | -| `PROGRESS` | The completion percentage of the job | -| `STATUS` | The current status of the job. `running` indicates in progress, `done` indicates normal completion, and `canceled` indicates job failure. | -| `FAIL_REASON` | If the job fails, this column contains the reason for the failure. Otherwise, it is empty. For example, `manually stopped` means the user manually canceled the job by executing `CANCEL TRAFFIC JOBS`. | -| `PARAMS` | The parameters of the job | - -## Synopsis - -```ebnf+diagram -TrafficStmt ::= - "SHOW" "TRAFFIC" "JOBS" -``` - -## Examples - -Show the traffic capture or replay jobs: - -```sql -SHOW TRAFFIC JOBS; -``` - -The following output example shows that two TiProxy instances are capturing traffic, and the progress is 45% for both: - -``` -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -2 rows in set (0.01 sec) -``` - -The following output example shows that the traffic replay jobs of two TiProxy instances are manually canceled: - -``` -+----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ -| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | -+----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ -| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.10:3080 | replay | 70% | canceled | manually stopped | INPUT="/tmp/traffic", USER="root", SPEED=0.000000, READ_ONLY=false | -| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:43.000000 | 10.1.0.11:3080 | replay | 69% | canceled | manually stopped | INPUT="/tmp/traffic", USER="root", SPEED=0.000000, READ_ONLY=false | -+----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ -2 rows in set (0.01 sec) -``` - -## MySQL compatibility - -This statement is a TiDB extension to MySQL syntax. - -## See also - -* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) -* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) -* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) -* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) diff --git a/sql-statements/sql-statement-traffic-capture.md b/sql-statements/sql-statement-traffic-capture.md deleted file mode 100644 index 96e3d26b4250c..0000000000000 --- a/sql-statements/sql-statement-traffic-capture.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: TRAFFIC CAPTURE -summary: An overview of the usage of TRAFFIC CAPTURE for the TiDB database. ---- - -# TRAFFIC CAPTURE - -TiDB v9.0.0 introduces the `TRAFFIC CAPTURE` syntax, which is used to send requests to all [TiProxy](/tiproxy/tiproxy-overview.md) instances in the cluster, allowing TiProxy to capture client traffic and save it to traffic files. - -TiProxy supports capturing traffic to local and external storage. When using local storage, you need to manually copy the traffic files to the TiProxy cluster for replay. When using external storage, no manual copying is needed. - -TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, and other S3-compatible file storage services. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). - -`TRAFFIC CAPTURE` supports the following options: - -- `DURATION`: (required) specifies the duration of capture. The unit is one of `m` (minutes), `h` (hours), or `d` (days). For example, `DURATION="1h"` captures traffic for one hour. -- `COMPRESS`: (optional) specifies whether to compress traffic files. `true` means compression, and the compression format is gzip. `false` means no compression. The default value is `true`. -- `ENCRYPTION_METHOD`: (optional) specifies the algorithm for encrypting traffic files. Only `""`, `plaintext`, and `aes256-ctr` are supported. `""` and `plaintext` indicate no encryption, and `aes256-ctr` indicates encryption using the `AES256-CTR` algorithm. When specifying encryption, you also need to configure [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path). The default value is `""`. - -To capture traffic, the current user must have the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - -## Synopsis - -```ebnf+diagram -TrafficStmt ::= - "TRAFFIC" "CAPTURE" "TO" stringLit TrafficCaptureOptList - -TrafficCaptureOptList ::= - TrafficCaptureOpt -| TrafficCaptureOptList TrafficCaptureOpt - -TrafficCaptureOpt ::= - "DURATION" EqOpt stringLit -| "ENCRYPTION_METHOD" EqOpt stringLit -| "COMPRESS" EqOpt Boolean -``` - -## Examples - -Capture traffic for one day and save it to the local `/tmp/traffic` directory on the TiProxy instance: - -```sql -TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1d"; -``` - -Capture traffic for 10 minutes and save it to S3: - -```sql -TRAFFIC CAPTURE TO "s3://external/traffic?access-key=${access-key}&secret-access-key=${secret-access-key}" DURATION="10m"; -``` - -Capture traffic with automatic encryption but without compression: - -```sql -TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1h" COMPRESS=false ENCRYPTION_METHOD="aes256-ctr"; -``` - -## MySQL compatibility - -This statement is a TiDB extension to MySQL syntax. - -## See also - -* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) -* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) -* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) -* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) diff --git a/sql-statements/sql-statement-traffic-replay.md b/sql-statements/sql-statement-traffic-replay.md deleted file mode 100644 index edc5203c4a094..0000000000000 --- a/sql-statements/sql-statement-traffic-replay.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: TRAFFIC REPLAY -summary: An overview of the usage of TRAFFIC REPLAY for the TiDB database. ---- - -# TRAFFIC REPLAY - -TiDB v9.0.0 introduces the `TRAFFIC REPLAY` syntax, which is used to send requests to all [TiProxy](/tiproxy/tiproxy-overview.md) instances in the cluster, allowing TiProxy to replay traffic from the traffic file to TiDB. - -To replay traffic, the current user must have the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - -`TRAFFIC REPLAY` supports the following options: - -- `USER`: (required) specifies the database username for replay. -- `PASSWORD`: (optional) specifies the password for the username. The default value is an empty string `""`. -- `SPEED`: (optional) specifies the replay speed multiplier. The range is `[0.1, 10]`. The default value is `1`, indicating replay at the original speed. -- `READ_ONLY`: (optional) specifies whether to replay only read-only SQL statements. `true` means to replay only read-only SQL statements, `false` means to replay all SQL statements. The default value is `false`. - -## Synopsis - -```ebnf+diagram -TrafficStmt ::= - "TRAFFIC" "REPLAY" "FROM" stringLit TrafficReplayOptList - -TrafficReplayOptList ::= - TrafficReplayOpt -| TrafficReplayOptList TrafficReplayOpt - -TrafficReplayOpt ::= - "USER" EqOpt stringLit -| "PASSWORD" EqOpt stringLit -| "SPEED" EqOpt NumLiteral -| "READ_ONLY" EqOpt Boolean -``` - -## Examples - -Replay traffic from the local `/tmp/traffic` directory of the TiProxy instance, using the TiDB user `u1`, whose password is `"123456"`: - -```sql -TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456"; -``` - -Replay traffic from the traffic files stored in the S3 storage: - -```sql -TRAFFIC REPLAY FROM "s3://external/traffic?access-key=${access-key}&secret-access-key=${secret-access-key}" USER="u1" PASSWORD="123456"; -``` - -Replay traffic at double speed: - -```sql -TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" SPEED=2; -``` - -Replay only read-only statements, not write statements: - -```sql -TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" READ_ONLY=true; -``` - -## MySQL compatibility - -This statement is a TiDB extension to MySQL syntax. - -## See also - -* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) -* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) -* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) -* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) diff --git a/stale-read.md b/stale-read.md index b124e3977969e..bb1d2fb33ed38 100644 --- a/stale-read.md +++ b/stale-read.md @@ -35,7 +35,7 @@ TiDB provides the methods of performing Stale Read at the statement level, the s - Session level - Specifying a time range: In a session, if you need TiDB to read the data as new as possible within a time range in subsequent queries without violating the isolation level, you can specify the time range by setting the `tidb_read_staleness` system variable. For detailed usage, refer to [`tidb_read_staleness`](/tidb-read-staleness.md). -Besides, TiDB provides a way to specify an exact point in time at the session or global level by setting the [`tidb_external_ts`](/system-variables.md#tidb_external_ts-new-in-v640) and [`tidb_enable_external_ts_read`](/system-variables.md#tidb_enable_external_ts_read-new-in-v640) system variables. For detailed usage, refer to [Perform Stale Read Using `tidb_external_ts`](/tidb-external-ts.md). +Besides, TiDB provides a way to specify an exact point in time by setting the [`tidb_external_ts`](/system-variables.md#tidb_external_ts-new-in-v640) system variable on session or global level. For detailed usage, refer to [Perform Stale Read Using `tidb_external_ts`](/tidb-external-ts.md). ### Reduce Stale Read latency diff --git a/statement-summary-tables.md b/statement-summary-tables.md index ed295570c17b9..5e3b42eb7172d 100644 --- a/statement-summary-tables.md +++ b/statement-summary-tables.md @@ -415,17 +415,6 @@ Fields related to Resource Control: - `MAX_QUEUED_RC_TIME`: the maximum waiting time for available RU when executing SQL statements. - `RESOURCE_GROUP`: the resource group bound to SQL statements. -Fields related to network traffic: - -- `SUM_UNPACKED_BYTES_SENT_TIKV_TOTAL`: total bytes sent from SQL statements to TiKV. -- `SUM_UNPACKED_BYTES_RECEIVED_TIKV_TOTAL`: total bytes received by SQL statements from TiKV. -- `SUM_UNPACKED_BYTES_SENT_TIKV_CROSS_ZONE`: bytes sent from SQL statements to TiKV across availability zones. -- `SUM_UNPACKED_BYTES_RECEIVED_TIKV_CROSS_ZONE`: bytes received by SQL statements from TiKV across availability zones. -- `SUM_UNPACKED_BYTES_SENT_TIFLASH_TOTAL`: total bytes sent from SQL statements to TiFlash, including bytes sent between TiFlash nodes. -- `SUM_UNPACKED_BYTES_RECEIVED_TIFLASH_TOTAL`: total bytes received by SQL statements from TiFlash, including bytes received between TiFlash nodes. -- `SUM_UNPACKED_BYTES_SENT_TIFLASH_CROSS_ZONE`: bytes sent from SQL statements to TiFlash across availability zones, including bytes sent between TiFlash nodes across availability zones. -- `SUM_UNPACKED_BYTES_RECEIVED_TIFLASH_CROSS_ZONE`: bytes received by SQL statements from TiFlash across availability zones, including bytes received between TiFlash nodes across availability zones. - ### `statements_summary_evicted` fields description - `BEGIN_TIME`: Records the starting time. diff --git a/statistics.md b/statistics.md index f16cf14580911..06e5a8ba5c56e 100644 --- a/statistics.md +++ b/statistics.md @@ -32,15 +32,13 @@ Based upon the number of changes to a table, TiDB will automatically schedule [` | System Variable | Default Value | Description | |---|---|---| -| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840) | `1` | The concurrency for auto-analyze operations within a TiDB cluster. | | [`tidb_auto_analyze_end_time`](/system-variables.md#tidb_auto_analyze_end_time) | `23:59 +0000` | The end time in a day when TiDB can perform automatic updates. | -| [`tidb_auto_analyze_partition_batch_size`](/system-variables.md#tidb_auto_analyze_partition_batch_size-new-in-v640) | `8192` | The number of partitions that TiDB automatically analyzes when analyzing a partitioned table (that is, when automatically updating statistics on a partitioned table). | | [`tidb_auto_analyze_ratio`](/system-variables.md#tidb_auto_analyze_ratio) | `0.5` | The threshold value of automatic update. | | [`tidb_auto_analyze_start_time`](/system-variables.md#tidb_auto_analyze_start_time) | `00:00 +0000` | The start time in a day when TiDB can perform automatic update. | +| [`tidb_auto_analyze_partition_batch_size`](/system-variables.md#tidb_auto_analyze_partition_batch_size-new-in-v640) | `128` | The number of partitions that TiDB automatically analyzes when analyzing a partitioned table (that is, when automatically updating statistics on a partitioned table). | | [`tidb_enable_auto_analyze`](/system-variables.md#tidb_enable_auto_analyze-new-in-v610) | `ON` | Controls whether TiDB automatically executes `ANALYZE`. | | [`tidb_enable_auto_analyze_priority_queue`](/system-variables.md#tidb_enable_auto_analyze_priority_queue-new-in-v800) | `ON` | Controls whether to enable the priority queue to schedule the tasks of automatically collecting statistics. When this variable is enabled, TiDB prioritizes collecting statistics for tables that are more valuable to collect, such as newly created indexes and partitioned tables with partition changes. Additionally, TiDB prioritizes tables with lower health scores, placing them at the front of the queue. | | [`tidb_enable_stats_owner`](/system-variables.md#tidb_enable_stats_owner-new-in-v840) | `ON` | Controls whether the corresponding TiDB instance can run automatic statistics update tasks. | -| [`tidb_max_auto_analyze_time`](/system-variables.md#tidb_max_auto_analyze_time-new-in-v610) | `43200` (12 hours) | The maximum execution time of automatic `ANALYZE` tasks. The unit is second. | When the ratio of the number of modified rows to the total number of rows of `tbl` in a table is greater than `tidb_auto_analyze_ratio`, and the current time is between `tidb_auto_analyze_start_time` and `tidb_auto_analyze_end_time`, TiDB executes the `ANALYZE TABLE tbl` statement in the background to automatically update the statistics on this table. diff --git a/system-variable-reference.md b/system-variable-reference.md index 970d7cb8f00a4..e64d96b8072eb 100644 --- a/system-variable-reference.md +++ b/system-variable-reference.md @@ -4035,26 +4035,6 @@ Referenced in: - [SHOW [GLOBAL|SESSION] VARIABLES](/sql-statements/sql-statement-show-variables.md) - [System Variables](/system-variables.md#tidb_window_concurrency-new-in-v40) -### tidb_workload_repository_dest - -- [TiDB Workload Repository](/workload-repository.md#enable-the-workload-repository) -- [System Variables](/system-variables.md#tidb_workload_repository_dest-new-in-v900) - -### tidb_workload_repository_active_sampling_interval - -- [TiDB Workload Repository](/workload-repository.md#time-based-sampling-process-every-5-seconds-by-default) -- [System Variables](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) - -### tidb_workload_repository_retention_days - -- [TiDB Workload Repository](/workload-repository.md#data-retention) -- [System Variables](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) - -### tidb_workload_repository_snapshot_interval - -- [TiDB Workload Repository](/workload-repository.md#snapshot-sampling-process-hourly-by-default) -- [System Variables](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) - ### tiflash_fastscan Referenced in: @@ -4165,6 +4145,15 @@ Referenced in: - [System Variables](/system-variables.md#tx_read_ts) +### txn_scope + +Referenced in: + +- [Limited SQL features on TiDB Cloud](https://docs.pingcap.com/tidbcloud/limited-sql-features) +- [System Variables](/system-variables.md#txn_scope) +- [TiDB Configuration File](/tidb-configuration-file.md) +- [Use Resource Control to Achieve Resource Group Limitation and Flow Control](/tidb-resource-control-ru-groups.md) + ### validate_password.check_user_name Referenced in: diff --git a/system-variables.md b/system-variables.md index c31bde4afb2b9..15cfe1b9be5de 100644 --- a/system-variables.md +++ b/system-variables.md @@ -1224,7 +1224,7 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - Type: Integer - Default value: `1` - Range: `[1, 2147483647]` -- This variable controls the number of concurrent auto-analyze operations that can run in a TiDB cluster. Before v8.4.0, this concurrency is fixed at 1. To accelerate statistics collection tasks, you can increase this concurrency based on the available resources in your cluster. +- This variable is used to set the concurrency within a single automatic statistics collection task. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. ### tidb_auto_analyze_end_time @@ -1742,7 +1742,7 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - Default value: `0` - Range: `[0, 1PiB]` - This variable limits the write bandwidth for each TiKV node and only takes effect when index creation acceleration is enabled (controlled by the [`tidb_ddl_enable_fast_reorg`](#tidb_ddl_enable_fast_reorg-new-in-v630) variable). When the data size in your cluster is quite large (such as billions of rows), limiting the write bandwidth for index creation can effectively reduce the impact on application workloads. -- The default value `0` means no write bandwidth limit. +- The default value `0` means no write bandwidth limit. - You can specify the value of this variable either with a unit or without a unit. - When you specify the value without a unit, the default unit is bytes per second. For example, `67108864` represents `64MiB` per second. - When you specify the value with a unit, supported units include KiB, MiB, GiB, and TiB. For example, `'1GiB`' represents 1 GiB per second, and `'256MiB'` represents 256 MiB per second. @@ -2578,14 +2578,6 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; -### tidb_enable_point_get_cache - -- Scope: SESSION -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): YES -- Type: Boolean -- Default value: `OFF` -- When you set the table lock type of [`LOCK TABLES`](/sql-statements/sql-statement-lock-tables-and-unlock-tables.md) to `READ`, setting this variable to `ON` enables caching of point query results, reducing the overhead of repeated queries and improving point query performance. - ### tidb_enable_prepared_plan_cache New in v6.1.0 - Scope: SESSION | GLOBAL @@ -3179,7 +3171,7 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - This variable is used to set whether to record all SQL statements in the [log](/tidb-configuration-file.md#logfile). This feature is disabled by default. If maintenance personnel needs to trace all SQL statements when locating issues, they can enable this feature. -- If the [`log.general-log-file`](/tidb-configuration-file.md#general-log-file-new-in-v800) configuration item is specified, the general log is written to the specified file separately. +- If the [`log.general-log-file`](/tidb-configuration-file.md#general-log-file-new-in-v800) configuration item is specified, the general log is written to the specified file separately. - The [`log.format`](/tidb-configuration-file.md#format) configuration item enables you to configure the log message format, whether the general log is in a separate file or combined with other logs. @@ -3550,6 +3542,7 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Default value: "" - This is a read-only variable. It is internally used in TiDB to query the transaction information of the last DML statement. The information includes: + - `txn_scope`: The scope of the transaction, which can be `global` or `local`. - `start_ts`: The start timestamp of the transaction. - `for_update_ts`: The `for_update_ts` of the previously executed DML statement. This is an internal term of TiDB used for tests. Usually, you can ignore this information. - `error`: The error message, if any. @@ -3676,7 +3669,7 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Persists to cluster: Yes - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Type: Integer -- Default value: `43200` (12 hours) +- Default value: `43200` - Range: `[0, 2147483647]` - Unit: Seconds - This variable is used to specify the maximum execution time of automatic `ANALYZE` tasks. When the execution time of an automatic `ANALYZE` task exceeds the specified time, the task will be terminated. When the value of this variable is `0`, there is no limit to the maximum execution time of automatic `ANALYZE` tasks. @@ -3786,22 +3779,6 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Range: `[100, 16384]` - This variable is used to set the maximum number of schema versions (the table IDs modified for corresponding versions) allowed to be cached. The value range is 100 ~ 16384. -### tidb_max_dist_task_nodes New in v9.0.0 - -- Scope: SESSION | GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Type: Integer -- Default value: `-1` -- Range: `-1` or `[1, 128]` -- This variable defines the maximum number of TiDB nodes that the Distributed eXecution Framework (DXF) tasks can use. The default value is `-1`, which indicates that automatic mode is enabled. In automatic mode, TiDB dynamically calculates the value as `min(3, tikv_nodes / 3)`, where `tikv_nodes` represents the number of TiKV nodes in the cluster. - -> **Note:** -> -> If you explicitly set the [`tidb_service_scope`](#tidb_service_scope-new-in-v740) system variable for some TiDB nodes, the Distributed eXecution Framework schedules tasks only to these nodes. In this case, even if you set `tidb_max_dist_task_nodes` to a larger value, the framework uses no more than the number of nodes explicitly configured with `tidb_service_scope`. -> -> For example, if the cluster has 10 TiDB nodes, and 4 of them are configured with `tidb_service_scope = group1`, then even if you set `tidb_max_dist_task_nodes = 5`, only 4 nodes participate in task execution. - ### tidb_max_paging_size New in v6.3.0 - Scope: SESSION | GLOBAL @@ -4959,22 +4936,6 @@ SHOW WARNINGS; > - This option only takes effect on statements that need to lock a single key. If a statement needs to lock multiple rows at the same time, this option will not take effect on such statements. > - This feature is introduced in v6.6.0 by the [`tidb_pessimistic_txn_aggressive_locking`](https://docs-archive.pingcap.com/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-new-in-v660) variable, which is disabled by default. -### tidb_pipelined_dml_resource_policy New in v9.0.0 - -- Scope: SESSION | GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): Yes -- Type: String -- Default value: `"standard"` -- Possible values: `"standard"`, `"conservative"`, and `"custom{...}"` -- This variable controls the resource usage policy for [Pipelined DML](/pipelined-dml.md). It takes effect only when [`tidb_dml_type`](#tidb_dml_type-new-in-v800) is set to `bulk`. The meaning of each possible value is as follows: - - `"standard"`: the default resource usage policy. - - `"conservative"`: Pipelined DML uses fewer resources, but its execution speed is slower than the default policy, suitable for scenarios with sensitive resource usage. - - `"custom{option1=value1,option2=value2,...}"`: a custom resource usage policy. You can specify only the required options. For example, `"custom{concurrency=8,write_throttle_ratio=0.5}"`. Make sure that the value is enclosed in double quotes. The supported custom options include the following: - - `concurrency`: specifies the concurrency of the flush operation, which affects the execution speed and resource usage of Pipelined DML. The value range is `[1, 8192]`. - - `resolve_concurrency`: specifies the concurrency of the asynchronous resolve lock operations. It affects the resource usage of Pipelined DML but not its execution speed. The value range is `[1, 8192]`. - - `write_throttle_ratio`: specifies the ratio of the active throttle time to the total time. The larger the value, the higher the ratio of throttle time in total time, and the more resources are saved. `0` means no throttle. The value range is `[0, 1)`. - ### tidb_placement_mode New in v6.0.0 > **Note:** @@ -6284,98 +6245,6 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - This variable is used to set the concurrency degree of the window operator. - A value of `-1` means that the value of `tidb_executor_concurrency` will be used instead. -### tidb_workload_repository_dest New in v9.0.0 - -- Scope: GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Type: String -- Default value: `''` - - - -- This variable is used to set the destination of the [Workload Repository](/workload-repository.md). -- The value can be either `'table'` (enabling the workload repository) or `''` (disabling the workload repository). - - - - - -- This variable is used to set the destination of the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository). -- The value can be either `'table'` (enabling the workload repository) or `''` (disabling the workload repository). - - - -### tidb_workload_repository_active_sampling_interval New in v9.0.0 - -- Scope: GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Type: Integer -- Default value: `5` -- Range: `[0, 600]` -- Unit: Seconds - - - -- Sets the sampling interval for the [Workload Repository](/workload-repository.md)'s time-based sampling process. -- Setting the value to `0` disables the time-based sampling process. - - - - - -- Sets the sampling interval for the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository)'s time-based sampling process. -- Setting the value to `0` disables the time-based sampling process. - - - -### tidb_workload_repository_retention_days New in v9.0.0 - -- Scope: GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Type: Integer -- Default value: `7` -- Range: `[0, 365]` -- Unit: Days - - - -- Sets the number of days that [Workload Repository](/workload-repository.md) data is retained. -- Setting the value to `0` disables automatic purging of old data. - - - - - -- Sets the number of days that [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository) data is retained. -- Setting the value to `0` disables automatic purging of old data. - - - -### tidb_workload_repository_snapshot_interval New in v9.0.0 - -- Scope: GLOBAL -- Persists to cluster: Yes -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Type: Integer -- Default value: `3600` -- Range: `[900, 7200]` -- Unit: Seconds - - - -- Sets the sampling interval for the [Workload Repository](/workload-repository.md)'s snapshot sampling process. - - - - - -- Sets the sampling interval for the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository)'s snapshot sampling process. - - - ### tiflash_fastscan New in v6.3.0 - Scope: SESSION | GLOBAL @@ -6391,7 +6260,7 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Default value: `8192` - Range: `[1, 18446744073709551615]` - When Fine Grained Shuffle is enabled, the window function pushed down to TiFlash can be executed in parallel. This variable controls the batch size of the data sent by the sender. -- Impact on performance: set a reasonable size according to your business requirements. Improper setting affects the performance. If the value is set too small, for example `1`, it causes one network transfer per Block. If the value is set too large, for example, the total number of rows of the table, it causes the receiving end to spend most of the time waiting for data, and the pipelined computation cannot work. To set a proper value, you can observe the distribution of the number of rows received by the TiFlash receiver. If most threads receive only a few rows, for example a few hundred, you can increase this value to reduce the network overhead. +- Impact on performance: set a reasonable size according to your business requirements. Improper setting affects the performance. If the value is set too small, for example `1`, it causes one network transfer per Block. If the value is set too large, for example, the total number of rows of the table, it causes the receiving end to spend most of the time waiting for data, and the piplelined computation cannot work. To set a proper value, you can observe the distribution of the number of rows received by the TiFlash receiver. If most threads receive only a few rows, for example a few hundred, you can increase this value to reduce the network overhead. ### tiflash_fine_grained_shuffle_stream_count New in v6.2.0 @@ -6539,6 +6408,19 @@ Internally, the TiDB parser transforms the `SET TRANSACTION ISOLATION LEVEL [REA - In the Stale Read scenarios, this session variable is used to help record the Stable Read timestamp value. - This variable is used for the internal operation of TiDB. It is **NOT recommended** to set this variable. +### txn_scope + +> **Note:** +> +> This variable is read-only for [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless). + +- Scope: SESSION +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Default value: `global` +- Value options: `global` and `local` +- This variable is used to set whether the current session transaction is a global transaction or a local transaction. +- This variable is used for the internal operation of TiDB. It is **NOT recommended** to set this variable. + ### validate_password.check_user_name New in v6.5.0 - Scope: GLOBAL diff --git a/three-data-centers-in-two-cities-deployment.md b/three-data-centers-in-two-cities-deployment.md index 6b473cc1d431f..6ce2d698453aa 100644 --- a/three-data-centers-in-two-cities-deployment.md +++ b/three-data-centers-in-two-cities-deployment.md @@ -179,7 +179,7 @@ In the deployment of three AZs in two regions, to optimize performance, you need > **Note:** > -> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks` before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. +> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks' before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. - Configure scheduling. After the cluster is enabled, use the `tiup ctl:v{CLUSTER_VERSION} pd` tool to modify the scheduling policy. Modify the number of TiKV Raft replicas. Configure this number as planned. In this example, the number of replicas is five. diff --git a/ticdc/ticdc-avro-protocol.md b/ticdc/ticdc-avro-protocol.md index 74d0cc0880caa..46a816fd2207e 100644 --- a/ticdc/ticdc-avro-protocol.md +++ b/ticdc/ticdc-avro-protocol.md @@ -205,7 +205,6 @@ If one column can be NULL, the Column data format can be: | ENUM | ENUM | string | - | | SET | SET | string | - | | DECIMAL | DECIMAL | bytes | When `avro-decimal-handling-mode` is string, AVRO_TYPE is string. | -| TiDBVECTORFloat32 | TiDBVECTORFloat32 | string | - | In the Avro protocol, two other `sink-uri` parameters might affect the Column data format as well: `avro-decimal-handling-mode` and `avro-bigint-unsigned-handling-mode`. diff --git a/ticdc/ticdc-canal-json.md b/ticdc/ticdc-canal-json.md index 100a9f5ff9eac..1b5151ddea5ac 100644 --- a/ticdc/ticdc-canal-json.md +++ b/ticdc/ticdc-canal-json.md @@ -213,7 +213,6 @@ In the `sqlType` field, the Canal-JSON format records Java SQL Type of each colu | Set | -7 | | Bit | -7 | | JSON | 12 | -| TiDBVectorFloat32 | 12 | ## Integer types diff --git a/ticdc/ticdc-csv.md b/ticdc/ticdc-csv.md index 40d6de9161fb8..12278eec59ca0 100644 --- a/ticdc/ticdc-csv.md +++ b/ticdc/ticdc-csv.md @@ -102,4 +102,3 @@ When `include-commit-ts = true` and `output-old-value = true`, the DML events of | `DECIMAL` | String | `"129012.1230000"` | - | | `ENUM` | String | `"a"` | - | | `SET` | String | `"a,b"` | - | -| `TiDBVectorFloat32` | String | `"[1.23, -0.4]"` | - | diff --git a/ticdc/ticdc-glossary.md b/ticdc/ticdc-glossary.md index 5f3de3a515cf2..b054da51db7db 100644 --- a/ticdc/ticdc-glossary.md +++ b/ticdc/ticdc-glossary.md @@ -5,7 +5,7 @@ summary: Learn the terms about TiCDC and their definitions. # TiCDC Glossary -This glossary provides TiCDC-related terms and definitions. These terms appear in TiCDC logs, monitoring metrics, configurations, and documents. +This glossary provides TiCDC-related terms and definitions. These terms appears in TiCDC logs, monitoring metrics, configurations, and documents. For TiDB-related terms and definitions, see [TiDB glossary](/glossary.md). diff --git a/ticdc/ticdc-manage-changefeed.md b/ticdc/ticdc-manage-changefeed.md index 1095fbc3962fe..814d55fcd7ecb 100644 --- a/ticdc/ticdc-manage-changefeed.md +++ b/ticdc/ticdc-manage-changefeed.md @@ -170,7 +170,7 @@ cdc cli changefeed resume --server=http://10.0.10.25:8300 --changefeed-id simple ``` - `--changefeed-id=uuid` represents the ID of the changefeed that corresponds to the replication task you want to resume. -- `--overwrite-checkpoint-ts`: starting from v6.2.0, you can specify the starting TSO of resuming the replication task. TiCDC starts pulling data from the specified TSO. The argument accepts `now` or a specific TSO (such as 434873584621453313). The specified TSO must be in the range of (GC safe point, CurrentTSO]. If this argument is not specified, TiCDC replicates data from the current `checkpoint-ts` by default. You can use the `cdc cli changefeed list` command to check the current value of `checkpoint-ts`. +- `--overwrite-checkpoint-ts`: starting from v6.2.0, you can specify the starting TSO of resuming the replication task. TiCDC starts pulling data from the specified TSO. The argument accepts `now` or a specific TSO (such as 434873584621453313). The specified TSO must be in the range of (GC safe point, CurrentTSO]. If this argument is not specified, TiCDC replicates data from the current `checkpoint-ts` by default. - `--no-confirm`: when the replication is resumed, you do not need to confirm the related information. Defaults to `false`. > **Note:** diff --git a/ticdc/ticdc-open-protocol.md b/ticdc/ticdc-open-protocol.md index d15a92a0b5fcf..03105a3f6e367 100644 --- a/ticdc/ticdc-open-protocol.md +++ b/ticdc/ticdc-open-protocol.md @@ -308,7 +308,6 @@ Currently, TiCDC does not provide the standard parsing library for TiCDC Open Pr | LONGTEXT/LONGBLOB | 251 | {"t":251,"v":"5rWL6K+VdGV4dA=="} | The value is encoded in Base64. | | TEXT/BLOB | 252 | {"t":252,"v":"5rWL6K+VdGV4dA=="} | The value is encoded in Base64. | | CHAR/BINARY | 254 | {"t":254,"v":"test"} / {"t":254,"v":"\\\\x89PNG\\\\r\\\\n\\\\x1a\\\\n"} | The value is encoded in UTF-8. When the upstream type is BINARY, invisible characters are escaped. | -| TiDBVectorFloat32 | 225 | {"t":225,"v":"[1.23, -0.4]"} | | | GEOMETRY | 255 | | Unsupported | ## DDL Type Code diff --git a/ticdc/ticdc-simple-protocol.md b/ticdc/ticdc-simple-protocol.md index db1ad3bc98fc6..7a3f4a03cc4af 100644 --- a/ticdc/ticdc-simple-protocol.md +++ b/ticdc/ticdc-simple-protocol.md @@ -708,7 +708,6 @@ The following table describes the value range of the `mysqlType` field in the Ti | bit | / | uint64 | long | | json | / | string | string | | bool | / | int64 | long | -| TiDBVectorFloat32 | / | string | string | ### Avro schema definition diff --git a/ticdc/ticdc-sink-to-cloud-storage.md b/ticdc/ticdc-sink-to-cloud-storage.md index 2ce91106228d3..7ef21594919a9 100644 --- a/ticdc/ticdc-sink-to-cloud-storage.md +++ b/ticdc/ticdc-sink-to-cloud-storage.md @@ -176,13 +176,7 @@ Data change records are saved to the following path: > **Note:** > -> The table version changes in the following scenarios: -> -> - The upstream TiDB performs a DDL operation on the table. -> - TiCDC schedules the table across nodes. -> - The changefeed to which the table belongs restarts. -> -> Note that the change of the table version does not mean the change of the table schema. For example, adding a comment to a column does not cause the schema file content to change. +> The table version changes only after a DDL operation is performed on the upstream table, and the new table version is the TSO when the upstream TiDB completes the execution of the DDL. However, the change of the table version does not mean the change of the table schema. For example, adding a comment to a column does not cause the schema file content to change. ### Index files diff --git a/ticdc/ticdc-sink-to-mysql.md b/ticdc/ticdc-sink-to-mysql.md index 8e2dfeed7f86b..64f8157bc74c6 100644 --- a/ticdc/ticdc-sink-to-mysql.md +++ b/ticdc/ticdc-sink-to-mysql.md @@ -176,5 +176,5 @@ cdc redo apply --tmp-dir="/tmp/cdc/redo/apply" \ In this command: - `tmp-dir`: Specifies the temporary directory for downloading TiCDC incremental data backup files. -- `storage`: Specifies the address for storing the TiCDC incremental data backup files, either a URI of object storage or an NFS directory. +- `storage`: Specifies the address for storing the TiCDC incremental data backup files, either an URI of object storage or an NFS directory. - `sink-uri`: Specifies the secondary cluster address to restore the data to. Scheme can only be `mysql`. diff --git a/tidb-cloud/high-availability-with-multi-az.md b/tidb-cloud/high-availability-with-multi-az.md index 4260fae5b4d26..1741634147c42 100644 --- a/tidb-cloud/high-availability-with-multi-az.md +++ b/tidb-cloud/high-availability-with-multi-az.md @@ -7,7 +7,7 @@ summary: TiDB Cloud supports high availability with Multi-AZ deployments. TiDB uses the Raft consensus algorithm to ensure that data is highly available and safely replicated throughout storage in Raft Groups. Data is redundantly copied between storage nodes and placed in different availability zones to protect against machine or data center failures. With automatic failover, TiDB ensures that your service is always on. -TiDB Cloud clusters consist of three major components: TiDB node, TiKV node, and TiFlash node. The high availability implementation of each component for TiDB Cloud Dedicated is as follows: +TiDB Cloud clusters consist of three major components: TiDB node, TiKV node, and TiFlash node. The highly availability implementation of each component for TiDB Cloud Dedicated is as follows: * **TiDB node** diff --git a/tidb-cloud/integrate-tidbcloud-with-n8n.md b/tidb-cloud/integrate-tidbcloud-with-n8n.md index eb4a615bb2070..bf5fb005b2014 100644 --- a/tidb-cloud/integrate-tidbcloud-with-n8n.md +++ b/tidb-cloud/integrate-tidbcloud-with-n8n.md @@ -140,7 +140,7 @@ This trigger will execute your workflow every morning at 8 AM. 1. Click **+** to the right of the RSS Read node. 2. Search `TiDB Cloud` and add it to the workspace. -3. Select the credentials that you entered the previous TiDB Cloud node. +3. Select the credentials that you entered in the previous TiDB Cloud node. 4. In the **Project** list, select your project. 5. In the **Operation** list, select `Insert`. 6. In **Cluster**, **User**, **Database** and **Password** boxes, enter the corresponding values. diff --git a/tidb-cloud/limited-sql-features.md b/tidb-cloud/limited-sql-features.md index 96d63fc7d2ca9..455d756445c26 100644 --- a/tidb-cloud/limited-sql-features.md +++ b/tidb-cloud/limited-sql-features.md @@ -205,6 +205,7 @@ TiDB Cloud works with almost all workloads that TiDB supports, but there are som | `tidb_txn_mode` | No limitation | Read-only [^10] | | `tidb_wait_split_region_finish` | No limitation | Read-only [^10] | | `tidb_wait_split_region_timeout` | No limitation | Read-only [^10] | +| `txn_scope` | No limitation | Read-only [^10] | | `validate_password.enable` | No limitation | Always enabled [^9] | | `validate_password.length` | No limitation | At least `8` [^9] | | `validate_password.mixed_case_count` | No limitation | At least `1` [^9] | diff --git a/tidb-cloud/ticloud-config-edit.md b/tidb-cloud/ticloud-config-edit.md index be5a2c24962ac..83389b8c148db 100644 --- a/tidb-cloud/ticloud-config-edit.md +++ b/tidb-cloud/ticloud-config-edit.md @@ -15,7 +15,7 @@ If you are using Windows, after you execute the preceding command, the path of t > **Note:** > -> To avoid format errors and execution failures, it is NOT recommended to manually edit the configuration file. Instead, you can use [`ticloud config create`](/tidb-cloud/ticloud-config-create.md), [`ticloud config delete`](/tidb-cloud/ticloud-config-delete.md), or [`ticloud config set`](/tidb-cloud/ticloud-config-set.md) to modify the configurations. +> To avoid format errors and execution failures, it is NOT recommended to manually edit the configuration file. Instead, you can use [`ticloud config create`](/tidb-cloud/ticloud-config-create.md), [`ticloud config delete`](/tidb-cloud/ticloud-config-delete.md), or [`ticloud config set`](/tidb-cloud/ticloud-config-set.md) to modify the confiturations. ## Examples diff --git a/tidb-cloud/troubleshoot-import-access-denied-error.md b/tidb-cloud/troubleshoot-import-access-denied-error.md index 4a861ce6ee0ac..d418157f2f5cd 100644 --- a/tidb-cloud/troubleshoot-import-access-denied-error.md +++ b/tidb-cloud/troubleshoot-import-access-denied-error.md @@ -229,7 +229,7 @@ To solve the `AccessDenied` error in this situation, click the key ARN or manual > **Note:** > -> If the objects in your bucket have been copied from an existing encrypted bucket, you also need to include the key of the source bucket in the AWS KMS key ARN. This is because the objects in your bucket use the same encryption method as the source object encryption. For more information, see the AWS document [Using default encryption with replication](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html). +> If the objects in your bucket have been copied from an existing encrypted bucket, you also need to include the key of the source bucket in the AWS KMS key ARN. This is because the objects in the your bucket use the same encryption method as the source object encryption. For more information, see the AWS document [Using default encryption with replication](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html). ### Check the AWS article for instruction diff --git a/tidb-configuration-file.md b/tidb-configuration-file.md index 7ff5e9b48cdf6..22dbd2d5c288c 100644 --- a/tidb-configuration-file.md +++ b/tidb-configuration-file.md @@ -261,7 +261,7 @@ The TiDB configuration file supports more options than command-line parameters. > **Note:** > -> - In TiDB, the `zone` label is specially used to specify the zone where a server is located. If `zone` is set to a non-null value, the corresponding value is automatically used by [`Follower read`](/follower-read.md). +> - In TiDB, the `zone` label is specially used to specify the zone where a server is located. If `zone` is set to a non-null value, the corresponding value is automatically used by features such as [`txn-score`](/system-variables.md#txn_scope) and [`Follower read`](/follower-read.md). > - The `group` label has a special use in TiDB Operator. For clusters deployed using [TiDB Operator](/tidb-operator-overview.md), it is **NOT** recommended that you specify the `group` label manually. ## log @@ -828,7 +828,7 @@ Configuration related to the status of TiDB service. ### `record-db-label` - Determines whether to transmit the database-related QPS metrics to Prometheus. -- Supports more metrics types than `record-db-qps`, for example, duration and statements. +- Supports more metircs types than `record-db-qps`, for example, duration and statements. - Default value: `false` ## pessimistic-txn diff --git a/tidb-control.md b/tidb-control.md index 8822a5f1ecaef..36bb981b1b9e4 100644 --- a/tidb-control.md +++ b/tidb-control.md @@ -179,7 +179,7 @@ tidb-ctl base64decode [table_id] [base64_data] alter table t add column e varchar(20); ``` -2. Obtain MVCC data using the HTTP API interface: +2. Obtian MVCC data using the HTTP API interface: ```shell $ curl "http://$IP:10080/mvcc/index/test/t/a/1?a=1" diff --git a/tidb-monitoring-framework.md b/tidb-monitoring-framework.md index 786d25d70bdac..ea91beabaeaa0 100644 --- a/tidb-monitoring-framework.md +++ b/tidb-monitoring-framework.md @@ -1,12 +1,12 @@ --- title: TiDB Monitoring Framework Overview -summary: Use Prometheus, Grafana, and TiDB Dashboard to build the TiDB monitoring framework. +summary: Use Prometheus and Grafana to build the TiDB monitoring framework. aliases: ['/docs/dev/tidb-monitoring-framework/','/docs/dev/how-to/monitor/overview/'] --- # TiDB Monitoring Framework Overview -The TiDB monitoring framework adopts two open source projects: Prometheus and Grafana. TiDB uses [Prometheus](https://prometheus.io) to store the monitoring and performance metrics and [Grafana](https://grafana.com/grafana) to visualize these metrics. TiDB also provides a built-in [TiDB Dashboard](/dashboard/dashboard-intro.md) for monitoring and diagnosing TiDB clusters. +The TiDB monitoring framework adopts two open source projects: Prometheus and Grafana. TiDB uses [Prometheus](https://prometheus.io) to store the monitoring and performance metrics and [Grafana](https://grafana.com/grafana) to visualize these metrics. ## About Prometheus in TiDB @@ -51,7 +51,3 @@ Grafana is an open source project for analyzing and visualizing metrics. TiDB us Each group has multiple panel labels of monitoring metrics, and each panel contains detailed information of multiple monitoring metrics. For example, the **Overview** monitoring group has five panel labels, and each labels corresponds to a monitoring panel. See the following UI: ![Grafana Overview](/media/grafana-monitor-overview.png) - -## TiDB Dashboard - -TiDB Dashboard is a web UI for monitoring, diagnosing, and managing the TiDB cluster, which is introduced in v4.0. It is built into the PD component and does not require an independent deployment. For more information, see [TiDB Dashboard introduction](/dashboard/dashboard-intro.md). diff --git a/tidb-resource-control-ru-groups.md b/tidb-resource-control-ru-groups.md index 3fdd338db65bd..21bd38f973b07 100644 --- a/tidb-resource-control-ru-groups.md +++ b/tidb-resource-control-ru-groups.md @@ -333,11 +333,11 @@ Example: ``` ``` - +---------------------------------------------------------------------------------------------------+ - | @@tidb_last_query_info | - +---------------------------------------------------------------------------------------------------+ - | {"start_ts":446809472210829315,"for_update_ts":446809472210829315,"ru_consumption":4.34885578125} | - +---------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------------------+ + | @@tidb_last_query_info | + +------------------------------------------------------------------------------------------------------------------------+ + | {"txn_scope":"global","start_ts":446809472210829315,"for_update_ts":446809472210829315,"ru_consumption":4.34885578125} | + +------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) ``` diff --git a/tidb-troubleshooting-map.md b/tidb-troubleshooting-map.md index b85ee4e0762f9..7112cf9f0d31e 100644 --- a/tidb-troubleshooting-map.md +++ b/tidb-troubleshooting-map.md @@ -267,7 +267,7 @@ Check the specific cause for busy by viewing the monitor **Grafana** -> **TiKV** - `append log duration` is high, which causes slow processing of messages. You can refer to [4.5](#45-tikv-write-is-slow) to analyze why `append log duration` is high. - raftstore receives a large batch of messages in an instant (check in the TiKV Raft messages dashboard), and fails to process them. Usually the short-term `channel full` status does not affect the service. -- 4.3.4 TiKV coprocessor is in a queue. The number of piled up tasks exceeds `coprocessor threads * readpool.coprocessor.max-tasks-per-worker-[normal|low|high]`. Too many large queries leads to the tasks piling up in coprocessor. You need to check whether an execution plan change causes a large number of table scan operations. Refer to [3.3](#33-wrong-execution-plan). +- 4.3.4 TiKV coprocessor is in a queue. The number of piled up tasks exceeds `coprocessor threads * readpool.coprocessor.max-tasks-per-worker-[normal|low|high]`. Too many large queries leads to the tasks piling up in coprocessor. You need to check whether a execution plan change causes a large number of table scan operations. Refer to [3.3](#33-wrong-execution-plan). ### 4.4 Some TiKV nodes drop Leader frequently diff --git a/tiflash-upgrade-guide.md b/tiflash-upgrade-guide.md index 3425ffff49247..ad7c9000a168f 100644 --- a/tiflash-upgrade-guide.md +++ b/tiflash-upgrade-guide.md @@ -65,7 +65,7 @@ When you upgrade TiFlash from v5.x or v6.0 to v6.1, pay attention to the functio TiFlash Proxy is upgraded in v6.1.0 (aligned with TiKV v6.0.0). The new version has upgraded the RocksDB version. After you upgrade TiFlash to v6.1, the data format is converted to the new version automatically. -In regular upgrades, the data conversion does not involve any risks. However, if you need to downgrade TiFlash from v6.1 to any earlier version in special scenarios (for example, testing or verification scenarios), the earlier version might fail to parse the new RocksDB configuration. As result, TiFlash will fail to restart. It is recommended that you fully test and verify the upgrade process and prepare an emergency plan. +In regular upgrades, the data conversion does not involve any risks. However, if you need to downgrade TiFlash from v6.1 to any earlier version in special scenarios (for example, testing or verification scenarios), the earlier version might fail to parse the new RocksDB configuration. As as result, TiFlash will fail to restart. It is recommended that you fully test and verify the upgrade process and prepare an emergency plan. **Workaround for downgrading TiFlash in testing or other special scenarios** @@ -128,10 +128,6 @@ Starting from v7.4, to reduce the read and write amplification generated during Starting from v8.4, the underlying storage format of TiFlash is updated to support [vector search](/vector-search/vector-search-overview.md). Therefore, after TiFlash is upgraded to v8.4 or a later version, in-place downgrading to the original version is not supported. -## From v8.x to v9.0 or a later version - -Starting from v9.0.0, TiFlash optimizes the storage format of string data to improve the string read and write performance. Therefore, after TiFlash is upgraded to v9.0.0 or a later version, in-place downgrading to the original version is not supported. - **Workaround for downgrading TiFlash in testing or other special scenarios** To downgrade TiFlash in testing or other special scenarios, you can forcibly scale in the target TiFlash node and then replicate data from TiKV again. For detailed steps, see [Scale in a TiFlash cluster](/scale-tidb-using-tiup.md#scale-in-a-tiflash-cluster). diff --git a/tiflash/tiflash-overview.md b/tiflash/tiflash-overview.md index c7e5a8e06cfbb..ffce1d3373b38 100644 --- a/tiflash/tiflash-overview.md +++ b/tiflash/tiflash-overview.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/tiflash/tiflash-overview/','/docs/dev/reference/tiflash/ove # TiFlash Overview -[TiFlash](https://github.com/pingcap/tiflash) is the key component that makes TiDB essentially a Hybrid Transactional/Analytical Processing (HTAP) database. As a columnar storage extension of TiKV, TiFlash provides both good isolation level and strong consistency guarantee. +[TiFlash](https://github.com/pingcap/tiflash) is the key component that makes TiDB essentially an Hybrid Transactional/Analytical Processing (HTAP) database. As a columnar storage extension of TiKV, TiFlash provides both good isolation level and strong consistency guarantee. In TiFlash, the columnar replicas are asynchronously replicated according to the Raft Learner consensus algorithm. When these replicas are read, the Snapshot Isolation level of consistency is achieved by validating Raft index and multi-version concurrency control (MVCC). diff --git a/tikv-configuration-file.md b/tikv-configuration-file.md index 9c132d69eff77..7ec9e0937b6e7 100644 --- a/tikv-configuration-file.md +++ b/tikv-configuration-file.md @@ -427,7 +427,7 @@ Configuration items related to storage. > > This feature is experimental. It is not recommended that you use it in the production environment. This feature might be changed or removed without prior notice. If you find a bug, you can report an [issue](https://github.com/pingcap/tidb/issues) on GitHub. -+ Specifies the engine type. This configuration can only be specified when creating a new cluster and cannot be modified once being specified. ++ Specifies the engine type. This configuration can only be specified when creating a new cluster and cannot be modifies once being specified. + Default value: `"raft-kv"` + Value options: diff --git a/tiproxy/tiproxy-command-line-flags.md b/tiproxy/tiproxy-command-line-flags.md index ab75c0fcad55a..7f4f00b2d7549 100644 --- a/tiproxy/tiproxy-command-line-flags.md +++ b/tiproxy/tiproxy-command-line-flags.md @@ -165,8 +165,6 @@ Options: - `--output`: (required) specifies the directory to store traffic files. - `--duration`: (required) specifies the duration of capture. The unit is one of `m` (minutes), `h` (hours), or `d` (days). For example, `--duration=1h` captures traffic for one hour. -- `--compress`: (optional) specifies whether to compress traffic files. `true` means compression, and the compression format is gzip. `false` means no compression. The default value is `true`. -- `--encryption-method`: (optional) specifies the algorithm for encrypting traffic files. Only `""`, `plaintext`, and `aes256-ctr` are supported. `""` and `plaintext` indicate no encryption, and `aes256-ctr` indicates encryption using the `AES256-CTR` algorithm. When specifying encryption, you also need to configure [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path). The default value is `""`. Example: @@ -183,10 +181,9 @@ The `tiproxyctl traffic replay` command is used to replay captured traffic. Options: - `--username`: (required) specifies the database username for replay. -- `--password`: (optional) specifies the password for the username. If not specified, you need to enter the password in an interactive mode. +- `--password`: (optional) specifies the password for the username. The default value is an empty string `""`. - `--input`: (required) specifies the directory containing traffic files. - `--speed`: (optional) specifies the replay speed multiplier. The range is `[0.1, 10]`. The default value is `1`, indicating replay at the original speed. -- `--read-only`: (optional) specifies whether to replay only read-only SQL statements. `true` means to replay only read-only SQL statements, and `false` means to replay all SQL statements. The default value is `false`. Example: @@ -198,26 +195,17 @@ tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --passwor #### `traffic cancel` -The `tiproxyctl traffic cancel` command is used to cancel the current capture or replay job. +The `tiproxyctl traffic cancel` command is used to cancel the current capture or replay task. #### `traffic show` -The `tiproxyctl traffic show` command is used to display historical capture and replay jobs. It outputs an array of objects, and each object represents a job. Each job has the following fields: - -- `type`: the job type. `capture` indicates a traffic capture job, `replay` indicates a traffic replay job -- `status`: the current status of the job. `running` indicates in progress, `done` indicates normal completion, and `canceled` indicates job failure. -- `start_time`: the start time of the job -- `end_time`: the end time if the job has completed. Otherwise, it is empty. -- `progress`: the completion percentage of the job -- `error`: if the job fails, this column contains the reason for the failure. Otherwise, it is empty. For example, `manually stopped` means the user manually cancels the job by executing `CANCEL TRAFFIC JOBS`. -- `output`: the output traffic file path of the capture job -- `duration`: the duration of the traffic capture job -- `compress`: whether the traffic files are compressed -- `encryption_method`: the encryption method of the traffic file -- `input`: the input traffic file path of the replay job -- `username`: the database username for traffic replay -- `speed`: the replay speed multiplier -- `read_only`: whether only replays read-only statements +The `tiproxyctl traffic show` command is used to display historical capture and replay tasks. + +The `status` field in the output indicates the task status, with the following possible values: + +- `done`: the task completed normally. +- `canceled`: the task was canceled. You can check the `error` field for the reason. +- `running`: the task is running. You can check the `progress` field for the completion percentage. Example output: @@ -225,31 +213,30 @@ Example output: [ { "type": "capture", - "status": "done", "start_time": "2024-09-01T14:30:40.99096+08:00", "end_time": "2024-09-01T16:30:40.99096+08:00", - "progress": "100%", - "output": "/tmp/traffic", "duration": "2h", - "compress": true + "output": "/tmp/traffic", + "progress": "100%", + "status": "done" }, { "type": "capture", - "status": "canceled", "start_time": "2024-09-02T18:30:40.99096+08:00", "end_time": "2024-09-02T19:00:40.99096+08:00", - "progress": "25%", - "error": "manually stopped", + "duration": "2h", "output": "/tmp/traffic", - "duration": "2h" + "progress": "25%", + "status": "canceled", + "error": "canceled manually" }, { "type": "capture", - "status": "running", "start_time": "2024-09-03T13:31:40.99096+08:00", - "progress": "45%", + "duration": "2h", "output": "/tmp/traffic", - "duration": "2h" + "progress": "45%", + "status": "running" } ] ``` diff --git a/tiproxy/tiproxy-configuration.md b/tiproxy/tiproxy-configuration.md index 4e9084af3fde6..28bbdcabd4cc7 100644 --- a/tiproxy/tiproxy-configuration.md +++ b/tiproxy/tiproxy-configuration.md @@ -128,13 +128,6 @@ Configurations for the load balancing policy of TiProxy. + Possible values: `resource`, `location`, `connection` + Specifies the load balancing policy. For the meaning of each possible value, see [TiProxy load balancing policies](/tiproxy/tiproxy-load-balance.md#configure-load-balancing-policies). -### `enable-traffic-replay` - -+ Default value: `true` -+ Support hot-reload: yes -+ Possible values: `true`, `false` -+ Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. - ### ha High availability configurations for TiProxy. @@ -143,7 +136,7 @@ High availability configurations for TiProxy. + Default value: `""` + Support hot-reload: no -+ Specifies the virtual IP address in the CIDR format, such as `"10.0.1.10/24"`. When multiple TiProxy instances in a cluster are configured with the same virtual IP, only one TiProxy instance will be bound to the virtual IP. If this instance goes offline, another TiProxy instance will automatically bind to the IP, ensuring clients can always connect to an available TiProxy through the virtual IP. ++ Specifies the virtual IP address in the CIDR format, such as `"10.0.1.10/24"`. In a cluster with multiple TiProxy instances, only one instance binds to the virtual IP. If this instance goes offline, another TiProxy instance will automatically bind to the IP, ensuring clients can always connect to an available TiProxy through the virtual IP. The following is an example configuration: @@ -154,8 +147,6 @@ server_configs: ha.interface: "eth0" ``` -When you need to isolate computing layer resources, you can configure multiple virtual IP addresses and use [label-based load balancing](/tiproxy/tiproxy-load-balance.md#label-based-load-balancing) in combination. For examples, see [label-based load balancing](/tiproxy/tiproxy-load-balance.md#label-based-load-balancing). - > **Note:** > > - Virtual IP is only supported on Linux operating systems. @@ -238,7 +229,6 @@ TLS object fields: + `ca`: specifies the CA + `cert`: specifies the certificate + `key`: specifies the private key -+ `cert-allowed-cn`: when other components connect to TiProxy with TLS, TiProxy can prevent unauthorized access by verifying the `Common Name` in the caller's certificate. This item specifies a list of `Common Name` of valid callers. After setting this item, this TLS object must enable TLS; otherwise, the item does not take effect. For more information on verifying component caller's identity, see [verify component caller's identity](/enable-tls-between-components.md#verify-component-callers-identity). + `auto-certs`: mostly used for tests. It generates certificates if no certificate or key is specified. + `skip-ca`: skips verifying certificates using CA on client object or skips server-side verification on server object. + `min-tls-version`: sets the minimum TLS version. Possible values are `1.0`、`1.1`、`1.2`, and `1.3`. The default value is `1.2`, which allows v1.2 or higher TLS versions. @@ -251,7 +241,7 @@ For client TLS object: - You must set either `ca` or `skip-ca` to skip verifying server certificates. - Optionally, you can set `cert` or `key` to pass server-side client verification. -- Useless fields: `cert-allowed-cn`, `auto-certs`, `rsa-key-size`, `autocert-expire-duration`. +- Useless fields: auto-certs. For server TLS object: @@ -262,16 +252,6 @@ For server TLS object: A client TLS object. It is used to access TiDB or PD. -#### `encryption-key-path` - -+ Default value: `""` -+ Support hot-reload: yes -+ Specifies the file path of the key used to encrypt the traffic files during traffic capture. The TiProxy instance used for replay needs to be configured with the same key file. The file must contain a 256-bit (32-byte) hexadecimal string with no additional content. An example of the file content is as follows: - -``` -3b5896b5be691006e0f71c3040a2949 -``` - #### `require-backend-tls` + Default value: `false` diff --git a/tiproxy/tiproxy-load-balance.md b/tiproxy/tiproxy-load-balance.md index 583a1e8986ba9..29a8d706eea10 100644 --- a/tiproxy/tiproxy-load-balance.md +++ b/tiproxy/tiproxy-load-balance.md @@ -38,11 +38,10 @@ After configuration, TiProxy uses the label name specified in `balance.label-nam Consider an application that handles both transaction and BI workloads. To prevent these workloads from interfering with each other, configure your cluster as follows: 1. Set [`balance.label-name`](/tiproxy/tiproxy-configuration.md#label-name) to `"app"` in TiProxy, indicating that TiDB servers will be matched by the label name `"app"`, and connections will be routed to TiDB servers with matching label values. -2. Deploy at least two TiProxy instances. Configure the TiProxy instance used for transaction business with [`labels`](/tiproxy/tiproxy-configuration.md#labels) as `{"app"="Order"}`, and the instance used for BI business with [`labels`](/tiproxy/tiproxy-configuration.md#labels) as `{"app"="BI"}`. -3. If high availability of TiProxy is required, deploy at least four TiProxy instances, and configure different virtual IP addresses for different businesses. For example, configure two TiProxy instances used for transaction business with virtual IP `10.0.1.10/24`, and two TiProxy instances used for BI business with virtual IP `10.0.1.20/24`. -4. Divide TiDB instances into two groups, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tidb-configuration-file.md#labels) configuration items. -5. Optional: For storage layer isolation, configure [Placement Rules](/configure-placement-rules.md) or [Resource Control](/tidb-resource-control-ru-groups.md). -6. Direct transaction and BI clients to connect to their respective virtual IP addresses. +2. Configure two TiProxy instances, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tiproxy/tiproxy-configuration.md#labels) configuration items. +3. Divide TiDB instances into two groups, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tidb-configuration-file.md#labels) configuration items. +4. Optional: For storage layer isolation, configure [Placement Rules](/configure-placement-rules.md) or [Resource Control](/tidb-resource-control-ru-groups.md). +5. Direct transaction and BI clients to connect to their respective TiProxy instance addresses. Label-based Load Balancing @@ -51,54 +50,35 @@ Example configuration for this topology: ```yaml component_versions: tiproxy: "v1.1.0" - server_configs: tiproxy: balance.label-name: "app" tidb: graceful-wait-before-shutdown: 15 - tiproxy_servers: - host: tiproxy-host-1 config: - labels: {"app": "Order"} - ha.virtual-ip: "10.0.1.10/24" - ha.interface: "eth0" + labels: {app: "Order"} - host: tiproxy-host-2 config: - labels: {"app": "Order"} - ha.virtual-ip: "10.0.1.10/24" - ha.interface: "eth0" - - host: tiproxy-host-3 - config: - labels: {"app": "BI"} - ha.virtual-ip: "10.0.1.20/24" - ha.interface: "eth0" - - host: tiproxy-host-4 - config: - labels: {"app": "BI"} - ha.virtual-ip: "10.0.1.20/24" - ha.interface: "eth0" - + labels: {app: "BI"} tidb_servers: - host: tidb-host-1 config: - labels: {"app": "Order"} + labels: {app: "Order"} - host: tidb-host-2 config: - labels: {"app": "Order"} + labels: {app: "Order"} - host: tidb-host-3 config: - labels: {"app": "BI"} + labels: {app: "BI"} - host: tidb-host-4 config: - labels: {"app": "BI"} - + labels: {app: "BI"} tikv_servers: - host: tikv-host-1 - host: tikv-host-2 - host: tikv-host-3 - pd_servers: - host: pd-host-1 - host: pd-host-2 diff --git a/tiproxy/tiproxy-traffic-replay.md b/tiproxy/tiproxy-traffic-replay.md index e453db837651a..1a0e93d494b56 100644 --- a/tiproxy/tiproxy-traffic-replay.md +++ b/tiproxy/tiproxy-traffic-replay.md @@ -5,7 +5,11 @@ summary: Introduce the use cases and steps for the TiProxy traffic replay featur # TiProxy Traffic Replay -Starting from TiProxy v1.3.0, you can use TiProxy to capture access traffic in a TiDB production cluster and replay it in a test cluster at a specified rate. This feature enables you to reproduce actual workloads from the production cluster in a test environment, verifying SQL statement execution results and performance. Starting from v1.4.0, the TiProxy traffic replay feature becomes generally available (GA). +> **Warning:** +> +> Currently, the TiProxy traffic replay feature is experimental. It is not recommended that you use it in production environments. This feature might be changed or removed without prior notice. If you find a bug, you can report an [issue](https://github.com/pingcap/tiproxy/issues) on GitHub. + +Starting from TiProxy v1.3.0, you can use TiProxy to capture access traffic in a TiDB production cluster and replay it in a test cluster at a specified rate. This feature enables you to reproduce actual workloads from the production cluster in a test environment, verifying SQL statement execution results and performance. TiProxy traffic replay @@ -25,60 +29,6 @@ Traffic replay is not suitable for the following scenarios: ## Usage -Before TiDB v9.0.0, only `tiproxyctl` is supported to connect to TiProxy for traffic capture and replay. Starting from TiDB v9.0.0, it is recommended to use SQL statements to capture and replay traffic. - - -
- -1. Prepare the test environment: - - 1. Create a test cluster. For more information, see [Deploy a TiDB Cluster Using TiUP](/production-deployment-using-tiup.md). - 2. Replicate data from the production cluster to the test cluster. For more information, see [Data Migration Overview](/migration-overview.md). - 3. Run the [`ANALYZE`](/sql-statements/sql-statement-analyze-table.md) statement in the test cluster to update statistics. - -2. Use the [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) statement to capture traffic. - - TiProxy supports capturing traffic to local and external storage. When capturing traffic to local, you need to manually copy the traffic file to the TiProxy cluster for replay after capturing the traffic, but when using external storage, there is no need to manually copy. TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, or other S3-compatible file storage services. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). - - To capture traffic, the current user must have the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - - > **Note:** - > - > - TiProxy captures traffic on all connections, including existing and newly created ones. - > - The higher the CPU usage of TiProxy, the greater the impact of traffic capture on QPS. To reduce the impact on the production cluster, it is recommended to reserve at least 30% of CPU capacity, which results in an approximately 3% decrease in average QPS. For detailed performance data, see [Traffic capture test](/tiproxy/tiproxy-performance-test.md#traffic-capture-test). - > - TiProxy does not automatically delete previous capture files when capturing traffic again. You need to manually delete them. - - For example, the following statement enables all TiProxy instances to capture traffic for one hour and save the traffic to the `/tmp/traffic` directory of each TiProxy instance: - - ```sql - TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1h" - ``` - - Traffic files are automatically rotated and compressed. For more options, see [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md). - -3. If the traffic files are captured to the TiProxy local storage, copy the traffic file directory to the TiProxy instances in the test cluster. - -4. Use the [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) statement to replay traffic. - - Replaying traffic requires the current user to have the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - - By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load. - - For example, the following statement connects to all TiProxy instances with username `u1` and password `123456`, reads the traffic files from the `/tmp/traffic` directory of each instance, and replays the traffic: - - ```sql - TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" - ``` - - Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. If the production cluster has a [resource group](/tidb-resource-control-ru-groups.md#manage-resource-groups), TiProxy automatically sets the resource group of each session to the same as when it was captured. Therefore, configure the [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) [privilege](/sql-statements/sql-statement-set-resource-group.md#privilege) for `u1`. - - If you replay all statements, before replaying again, you may need to restore the data to before the last replay to avoid errors caused by data duplication. You can also add the `READ_ONLY=true` option to replay only read-only statements to avoid restoring data before each replay. - - For more information, see [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md). - -
-
- 1. Prepare the test environment: 1. Create a test cluster. For more information, see [Deploy a TiDB Cluster Using TiUP](/production-deployment-using-tiup.md). @@ -88,12 +38,11 @@ Before TiDB v9.0.0, only `tiproxyctl` is supported to connect to TiProxy for tra 2. Use the [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture) command to connect to the production cluster's TiProxy instance and start capturing traffic. - TiProxy supports capturing traffic to local and external storage. When capturing traffic to local, you need to manually copy the traffic file to the TiProxy cluster for replay after capturing the traffic, but when using external storage, there is no need to manually copy. TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, or other file storage services that implement the S3 protocol. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). - > **Note:** > > - TiProxy captures traffic on all connections, including existing and newly created ones. - > - If TiProxy is configured with a virtual IP, it is recommended to connect to the virtual IP address. If there are multiple active TiProxy instances, connect to each TiProxy instance to execute. + > - In TiProxy primary-secondary mode, connect to the primary TiProxy instance. + > - If TiProxy is configured with a virtual IP, it is recommended to connect to the virtual IP address. > - The higher the CPU usage of TiProxy, the greater the impact of traffic capture on QPS. To reduce the impact on the production cluster, it is recommended to reserve at least 30% of CPU capacity, which results in an approximately 3% decrease in average QPS. For detailed performance data, see [Traffic capture test](/tiproxy/tiproxy-performance-test.md#traffic-capture-test). > - TiProxy does not automatically delete previous capture files when capturing traffic again. You need to manually delete them. @@ -103,12 +52,19 @@ Before TiDB v9.0.0, only `tiproxyctl` is supported to connect to TiProxy for tra tiproxyctl traffic capture --host 10.0.1.10 --port 3080 --output="/tmp/traffic" --duration=1h ``` - Traffic files are automatically rotated and compressed. For more options, see [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture). + Traffic files are automatically rotated and compressed. Example files in the `/tmp/traffic` directory: + + ```shell + ls /tmp/traffic + # meta traffic-2024-08-29T17-37-12.477.log.gz traffic-2024-08-29T17-43-11.166.log.gz traffic.log + ``` + + For more information, see [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture). -3. If the traffic files are captured to the TiProxy local storage, copy the traffic file directory to the TiProxy instances in the test cluster. +3. Copy the traffic file directory to the test cluster's TiProxy instance. 4. Use [`tiproxyctl traffic replay`](/tiproxy/tiproxy-command-line-flags.md#traffic-replay) to connect to the test cluster's TiProxy instance and start replaying traffic. - By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load. + By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load and ensure consistent transaction execution order. For example, the following command connects to the TiProxy instance at `10.0.1.10:3080` using username `u1` and password `123456`, reads traffic files from the `/tmp/traffic` directory on the TiProxy instance, and replays the traffic: @@ -116,94 +72,72 @@ Before TiDB v9.0.0, only `tiproxyctl` is supported to connect to TiProxy for tra tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --password="123456" --input="/tmp/traffic" ``` - Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. If the production cluster has a [resource group](/tidb-resource-control-ru-groups.md#manage-resource-groups), TiProxy automatically sets the resource group of each session to the same as when it was captured. Therefore, configure the [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) [privilege](/sql-statements/sql-statement-set-resource-group.md#privilege) for `u1`. - - If you replay all statements, before replaying again, you might need to restore the data to before the last replay to avoid errors caused by data duplication. You can also add the `--read-only=true` option to replay only read-only statements to avoid restoring data before each replay. + Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. For more information, see [`tiproxyctl traffic replay`](/tiproxy/tiproxy-command-line-flags.md#traffic-replay). -
-
- -## View the replay report +5. View the replay report. -After replay completion, the report is stored in the `tiproxy_traffic_replay` database on the test cluster. This database contains two tables: `fail` and `other_errors`. + After replay completion, the report is stored in the `tiproxy_traffic_replay` database on the test cluster. This database contains two tables: `fail` and `other_errors`. -The `fail` table stores failed SQL statements, with the following fields: + The `fail` table stores failed SQL statements, with the following fields: -- `replay_start_time`: the start time of the replay job, which is used to uniquely identify a replay job. It can be used to filter replay jobs. -- `cmd_type`: the type of a failed command, such as `Query` (execute an ordinary statement), `Prepare` (prepare a statement), and `Execute` (execute a prepared statement). -- `digest`: the digest of the failed SQL statement. -- `sample_stmt`: the SQL text when the statement first failed. -- `sample_err_msg`: the error message when the SQL statement failed. -- `sample_conn_id`: the connection ID recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. -- `sample_capture_time`: the execution time recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. -- `sample_replay_time`: the time when the SQL statement failed during replay. You can use this to view error information in the TiDB log file. -- `count`: the number of times the SQL statement failed. + - `cmd_type`: the type of a failed command, such as `Query` (execute an ordinary statement), `Prepare` (prepare a statement), and `Execute` (execute a prepared statement). + - `digest`: the digest of the failed SQL statement. + - `sample_stmt`: the SQL text when the statement first failed. + - `sample_err_msg`: the error message when the SQL statement failed. + - `sample_conn_id`: the connection ID recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. + - `sample_capture_time`: the execution time recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. + - `sample_replay_time`: the time when the SQL statement failed during replay. You can use this to view error information in the TiDB log file. + - `count`: the number of times the SQL statement failed. -The following is an example output of the `fail` table: + The following is an example output of the `fail` table: -```sql -SELECT * FROM tiproxy_traffic_replay.fail LIMIT 1\G -``` + ```sql + SELECT * FROM tiproxy_traffic_replay.fail LIMIT 1\G + ``` -``` -*************************** 1. row *************************** - replay_start_time: 2024-10-17 13:05:03 - cmd_type: StmtExecute - digest: 89c5c505772b8b7e8d5d1eb49f4d47ed914daa2663ed24a85f762daa3cdff43c - sample_stmt: INSERT INTO new_order (no_o_id, no_d_id, no_w_id) VALUES (?, ?, ?) params=[3077 6 1] - sample_err_msg: ERROR 1062 (23000): Duplicate entry '1-6-3077' for key 'new_order.PRIMARY' - sample_conn_id: 1356 -sample_capture_time: 2024-10-17 12:59:15 - sample_replay_time: 2024-10-17 13:05:05 - count: 4 -``` + ``` + *************************** 1. row *************************** + cmd_type: StmtExecute + digest: 89c5c505772b8b7e8d5d1eb49f4d47ed914daa2663ed24a85f762daa3cdff43c + sample_stmt: INSERT INTO new_order (no_o_id, no_d_id, no_w_id) VALUES (?, ?, ?) params=[3077 6 1] + sample_err_msg: ERROR 1062 (23000): Duplicate entry '1-6-3077' for key 'new_order.PRIMARY' + sample_conn_id: 1356 + sample_capture_time: 2024-10-17 12:59:15 + sample_replay_time: 2024-10-17 13:05:05 + count: 4 + ``` -The `other_errors` table stores unexpected errors, such as network errors or database connection errors, with the following fields: + The `other_errors` table stores unexpected errors, such as network errors or database connection errors, with the following fields: -- `replay_start_time`: the start time of the replay job, which is used to uniquely identify a replay job. It can be used to filter replay jobs. -- `err_type`: the type of error, presented as a brief error message. For example, `i/o timeout`. -- `sample_err_msg`: the complete error message when the error first occurred. -- `sample_replay_time`: the time when the error occurred during replay. You can use this to view error information in the TiDB log file. -- `count`: the number of occurrences for this error. + - `err_type`: the type of error, presented as a brief error message. For example, `i/o timeout`. + - `sample_err_msg`: the complete error message when the error first occurred. + - `sample_replay_time`: the time when the error occurred during replay. You can use this to view error information in the TiDB log file. + - `count`: the number of occurrences for this error. -The following is an example output of the `other_errors` table: + The following is an example output of the `other_errors` table: -```sql -SELECT * FROM tiproxy_traffic_replay.other_errors LIMIT 1\G -``` + ```sql + SELECT * FROM tiproxy_traffic_replay.other_errors LIMIT 1\G + ``` -``` -*************************** 1. row *************************** - replay_start_time: 2024-10-17 12:57:35 - err_type: failed to read the connection: EOF - sample_err_msg: this is an error from the backend connection: failed to read the connection: EOF -sample_replay_time: 2024-10-17 12:57:39 - count: 1 -``` + ``` + *************************** 1. row *************************** + err_type: failed to read the connection: EOF + sample_err_msg: this is an error from the backend connection: failed to read the connection: EOF + sample_replay_time: 2024-10-17 12:57:39 + count: 1 + ``` -> **Note:** -> -> - The table schema of `tiproxy_traffic_replay` might change in future versions. It is not recommended to directly read data from `tiproxy_traffic_replay` in your application or tool development. -> - Replay does not guarantee that the transaction execution order between connections exactly matches the capture sequence. This might lead to incorrect error reports. + > **Note:** + > + > - The table schema of `tiproxy_traffic_replay` might change in future versions. It is not recommended to directly read data from `tiproxy_traffic_replay` in your application or tool development. + > - Replay does not guarantee that the transaction execution order between connections exactly matches the capture sequence. This might lead to incorrect error reports. + > - TiProxy does not automatically delete the previous replay report when replaying traffic. You need to manually delete it. ## Test throughput - -
- -To test cluster throughput, use the `SPEED` option to adjust the replay rate. - -For example, `SPEED=2` executes SQL statements at twice the rate, reducing the total replay time by half: - -```sql -TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" SPEED=2 -``` - -
-
- To test cluster throughput, use the `--speed` option to adjust the replay rate. For example, `--speed=2` executes SQL statements at twice the rate, reducing the total replay time by half: @@ -212,79 +146,34 @@ For example, `--speed=2` executes SQL statements at twice the rate, reducing the tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --password="123456" --input="/tmp/traffic" --speed=2 ``` -
-
- Increasing the replay rate only reduces idle time between SQL statements and does not increase the number of connections. When session idle time is already short, increasing the speed might not effectively improve throughput. In such cases, you can deploy multiple TiProxy instances to replay the same traffic files simultaneously, increasing concurrency to improve throughput. -## View and manage jobs - - -
- -During capture and replay, jobs automatically stop if unknown errors occur. To view the current job progress or error information from the last job, use the [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) statement: - -```sql -SHOW TRAFFIC JOBS -``` - -The shown results vary depending on the privileges the current user has. - -- If the user has the [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege, this statement shows traffic capture jobs. -- If the user has the [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege, this statement shows traffic replay jobs. -- If the user has the `SUPER` privilege or both above privileges, this statement shows both traffic capture and traffic replay jobs. - -For example, the following output indicates that 2 TiProxy instances are capturing traffic: - -``` -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | -+----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ -2 rows in set (0.01 sec) -``` +## View and manage tasks -For more information, see [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md). - -To cancel the current capture or replay job, use the [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) statement: - -```sql -CANCEL TRAFFIC JOBS -``` - -Canceling traffic capture jobs requires the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege and canceling traffic replay jobs requires the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. - -For more information, see [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md). - -
-
- -During capture and replay, jobs automatically stop if unknown errors occur. To view the current job progress or error information from the last job, use the [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show) command: +During capture and replay, tasks automatically stop if unknown errors occur. To view the current task progress or error information from the last task, use the [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show) command: ```shell tiproxyctl traffic show --host 10.0.1.10 --port 3080 ``` -For example, the following output indicates a running capture job: +For example, the following output indicates a running capture task: ```json [ { "type": "capture", - "status": "running", "start_time": "2024-09-03T09:10:58.220644+08:00", - "progress": "45%", + "duration": "2h", "output": "/tmp/traffic", - "duration": "2h" + "progress": "45%", + "status": "running" } ] ``` For more information, see [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show). -To cancel the current capture or replay job, use the [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel) command: +To cancel the current capture or replay task, use the [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel) command: ```shell tiproxyctl traffic cancel --host 10.0.1.10 --port 3080 @@ -292,22 +181,12 @@ tiproxyctl traffic cancel --host 10.0.1.10 --port 3080 For more information, see [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel). -
-
- ## Limitations - TiProxy only supports replaying traffic files captured by TiProxy and does not support other file formats. Therefore, make sure to capture traffic from the production cluster using TiProxy first. +- TiProxy traffic replay does not support filtering SQL types and DML and DDL statements are replayed. Therefore, you need to restore the cluster data to its pre-replay state before replaying again. +- TiProxy traffic replay does not support testing [Resource Control](/tidb-resource-control-ru-groups.md) and [privilege management](/privilege-management.md) because TiProxy uses the same username to replay traffic. - TiProxy does not support replaying [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) statements. -- For security reasons, the following statements will not be captured and replayed: - - - `CREATE USER` statement - - `ALTER USER` statement - - `SET PASSWORD` statement - - `GRANT` statement - - `BACKUP` statement - - `RESTORE` statement - - `IMPORT` statement ## More resources diff --git a/tiup/tiup-cluster-topology-reference.md b/tiup/tiup-cluster-topology-reference.md index b9ae6807af547..0f7f604a2749a 100644 --- a/tiup/tiup-cluster-topology-reference.md +++ b/tiup/tiup-cluster-topology-reference.md @@ -404,7 +404,7 @@ tikv_servers: - `resource_control`: Resource control for the service. If this field is configured, the field content is merged with the `resource_control` content in `global` (if the two fields overlap, the content of this field takes effect). Then, a systemd configuration file is generated and sent to the machine specified in `host`. The configuration rules of `resource_control` are the same as the `resource_control` content in `global`. -After the deployment, for the fields above, you can only add directories to `data_dir`; for the fields below, you cannot modify these fields: +After the deployment, for the fields above, you can only add directories to `data_dir`; for the fields below, you cannot modified these fields: - `host` - `tcp_port` diff --git a/tiup/tiup-cluster.md b/tiup/tiup-cluster.md index 234437c44757c..f5ca368a3d154 100644 --- a/tiup/tiup-cluster.md +++ b/tiup/tiup-cluster.md @@ -700,7 +700,7 @@ Environment checks are not necessary for deploying a cluster. For the production All operations above performed on the cluster machine use the SSH client embedded in TiUP to connect to the cluster and execute commands. However, in some scenarios, you might also need to use the SSH client native to the control machine system to perform such cluster operations. For example: -- To use an SSH plug-in for authentication +- To use a SSH plug-in for authentication - To use a customized SSH client Then you can use the `--ssh=system` command-line flag to enable the system-native command-line tool: diff --git a/tiup/tiup-command-mirror-rotate.md b/tiup/tiup-command-mirror-rotate.md index 1a1e8a1b2e71e..699ef31f144ca 100644 --- a/tiup/tiup-command-mirror-rotate.md +++ b/tiup/tiup-command-mirror-rotate.md @@ -35,7 +35,7 @@ TiUP uses the command `tiup mirror rotate` to automate the above process. > **Note:** > -> + For TiUP versions earlier than v1.5.0, running this command does not return a correct new `root.json` file. See [#983](https://github.com/pingcap/tiup/issues/983). +> + For TiUP versions earlier than v1.5.0, running this command does not returns a correct new `root.json` file. See [#983](https://github.com/pingcap/tiup/issues/983). > + Before using this command, make sure that all TiUP clients are upgraded to v1.5.0 or a later version. ## Syntax diff --git a/tiup/tiup-command-mirror-sign.md b/tiup/tiup-command-mirror-sign.md index 53767fc35281a..cfa6846a3491b 100644 --- a/tiup/tiup-command-mirror-sign.md +++ b/tiup/tiup-command-mirror-sign.md @@ -5,7 +5,7 @@ summary: The `tiup mirror sign` command is used to sign metadata files in TiUP m # tiup mirror sign -The `tiup mirror sign` command is used to sign the metadata files (*.json) defined in TiUP [mirror](/tiup/tiup-mirror-reference.md). These metadata files might be stored on the local file system or remotely stored using the HTTP protocol to provide a signature entry. +The `tiup mirror sign` command is used to sign the metadata files (*.json)defined in TiUP [mirror](/tiup/tiup-mirror-reference.md). These metadata files might be stored on the local file system or remotely stored using the HTTP protocol to provide a signature entry. ## Syntax diff --git a/tiup/tiup-component-cluster-enable.md b/tiup/tiup-component-cluster-enable.md index c2d7dc3ba2671..9d54e4484d118 100644 --- a/tiup/tiup-component-cluster-enable.md +++ b/tiup/tiup-component-cluster-enable.md @@ -9,7 +9,7 @@ The `tiup cluster enable` command is used to set the auto-enabling of the cluste > **Note:** > -> When all clusters are shut down and restarted, the order of service startup is determined by the node's operating system startup order. When the restart order is incorrect, in some cases, the restarted cluster still cannot provide services. For example, if TiKV is started first but PD is not started, systemd gives up if TiKV is restarted multiple times while PD is not found. +> When all clusters are shut down and restarted, the order of service startup is determined by the node's operating system startup order. When the restart order is incorrect, in some cases, the restarted cluster still cannot provide services. For example, if TiKV is started first but PD is not started, systemd gives up if TiKV is restarted multiple times while PD is not found). ## Syntax diff --git a/tiup/tiup-component-cluster-patch.md b/tiup/tiup-component-cluster-patch.md index 3fe0b7a9ae694..d91ddd96b6df8 100644 --- a/tiup/tiup-component-cluster-patch.md +++ b/tiup/tiup-component-cluster-patch.md @@ -70,7 +70,7 @@ After you have completed the preceding steps, you can use `/tmp/${component}-hot ### --overwrite -- After you patch a certain component (such as TiDB or TiKV), when the tiup cluster scales out the component, TiUP uses the original component version by default. To use the version that you patch when the cluster scales out in the future, you need to specify the option `--overwrite` in the command. +- After you patch a certain component (such as TiDB or TiKV), when the tiup cluster scales out the component, TiUP uses the original component version by default. To use the version that you patch when the cluster scales out in the future, you need to specified the option `--overwrite` in the command. - Data type: `BOOLEAN` - This option is disabled by default with the `false` value. To enable this option, add this option to the command, and either pass the `true` value or do not pass any value. diff --git a/tiup/tiup-component-dm-patch.md b/tiup/tiup-component-dm-patch.md index 64489416a273c..46512ba2ffa50 100644 --- a/tiup/tiup-component-dm-patch.md +++ b/tiup/tiup-component-dm-patch.md @@ -79,7 +79,7 @@ The following example shows how to apply `v5.3.0-hotfix` to the `v5.3.0` cluster > **Note:** > -> Hotfix is used only for emergency fixes. Its daily maintenance is complicated. It is recommended that you upgrade the DM cluster to an official version as soon as it is released. +> Hotfix is used only for emergency fixes. Its daily maintenance is complicated. It is recommend that you upgrade the DM cluster to an official version as soon as it is released. ### Preparations diff --git a/tiup/tiup-component-dm.md b/tiup/tiup-component-dm.md index 5f483af57247b..0a9e6aacb1c34 100644 --- a/tiup/tiup-component-dm.md +++ b/tiup/tiup-component-dm.md @@ -39,7 +39,7 @@ tiup dm [command] [flags] - Specifies the maximum waiting time (in seconds) for each step in the operation process. The operation process consists of many steps, such as specifying systemctl to start or stop services, and waiting for ports to be online or offline. Each step may take several seconds. If the execution time of a step exceeds the specified timeout, the step exits with an error. - Data type: `UINT` -- If this option is not specified in the command, the maximum waiting time for each step is `120` seconds. +- If this option is not specified in the command, the maximum waiting time for each steps is `120` seconds. ### -y, --yes diff --git a/tune-operating-system.md b/tune-operating-system.md index d54e9d5e409fb..9007714bcc7b0 100644 --- a/tune-operating-system.md +++ b/tune-operating-system.md @@ -10,7 +10,7 @@ This document introduces how to tune each subsystem of CentOS 7. > **Note:** > -> + The default configuration of the CentOS 7 operating system is suitable for most services running under moderate workloads. Adjusting the performance of a particular subsystem might negatively affect other subsystems. Therefore, before tuning the system, back up all the user data and configuration information. +> + The default configuration of the CentOS 7 operating system is suitable for most services running under moderate workloads. Adjusting the performance of a particular subsystem might negatively affects other subsystems. Therefore, before tuning the system, back up all the user data and configuration information. > + Fully test all the changes in the test environment before applying them to the production environment. ## Performance analysis methods diff --git a/vector-search/vector-search-index.md b/vector-search/vector-search-index.md index 312f6a8ca3ba3..c5bd4021c520f 100644 --- a/vector-search/vector-search-index.md +++ b/vector-search/vector-search-index.md @@ -5,9 +5,9 @@ summary: Learn how to build and use the vector search index to accelerate K-Near # Vector Search Index -As described in the [Vector Search](/vector-search/vector-search-overview.md) document, vector search identifies the Top K-Nearest Neighbors (KNN) to a given vector by calculating the distance between the given vector and all vectors stored in the database. While this approach provides accurate results, it can be slow when the table contains a large number of vectors because it involves a full table scan. +K-nearest neighbors (KNN) search is the method for finding the K closest points to a given point in a vector space. The most straightforward approach to perform KNN search is a brute force search, which calculates the distance between the given vector and all other vectors in the space. This approach guarantees perfect accuracy, but it is usually too slow for real-world use. Therefore, approximate algorithms are commonly used in KNN search to enhance speed and efficiency. -To improve search efficiency, you can create vector search indexes in TiDB for approximate KNN (ANN) search. When using vector indexes for vector search, TiDB can greatly improve query performance with only a slight reduction in accuracy, generally maintaining a search recall rate above 90%. +In TiDB, you can create and use vector search indexes for such approximate nearest neighbor (ANN) searches over columns with [vector data types](/vector-search/vector-search-data-types.md). By using vector search indexes, vector search queries could be finished in milliseconds. diff --git a/vector-search/vector-search-integrate-with-llamaindex.md b/vector-search/vector-search-integrate-with-llamaindex.md index fc0901a895211..e074a46eaf361 100644 --- a/vector-search/vector-search-integrate-with-llamaindex.md +++ b/vector-search/vector-search-integrate-with-llamaindex.md @@ -108,7 +108,7 @@ For a TiDB Cloud Serverless cluster, take the following steps to obtain the clus 5. Configure environment variables. - This document uses [OpenAI](https://platform.openai.com/docs/introduction) as the embedding model provider. In this step, you need to provide the connection string obtained from the previous step and your [OpenAI API key](https://platform.openai.com/docs/quickstart/step-2-set-up-your-api-key). + This document uses [OpenAI](https://platform.openai.com/docs/introduction) as the embedding model provider. In this step, you need to provide the connection string obtained from from the previous step and your [OpenAI API key](https://platform.openai.com/docs/quickstart/step-2-set-up-your-api-key). To configure the environment variables, run the following code. You will be prompted to enter your connection string and OpenAI API key: diff --git a/workload-repository.md b/workload-repository.md deleted file mode 100644 index 81fcc5a6383b6..0000000000000 --- a/workload-repository.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: TiDB Workload Repository -summary: Introduces the workload repository system for collecting and storing historical workload data from a TiDB cluster. ---- - -# TiDB Workload Repository - -The workload repository is a system for collecting and storing historical workload data from a TiDB cluster. It periodically samples various system tables to track cluster performance and usage patterns over time. - -## Enable the Workload Repository - -To enable the Workload Repository, set the [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900) system variable: - -```sql -SET GLOBAL tidb_workload_repository_dest = 'table'; -``` - -To disable it: - -```sql -SET GLOBAL tidb_workload_repository_dest = ''; -``` - -## Data collection - -The Workload Repository stores data in tables under the `WORKLOAD_SCHEMA` database. It collects data via two different methods: - -* The snapshot sampling process, which runs at configurable intervals, hourly by default, and can be triggered manually. -* The time-based sampling process, which runs at shorter intervals, typically every 5 seconds. - -## Snapshot sampling process (hourly by default) - -The snapshot sampling process, which runs every 15 minutes to 2 hours, samples data from various cumulative metrics tables. Snapshots are initiated from one of the TiDB nodes at the specified intervals, and the process is as follows: - -1. From the initiating node, a row is inserted into `WORKLOAD_SCHEMA.HIST_SNAPSHOTS`, capturing the snapshot ID, start and end timestamps, and server version details. -2. On each TiDB node, all rows from the source tables are copied to the corresponding target tables with the `HIST_` prefix. The copied data includes the original columns from the source tables plus additional columns for the timestamp, instance ID, and snapshot ID. - -Note that the sampled tables return data specific to the TiDB node from which they are queried. - -Data is sampled from the following tables: - -| Source table | Destination table | Description | -| --- | --- | --- | -| [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) | `HIST_TIDB_INDEX_USAGE` | Index usage statistics | -| [`TIDB_STATEMENTS_STATS`](/statement-summary-tables.md) | `HIST_TIDB_STATEMENTS_STATS` | Statement statistics | -| [`CLIENT_ERRORS_SUMMARY_BY_HOST`](/information-schema/client-errors-summary-by-host.md) | `HIST_CLIENT_ERRORS_SUMMARY_BY_HOST` | Client error summaries by host | -| [`CLIENT_ERRORS_SUMMARY_BY_USER`](/information-schema/client-errors-summary-by-user.md) | `HIST_CLIENT_ERRORS_SUMMARY_BY_USER` | Client error summaries by user | -| [`CLIENT_ERRORS_SUMMARY_GLOBAL`](/information-schema/client-errors-summary-global.md) | `HIST_CLIENT_ERRORS_SUMMARY_GLOBAL` | Client error summaries by global | - -The snapshot sampling interval can be controlled with [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900): - -```sql -SET GLOBAL tidb_workload_repository_snapshot_interval = 900; -- set the interval to 15 minutes -``` - -## Manual snapshots - -Note that while the snapshot sampling process runs automatically based on the configured interval, you can also trigger a manual snapshot using the following SQL statement: - -```sql -ADMIN CREATE WORKLOAD SNAPSHOT; -``` - -Manually triggering snapshots does not change the interval or timing of automatic snapshots. - -## Time-based sampling process (every 5 seconds by default) - -The time-based sampling process samples data from various non-cumulative metrics tables at intervals ranging from 1 to 600 seconds. - -When the time-base sampling process runs, all rows from the source tables are copied to the corresponding target tables with the `HIST_` prefix. The copied data includes the original columns from the source tables plus additional columns for the timestamp and instance ID. - -Unlike the snapshot sampling process, a row will not be added to the `HIST_SNAPSHOTS` table. - -Note that the sampled tables return data specific to the TiDB node from which they are queried. - -Data is sampled from the following tables: - -| Source table | Destination table | Description | -| --- | --- | --- | -| [`PROCESSLIST`](/information-schema/information-schema-processlist.md) | `HIST_PROCESSLIST` | Active sessions | -| [`DATA_LOCK_WAITS`](/information-schema/information-schema-data-lock-waits.md) | `HIST_DATA_LOCK_WAITS` | Data lock waits | -| [`TIDB_TRX`](/information-schema/information-schema-tidb-trx.md) | `HIST_TIDB_TRX` | Active transactions | -| [`MEMORY_USAGE`](/information-schema/information-schema-memory-usage.md) | `HIST_MEMORY_USAGE` | Memory usage | -| [`DEADLOCKS`](/information-schema/information-schema-deadlocks.md) | `HIST_DEADLOCKS` | Deadlock information | - -The time-based sampling interval can be controlled with [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900): - -```sql -SET GLOBAL tidb_workload_repository_active_sampling_interval = 20; -- set the interval to 20 seconds -``` - -Setting this global variable to `0` disables the time-based sampling process. - -## Data retention - -Historical data in the Workload Repository is retained for seven days by default. The system automatically purges data based on the retention period setting, using partitions for efficient data management. - -By default the Workload Repository retains historical data for seven days, but the [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) variable can be used to control the length of this period. For example, to keep data for 30 days, run the following: - -```sql -SET GLOBAL tidb_workload_repository_retention_days = 30; -``` - -A higher value for this variable allows for longer data retention, which might be beneficial for workload analysis, but will increase storage requirements. - -## Notes - -- Enabling the Workload Repository might have a small performance impact on the system. -- Setting sampling intervals too short might increase system overhead. -- Setting retention days to `0` disables automatic purging of old data. - -## Best practices - -- Start with default settings and adjust based on your monitoring needs. -- Set reasonable retention periods based on your storage capacity. -- Monitor the size of the `WORKLOAD_SCHEMA` database. -- Use longer sampling intervals in production environments to minimize overhead. diff --git a/wrong-index-solution.md b/wrong-index-solution.md index 46a9cc4706dd5..eb47888f9677a 100644 --- a/wrong-index-solution.md +++ b/wrong-index-solution.md @@ -29,7 +29,7 @@ The near 100% health state suggests that the `ANALYZE` statement is just complet For equivalence queries, the cause might be [Count-Min Sketch](/statistics.md#count-min-sketch). You can check whether Count-Min Sketch is the cause and take corresponding solutions. -If the cause above does not apply to your problem, you can force-select indexes by using the `USE_INDEX` or `use index` optimizer hint (see [USE_INDEX](/optimizer-hints.md#use_indext1_name-idx1_name--idx2_name-) for details). Also, you can change the query behavior by using [SQL Plan Management](/sql-plan-management.md) in a non-intrusive way. +If the cause above does not apply to your problem, you can force-select indexes by using the `USE_INDEX` or `use index` optimzer hint (see [USE_INDEX](/optimizer-hints.md#use_indext1_name-idx1_name--idx2_name-) for details). Also, you can change the query behavior by using [SQL Plan Management](/sql-plan-management.md) in a non-intrusive way. ### Other situations From 90f999884f41456fb8657262b17e5787d83db902 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 21 Apr 2025 13:22:46 +0800 Subject: [PATCH 25/51] Reapply "Merge remote-tracking branch 'upstream/master' into rn-9.0.0" This reverts commit dfe43537bcdcc8b8c76153278a206b7486938a48. --- .github/workflows/doc_review.yml | 2 +- TOC.md | 68 ++--- _index.md | 2 +- basic-features.md | 2 +- benchmark/benchmark-tidb-using-tpcc.md | 2 +- best-practices/java-app-best-practices.md | 48 +++- .../three-nodes-hybrid-deployment.md | 2 +- br/backup-and-restore-storages.md | 6 +- br/br-checkpoint-restore.md | 72 ++++- br/br-pitr-manual.md | 22 ++ cached-tables.md | 2 +- dashboard/dashboard-access.md | 2 +- dashboard/dashboard-diagnostics-report.md | 2 +- dashboard/dashboard-faq.md | 2 +- ddl-introduction.md | 2 +- deploy-monitoring-services.md | 4 +- develop/dev-guide-build-cluster-in-cloud.md | 2 +- develop/dev-guide-create-table.md | 2 +- develop/dev-guide-gui-datagrip.md | 2 +- develop/dev-guide-gui-navicat.md | 6 +- develop/dev-guide-index-best-practice.md | 2 +- ...dev-guide-sql-development-specification.md | 2 +- develop/dev-guide-use-subqueries.md | 2 +- dm/dm-continuous-data-validation.md | 2 +- dm/dm-webui-guide.md | 2 +- dm/maintain-dm-using-tiup.md | 2 +- ecosystem-tool-user-guide.md | 4 +- enable-tls-between-components.md | 32 ++- encryption-at-rest.md | 2 +- .../json-functions/json-functions-validate.md | 4 +- functions-and-operators/locking-functions.md | 2 +- functions-and-operators/string-functions.md | 2 +- geo-distributed-deployment-topology.md | 2 +- identify-slow-queries.md | 2 +- .../client-errors-summary-by-user.md | 2 +- .../information-schema-sql-diagnostics.md | 2 +- .../information-schema-statistics.md | 2 +- .../information-schema-tables.md | 2 +- literal-values.md | 2 +- media/tiproxy/tiproxy-balance-label.png | Bin 86358 -> 98047 bytes optimizer-fix-controls.md | 2 +- optimizer-hints.md | 2 +- pipelined-dml.md | 8 + privilege-management.md | 22 ++ releases/release-6.0.0-dmr.md | 2 +- releases/release-8.4.0.md | 6 +- security-compatibility-with-mysql.md | 2 +- sql-statements/sql-statement-admin.md | 24 ++ .../sql-statement-cancel-traffic-jobs.md | 73 +++++ sql-statements/sql-statement-commit.md | 2 +- sql-statements/sql-statement-drop-view.md | 2 +- sql-statements/sql-statement-rollback.md | 2 +- .../sql-statement-show-placement-for.md | 2 +- .../sql-statement-show-placement.md | 2 +- .../sql-statement-show-traffic-jobs.md | 77 +++++ .../sql-statement-traffic-capture.md | 67 +++++ .../sql-statement-traffic-replay.md | 71 +++++ stale-read.md | 2 +- statement-summary-tables.md | 11 + statistics.md | 4 +- system-variable-reference.md | 29 +- system-variables.md | 156 ++++++++-- ...e-data-centers-in-two-cities-deployment.md | 2 +- ticdc/ticdc-avro-protocol.md | 1 + ticdc/ticdc-canal-json.md | 1 + ticdc/ticdc-csv.md | 1 + ticdc/ticdc-glossary.md | 2 +- ticdc/ticdc-manage-changefeed.md | 2 +- ticdc/ticdc-open-protocol.md | 1 + ticdc/ticdc-simple-protocol.md | 1 + ticdc/ticdc-sink-to-cloud-storage.md | 8 +- ticdc/ticdc-sink-to-mysql.md | 2 +- tidb-cloud/high-availability-with-multi-az.md | 2 +- tidb-cloud/integrate-tidbcloud-with-n8n.md | 2 +- tidb-cloud/limited-sql-features.md | 1 - tidb-cloud/ticloud-config-edit.md | 2 +- ...troubleshoot-import-access-denied-error.md | 2 +- tidb-configuration-file.md | 4 +- tidb-control.md | 2 +- tidb-monitoring-framework.md | 8 +- tidb-resource-control-ru-groups.md | 10 +- tidb-troubleshooting-map.md | 2 +- tiflash-upgrade-guide.md | 6 +- tiflash/tiflash-overview.md | 2 +- tikv-configuration-file.md | 2 +- tiproxy/tiproxy-command-line-flags.md | 51 ++-- tiproxy/tiproxy-configuration.md | 24 +- tiproxy/tiproxy-load-balance.md | 40 ++- tiproxy/tiproxy-traffic-replay.md | 269 +++++++++++++----- tiup/tiup-cluster-topology-reference.md | 2 +- tiup/tiup-cluster.md | 2 +- tiup/tiup-command-mirror-rotate.md | 2 +- tiup/tiup-command-mirror-sign.md | 2 +- tiup/tiup-component-cluster-enable.md | 2 +- tiup/tiup-component-cluster-patch.md | 2 +- tiup/tiup-component-dm-patch.md | 2 +- tiup/tiup-component-dm.md | 2 +- tune-operating-system.md | 2 +- vector-search/vector-search-index.md | 4 +- ...vector-search-integrate-with-llamaindex.md | 2 +- workload-repository.md | 117 ++++++++ wrong-index-solution.md | 2 +- 102 files changed, 1213 insertions(+), 272 deletions(-) create mode 100644 sql-statements/sql-statement-cancel-traffic-jobs.md create mode 100644 sql-statements/sql-statement-show-traffic-jobs.md create mode 100644 sql-statements/sql-statement-traffic-capture.md create mode 100644 sql-statements/sql-statement-traffic-replay.md create mode 100644 workload-repository.md diff --git a/.github/workflows/doc_review.yml b/.github/workflows/doc_review.yml index 091e286fd640b..79614b63b3d24 100644 --- a/.github/workflows/doc_review.yml +++ b/.github/workflows/doc_review.yml @@ -76,7 +76,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} API_PROVIDER: "openai" # or "openai" if you want to use OpenAI OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - OPENAI_API_MODEL: "gpt-4" + OPENAI_API_MODEL: "gpt-4o" exclude: "**/*.json" # Optional: exclude patterns separated by commas REVIEW_MODE: ${{ steps.extract.outputs.REVIEW_MODE || 'default' }} COMMIT_SHA: ${{ steps.extract.outputs.COMMIT_SHA || '' }} diff --git a/TOC.md b/TOC.md index 4b220ca8f39c4..c862fcd2083dd 100644 --- a/TOC.md +++ b/TOC.md @@ -280,6 +280,37 @@ - [Monitoring API](/tidb-monitoring-api.md) - [Deploy Monitoring Services](/deploy-monitoring-services.md) - [Upgrade Monitoring Services](/upgrade-monitoring-services.md) + - TiDB Dashboard + - [Overview](/dashboard/dashboard-intro.md) + - Maintain + - [Deploy](/dashboard/dashboard-ops-deploy.md) + - [Reverse Proxy](/dashboard/dashboard-ops-reverse-proxy.md) + - [User Management](/dashboard/dashboard-user.md) + - [Secure](/dashboard/dashboard-ops-security.md) + - [Access](/dashboard/dashboard-access.md) + - [Overview Page](/dashboard/dashboard-overview.md) + - [Cluster Info Page](/dashboard/dashboard-cluster-info.md) + - [Top SQL Page](/dashboard/top-sql.md) + - [Key Visualizer Page](/dashboard/dashboard-key-visualizer.md) + - [Metrics Relation Graph](/dashboard/dashboard-metrics-relation.md) + - SQL Statements Analysis + - [SQL Statements Page](/dashboard/dashboard-statement-list.md) + - [SQL Details Page](/dashboard/dashboard-statement-details.md) + - [Slow Queries Page](/dashboard/dashboard-slow-query.md) + - Cluster Diagnostics + - [Access Cluster Diagnostics Page](/dashboard/dashboard-diagnostics-access.md) + - [View Diagnostics Report](/dashboard/dashboard-diagnostics-report.md) + - [Use Diagnostics](/dashboard/dashboard-diagnostics-usage.md) + - [Monitoring Page](/dashboard/dashboard-monitoring.md) + - [Search Logs Page](/dashboard/dashboard-log-search.md) + - [Resource Manager Page](/dashboard/dashboard-resource-manager.md) + - Instance Profiling + - [Manual Profiling](/dashboard/dashboard-profiling.md) + - [Continuous Profiling](/dashboard/continuous-profiling.md) + - Session Management and Configuration + - [Share Session](/dashboard/dashboard-session-share.md) + - [Configure SSO](/dashboard/dashboard-session-sso.md) + - [FAQ](/dashboard/dashboard-faq.md) - [Export Grafana Snapshots](/exporting-grafana-snapshots.md) - [TiDB Cluster Alert Rules](/alert-rules.md) - [TiFlash Alert Rules](/tiflash/tiflash-alert-rules.md) @@ -777,6 +808,7 @@ - [`BEGIN`](/sql-statements/sql-statement-begin.md) - [`CALIBRATE RESOURCE`](/sql-statements/sql-statement-calibrate-resource.md) - [`CANCEL IMPORT JOB`](/sql-statements/sql-statement-cancel-import-job.md) + - [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) - [`COMMIT`](/sql-statements/sql-statement-commit.md) - [`CREATE BINDING`](/sql-statements/sql-statement-create-binding.md) - [`CREATE DATABASE`](/sql-statements/sql-statement-create-database.md) @@ -883,6 +915,7 @@ - [`SHOW TABLE REGIONS`](/sql-statements/sql-statement-show-table-regions.md) - [`SHOW TABLE STATUS`](/sql-statements/sql-statement-show-table-status.md) - [`SHOW TABLES`](/sql-statements/sql-statement-show-tables.md) + - [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) - [`SHOW VARIABLES`](/sql-statements/sql-statement-show-variables.md) - [`SHOW WARNINGS`](/sql-statements/sql-statement-show-warnings.md) - [`SHUTDOWN`](/sql-statements/sql-statement-shutdown.md) @@ -890,6 +923,8 @@ - [`START TRANSACTION`](/sql-statements/sql-statement-start-transaction.md) - [`TABLE`](/sql-statements/sql-statement-table.md) - [`TRACE`](/sql-statements/sql-statement-trace.md) + - [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) + - [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) - [`TRUNCATE`](/sql-statements/sql-statement-truncate.md) - [`UNLOCK STATS`](/sql-statements/sql-statement-unlock-stats.md) - [`UPDATE`](/sql-statements/sql-statement-update.md) @@ -1034,43 +1069,12 @@ - [Metadata Lock](/metadata-lock.md) - [TiDB Accelerated Table Creation](/accelerated-table-creation.md) - [Schema Cache](/schema-cache.md) - - UI - - TiDB Dashboard - - [Overview](/dashboard/dashboard-intro.md) - - Maintain - - [Deploy](/dashboard/dashboard-ops-deploy.md) - - [Reverse Proxy](/dashboard/dashboard-ops-reverse-proxy.md) - - [User Management](/dashboard/dashboard-user.md) - - [Secure](/dashboard/dashboard-ops-security.md) - - [Access](/dashboard/dashboard-access.md) - - [Overview Page](/dashboard/dashboard-overview.md) - - [Cluster Info Page](/dashboard/dashboard-cluster-info.md) - - [Top SQL Page](/dashboard/top-sql.md) - - [Key Visualizer Page](/dashboard/dashboard-key-visualizer.md) - - [Metrics Relation Graph](/dashboard/dashboard-metrics-relation.md) - - SQL Statements Analysis - - [SQL Statements Page](/dashboard/dashboard-statement-list.md) - - [SQL Details Page](/dashboard/dashboard-statement-details.md) - - [Slow Queries Page](/dashboard/dashboard-slow-query.md) - - Cluster Diagnostics - - [Access Cluster Diagnostics Page](/dashboard/dashboard-diagnostics-access.md) - - [View Diagnostics Report](/dashboard/dashboard-diagnostics-report.md) - - [Use Diagnostics](/dashboard/dashboard-diagnostics-usage.md) - - [Monitoring Page](/dashboard/dashboard-monitoring.md) - - [Search Logs Page](/dashboard/dashboard-log-search.md) - - [Resource Manager Page](/dashboard/dashboard-resource-manager.md) - - Instance Profiling - - [Manual Profiling](/dashboard/dashboard-profiling.md) - - [Continuous Profiling](/dashboard/continuous-profiling.md) - - Session Management and Configuration - - [Share Session](/dashboard/dashboard-session-share.md) - - [Configure SSO](/dashboard/dashboard-session-sso.md) - - [FAQ](/dashboard/dashboard-faq.md) - [Telemetry](/telemetry.md) - [Error Codes](/error-codes.md) - [Table Filter](/table-filter.md) - [Schedule Replicas by Topology Labels](/schedule-replicas-by-topology-labels.md) - [URI Formats of External Storage Services](/external-storage-uri.md) + - [TiDB Workload Repository](/workload-repository.md) - FAQs - [FAQ Summary](/faq/faq-overview.md) - [TiDB FAQs](/faq/tidb-faq.md) diff --git a/_index.md b/_index.md index cdea814494b77..3b27a7d54a932 100644 --- a/_index.md +++ b/_index.md @@ -82,7 +82,7 @@ summary: TiDB is an open-source distributed SQL database that supports Hybrid Tr -[Use Prometheus and Grafana](https://docs.pingcap.com/tidb/dev/tidb-monitoring-framework) +[Use Prometheus, Grafana, and TiDB Dashboard](https://docs.pingcap.com/tidb/dev/tidb-monitoring-framework) [Monitoring API](https://docs.pingcap.com/tidb/dev/tidb-monitoring-api) diff --git a/basic-features.md b/basic-features.md index dfb8e228332ae..a32b3d0e3379a 100644 --- a/basic-features.md +++ b/basic-features.md @@ -28,7 +28,7 @@ You can try out TiDB features on [TiDB Playground](https://play.tidbcloud.com/?u | [Date and time types](/data-type-date-and-time.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [String types](/data-type-string.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [JSON type](/data-type-json.md) | Y | Y | Y | Y | Y | E | E | E | E | E | -| [Vectort types](/vector-search/vector-search-data-types.md) | E | N | N | N | N | N | N | N | N | N | +| [Vector types](/vector-search/vector-search-data-types.md) | E | N | N | N | N | N | N | N | N | N | | [Control flow functions](/functions-and-operators/control-flow-functions.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [String functions](/functions-and-operators/string-functions.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | [Numeric functions and operators](/functions-and-operators/numeric-functions-and-operators.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | diff --git a/benchmark/benchmark-tidb-using-tpcc.md b/benchmark/benchmark-tidb-using-tpcc.md index 72a3c270f1d1c..22a77bc9899cb 100644 --- a/benchmark/benchmark-tidb-using-tpcc.md +++ b/benchmark/benchmark-tidb-using-tpcc.md @@ -24,7 +24,7 @@ Before testing, TPC-C Benchmark specifies the initial state of the database, whi * The `DISTRICT` table has W \* 10 records (Each warehouse provides services to 10 districts) * The `CUSTOMER` table has W \* 10 \* 3,000 records (Each district has 3,000 customers) * The `HISTORY` table has W \* 10 \* 3,000 records (Each customer has one transaction history) -* The `ORDER` table has W \* 10 \* 3,000 records (Each district has 3,000 orders and the last 900 orders generated are added to the `NEW-ORDER` table. Each order randomly generates 5 ~ 15 ORDER-LINE records. +* The `ORDER` table has W \* 10 \* 3,000 records (Each district has 3,000 orders and the last 900 orders generated are added to the `NEW-ORDER` table. Each order randomly generates 5 ~ 15 ORDER-LINE records.) In this document, the testing uses 1,000 warehouses as an example to test TiDB. diff --git a/best-practices/java-app-best-practices.md b/best-practices/java-app-best-practices.md index abfa24b600a1f..c864ecd120ffd 100644 --- a/best-practices/java-app-best-practices.md +++ b/best-practices/java-app-best-practices.md @@ -204,26 +204,62 @@ Through monitoring, you might notice that although the application only performs After it is configured, you can check the monitoring to see a decreased number of `SELECT` statements. +> **Note:** +> +> Enabling `useConfigs=maxPerformance` requires MySQL Connector/J version 8.0.33 or later. For more details, see [MySQL JDBC Bug](/develop/dev-guide-third-party-tools-compatibility.md#mysql-jdbc-bugs). + #### Timeout-related parameters TiDB provides two MySQL-compatible parameters that controls the timeout: `wait_timeout` and `max_execution_time`. These two parameters respectively control the connection idle timeout with the Java application and the timeout of the SQL execution in the connection; that is to say, these parameters control the longest idle time and the longest busy time for the connection between TiDB and the Java application. The default value of both parameters is `0`, which by default allows the connection to be infinitely idle and infinitely busy (an infinite duration for one SQL statement to execute). However, in an actual production environment, idle connections and SQL statements with excessively long execution time negatively affect databases and applications. To avoid idle connections and SQL statements that are executed for too long, you can configure these two parameters in your application's connection string. For example, set `sessionVariables=wait_timeout=3600` (1 hour) and `sessionVariables=max_execution_time=300000` (5 minutes). +#### Typical JDBC connection string parameters + +Combining the preceding parameter values, the JDBC connection string configuration is as follows: + +``` +jdbc:mysql://:/?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true +``` + +> **Note:** +> +> If you are connecting over a public network, you need to set `useSSL=true` and [enable TLS between TiDB clients and servers](/enable-tls-between-clients-and-servers.md). + ## Connection pool Building TiDB (MySQL) connections is relatively expensive (for OLTP scenarios at least), because in addition to building a TCP connection, connection authentication is also required. Therefore, the client usually saves the TiDB (MySQL) connections to the connection pool for reuse. -Java has many connection pool implementations such as [HikariCP](https://github.com/brettwooldridge/HikariCP), [tomcat-jdbc](https://tomcat.apache.org/tomcat-10.1-doc/jdbc-pool.html), [druid](https://github.com/alibaba/druid), [c3p0](https://www.mchange.com/projects/c3p0/), and [dbcp](https://commons.apache.org/proper/commons-dbcp/). TiDB does not limit which connection pool you use, so you can choose whichever you like for your application. +TiDB supports the following Java connection pools: + +- [HikariCP](https://github.com/brettwooldridge/HikariCP) +- [tomcat-jdbc](https://tomcat.apache.org/tomcat-10.1-doc/jdbc-pool) +- [druid](https://github.com/alibaba/druid) +- [c3p0](https://www.mchange.com/projects/c3p0/) +- [dbcp](https://commons.apache.org/proper/commons-dbcp/) -### Configure the number of connections +In practice, some connection pools might persistently use specific active sessions. Although the total number of connections appears evenly distributed across TiDB compute nodes, uneven distribution of active connections can lead to actual load imbalance. In distributed scenarios, it is recommended to use HikariCP, which manages connection lifecycles effectively and helps prevent active connections from being fixed on certain nodes, achieving balanced load distribution. -It is a common practice that the connection pool size is well adjusted according to the application's own needs. Take HikariCP as an example: +### Typical connection pool configuration + +The following is an example configuration for HikariCP: + +```yaml +hikari: + maximumPoolSize: 20 + poolName: hikariCP + connectionTimeout: 30000 + maxLifetime: 1200000 + keepaliveTime: 120000 +``` -- `maximumPoolSize`: The maximum number of connections in the connection pool. If this value is too large, TiDB consumes resources to maintain useless connections. If this value is too small, the application gets slow connections. So configure this value for your own good. For details, see [About Pool Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing). -- `minimumIdle`: The minimum number of idle connections in the connection pool. It is mainly used to reserve some connections to respond to sudden requests when the application is idle. You can also configure it according to your application needs. +The parameter explanations are as follows. For more details, refer to the [official HikariCP documentation](https://github.com/brettwooldridge/HikariCP/blob/dev/README.md). -The application needs to return the connection after finishing using it. It is also recommended that the application use the corresponding connection pool monitoring (such as `metricRegistry`) to locate the connection pool issue in time. +- `maximumPoolSize`: the maximum number of connections in the pool. The default value is `10`. In containerized environments, it is recommended to set this to 4–10 times the number of CPU cores available to the Java application. Setting this value too high can lead to resource wastage, while setting it too low can slow down connection acquisition. See [About Pool Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing) for more details. +- `minimumIdle`: HikariCP recommends not setting this parameter. The default value is equal to the value of `maximumPoolSize`, which disables connection pool scaling. This ensures that connections are readily available during traffic spikes and avoids delays caused by connection creation. +- `connectionTimeout`: the maximum time (in milliseconds) that an application waits to acquire a connection from the pool. The default value is `30000` milliseconds (30 seconds). If no available connection is obtained within this time, a `SQLException` exception occurs. +- `maxLifetime`: the maximum lifetime (in milliseconds) of a connection in the pool. The default value is `1800000` milliseconds (30 minutes). Connections in use are not affected. After the connection is closed, it will be removed according to this setting. Setting this value too low can cause frequent reconnections. If you are using [`graceful-wait-before-shutdown`](/tidb-configuration-file.md#graceful-wait-before-shutdown-new-in-v50), ensure this value is less than the wait time. +- `keepaliveTime`: the interval (in milliseconds) between keepalive operations on connections in the pool. This setting helps prevent disconnections caused by database or network idle timeouts. The default value is `120000` milliseconds (2 minutes). The pool prefers using the JDBC4 `isValid()` method to keep idle connections alive. ### Probe configuration diff --git a/best-practices/three-nodes-hybrid-deployment.md b/best-practices/three-nodes-hybrid-deployment.md index 9c6cb82d7bcb8..cbd698c50de28 100644 --- a/best-practices/three-nodes-hybrid-deployment.md +++ b/best-practices/three-nodes-hybrid-deployment.md @@ -69,7 +69,7 @@ In this test, the value of this parameter is set to `2`. Observe the **gRPC poll #### `storage.scheduler-worker-pool-size` -When TiKV detects that the CPU core number of the machine is greater than or equal to `16`, this parameter value defaults to `8`. When the CPU core number is smaller than `16`, the parameter value defaults to `4`. This parameter is used when TiKV converts complex transaction requests to simple key-value reads or writes, but the scheduler thread pool does not performs any writes. +When TiKV detects that the CPU core number of the machine is greater than or equal to `16`, this parameter value defaults to `8`. When the CPU core number is smaller than `16`, the parameter value defaults to `4`. This parameter is used when TiKV converts complex transaction requests to simple key-value reads or writes, but the scheduler thread pool does not perform any writes. Ideally, the usage rate of the scheduler thread pool is kept between 50% and 75%. Similar to the gRPC thread pool, the `storage.scheduler-worker-pool-size` parameter defaults to a larger value during the hybrid deployment, which makes resource usage insufficient. In this test, the value of this parameter is set to `2`, which is in line with the best practices, a conclusion drawn by observing the corresponding metrics in the **Scheduler worker CPU** panel. diff --git a/br/backup-and-restore-storages.md b/br/backup-and-restore-storages.md index 9c6aa083d8bbe..767dd887c6836 100644 --- a/br/backup-and-restore-storages.md +++ b/br/backup-and-restore-storages.md @@ -10,9 +10,9 @@ TiDB supports storing backup data to Amazon S3, Google Cloud Storage (GCS), Azur ## Send credentials to TiKV -| CLI parameter | Description | Default value -|:----------|:-------|:-------| -| `--send-credentials-to-tikv` | Controls whether to send credentials obtained by BR to TiKV. | `true`| +| CLI parameter | Description | Default value | +|:-----------------------------|:-------------------------------------------------------------|:--------------| +| `--send-credentials-to-tikv` | Controls whether to send credentials obtained by BR to TiKV. | `true` | By default, BR sends a credential to each TiKV node when using Amazon S3, GCS, or Azure Blob Storage as the storage system. This behavior simplifies the configuration and is controlled by the parameter `--send-credentials-to-tikv`(or `-c` in short). diff --git a/br/br-checkpoint-restore.md b/br/br-checkpoint-restore.md index b94ecc47361a4..8a734e98c46c7 100644 --- a/br/br-checkpoint-restore.md +++ b/br/br-checkpoint-restore.md @@ -15,7 +15,7 @@ If your TiDB cluster is large and cannot afford to restore again after a failure ## Implementation principles -The implementation of checkpoint restore is divided into two parts: snapshot restore and log restore. For more information, see [Implementation details](#implementation-details). +The implementation of checkpoint restore is divided into two parts: snapshot restore and log restore. For more information, see [Implementation details: store checkpoint data in the downstream cluster](#implementation-details-store-checkpoint-data-in-the-downstream-cluster) and [Implementation details: store checkpoint data in the external storage](#implementation-details-store-checkpoint-data-in-the-external-storage). ### Snapshot restore @@ -65,7 +65,11 @@ After a restore failure, avoid writing, deleting, or creating tables in the clus Cross-major-version checkpoint recovery is not recommended. For clusters where `br` recovery fails using the Long-Term Support (LTS) versions prior to v8.5.0, recovery cannot be continued with v8.5.0 or later LTS versions, and vice versa. -## Implementation details +## Implementation details: store checkpoint data in the downstream cluster + +> **Note:** +> +> Starting from v9.0.0, BR stores checkpoint data in the downstream cluster by default. You can specify an external storage for checkpoint data using the `--checkpoint-storage` parameter. Checkpoint restore operations are divided into two parts: snapshot restore and PITR restore. @@ -81,8 +85,70 @@ If the restore fails and you try to restore backup data with different checkpoin [PITR (Point-in-time recovery)](/br/br-pitr-guide.md) consists of snapshot restore and log restore phases. -During the initial restore, `br` first enters the snapshot restore phase. This phase follows the same process as the preceding [snapshot restore](#snapshot-restore-1): BR records the checkpoint data, the upstream cluster ID, and BackupTS of the backup data (that is, the start time point `start-ts` of log restore) in the `__TiDB_BR_Temporary_Snapshot_Restore_Checkpoint` database. If restore fails during this phase, you cannot adjust the `start-ts` of log restore when resuming checkpoint restore. +During the initial restore, `br` first enters the snapshot restore phase. BR records the checkpoint data, the upstream cluster ID, BackupTS of the backup data (that is, the start time point `start-ts` of log restore) and the restored time point `restored-ts` of log restore in the `__TiDB_BR_Temporary_Snapshot_Restore_Checkpoint` database. If restore fails during this phase, you cannot adjust the `start-ts` and `restored-ts` of log restore when resuming checkpoint restore. When entering the log restore phase during the initial restore, `br` creates a `__TiDB_BR_Temporary_Log_Restore_Checkpoint` database in the target cluster. This database records checkpoint data, the upstream cluster ID, and the restore time range (`start-ts` and `restored-ts`). If restore fails during this phase, you need to specify the same `start-ts` and `restored-ts` as recorded in the checkpoint database when retrying. Otherwise, `br` will report an error and prompt that the current specified restore time range or upstream cluster ID is different from the checkpoint record. If the restore cluster has been cleaned, you can manually delete the `__TiDB_BR_Temporary_Log_Restore_Checkpoint` database and retry with a different backup. Before entering the log restore phase during the initial restore, `br` constructs a mapping of upstream and downstream cluster database and table IDs at the `restored-ts` time point. This mapping is persisted in the system table `mysql.tidb_pitr_id_map` to prevent duplicate allocation of database and table IDs. Deleting data from `mysql.tidb_pitr_id_map` might lead to inconsistent PITR restore data. + +## Implementation details: store checkpoint data in the external storage + +> **Note:** +> +> Starting from v9.0.0, BR stores checkpoint data in the downstream cluster by default. You can specify an external storage for checkpoint data using the `--checkpoint-storage` parameter. For example: +> +> ```shell +> ./br restore full -s "s3://backup-bucket/backup-prefix" --checkpoint-storage "s3://temp-bucket/checkpoints" +> ``` + +In the external storage, the directory structure of the checkpoint data is as follows: + +- Root path `restore-{downstream-cluster-ID}` uses the downstream cluster ID `{downstream-cluster-ID}` to distinguish between different restore clusters. +- Path `restore-{downstream-cluster-ID}/log` stores log file checkpoint data during the log restore phase. +- Path `restore-{downstream-cluster-ID}/sst` stores checkpoint data of the SST files that are not backed up by log backup during the log restore phase. +- Path `restore-{downstream-cluster-ID}/snapshot` stores checkpoint data during the snapshot restore phase. + +``` +. +`-- restore-{downstream-cluster-ID} + |-- log + | |-- checkpoint.meta + | |-- data + | | |-- {uuid}.cpt + | | |-- {uuid}.cpt + | | `-- {uuid}.cpt + | |-- ingest_index.meta + | `-- progress.meta + |-- snapshot + | |-- checkpoint.meta + | |-- checksum + | | |-- {uuid}.cpt + | | |-- {uuid}.cpt + | | `-- {uuid}.cpt + | `-- data + | |-- {uuid}.cpt + | |-- {uuid}.cpt + | `-- {uuid}.cpt + `-- sst + `-- checkpoint.meta +``` + +Checkpoint restore operations are divided into two parts: snapshot restore and PITR restore. + +### Snapshot restore + +During the initial restore, `br` creates a `restore-{downstream-cluster-ID}/snapshot` path in the target cluster. The path records checkpoint data, the upstream cluster ID, and the BackupTS of the backup data. + +If the restore fails, you can retry it using the same command. `br` will automatically read the checkpoint information from the specified external storage path and resume from the last restore point. + +If the restore fails and you try to restore backup data with different checkpoint information to the same cluster, `br` reports an error. It indicates that the current upstream cluster ID or BackupTS is different from the checkpoint record. If the restore cluster has been cleaned, you can manually clean up the checkpoint data in the external storage or specify another external storage path to store checkpoint data, and retry with a different backup. + +### PITR restore + +[PITR (Point-in-time recovery)](/br/br-pitr-guide.md) consists of snapshot restore and log restore phases. + +During the initial restore, `br` first enters the snapshot restore phase. BR records the checkpoint data, the upstream cluster ID, BackupTS of the backup data (that is, the start time point `start-ts` of log restore) and the restored time point `restored-ts` of log restore in the `restore-{downstream-cluster-ID}/snapshot` path. If restore fails during this phase, you cannot adjust the `start-ts` and `restored-ts` of log restore when resuming checkpoint restore. + +When entering the log restore phase during the initial restore, `br` creates a `restore-{downstream-cluster-ID}/log` path in the target cluster. This path records checkpoint data, the upstream cluster ID, and the restore time range (`start-ts` and `restored-ts`). If restore fails during this phase, you need to specify the same `start-ts` and `restored-ts` as recorded in the checkpoint database when retrying. Otherwise, `br` will report an error and prompt that the current specified restore time range or upstream cluster ID is different from the checkpoint record. If the restore cluster has been cleaned, you can manually clean up the checkpoint data in the external storage or specify another external storage path to store checkpoint data, and retry with a different backup. + +Before entering the log restore phase during the initial restore, `br` constructs a mapping of the database and table IDs in the upstream and downstream clusters at the `restored-ts` time point. This mapping is persisted in the system table `mysql.tidb_pitr_id_map` to prevent duplicate allocation of database and table IDs. Deleting data from `mysql.tidb_pitr_id_map` might lead to inconsistent PITR restore data. diff --git a/br/br-pitr-manual.md b/br/br-pitr-manual.md index e36d345c3384e..b3f007c8976a1 100644 --- a/br/br-pitr-manual.md +++ b/br/br-pitr-manual.md @@ -495,3 +495,25 @@ tiup br restore point --pd="${PD_IP}:2379" --master-key-crypter-method aes128-ctr --master-key "local:///path/to/master.key" ``` + +### Compatibility between ongoing log backup and snapshot restore + +Starting from v9.0.0, when a log backup task is running, if all of the following conditions are met, you can still perform snapshot restore (`br restore [full|database|table]`) and allow the restored data to be properly recorded by the ongoing log backup (hereinafter referred to as "log backup"): + +- The node performing backup and restore operations has the following necessary permissions: + - Read access to the external storage containing the backup source, for snapshot restore + - Write access to the target external storage used by the log backup +- The target external storage for the log backup is Amazon S3 (`s3://`), Google Cloud Storage (`gcs://`), or Azure Blob Storage (`azblob://`). +- The data to be restored uses the same type of external storage as the target storage for the log backup. +- Neither the data to be restored nor the log backup has enabled local encryption. For details, see [log backup encryption](#encrypt-the-log-backup-data) and [snapshot backup encryption](/br/br-snapshot-manual.md#encrypt-the-backup-data). + +If any of the above conditions are not met, or if you need to perform a point-in-time recovery, while a log backup task is running, BR refuses to proceed with the data recovery. In this case, you can complete the recovery by following these steps: + +1. [Stop the log backup task](#stop-a-log-backup-task). +2. Perform the data restore. +3. After the restore is complete, perform a new snapshot backup. +4. [Restart the log backup task](#restart-a-log-backup-task). + +> **Note:** +> +> When restoring a log backup that contains records of snapshot (full) restore data, you must use BR v9.0.0 or later. Otherwise, restoring the recorded full restore data might fail. \ No newline at end of file diff --git a/cached-tables.md b/cached-tables.md index f0609a3b92931..67a5ce8671b40 100644 --- a/cached-tables.md +++ b/cached-tables.md @@ -15,7 +15,7 @@ The cached table feature is suitable for tables with the following characteristi - The data volume of the table is small, for example, less than 4 MiB. - The table is read-only or rarely updated, for example, with a write QPS (queries per second) of less than 10 times per minute. -- The table is frequently accessed, and you expect a better read performance, for example, when encountering hotspots on small tables during direct reads from from TiKV. +- The table is frequently accessed, and you expect a better read performance, for example, when encountering hotspots on small tables during direct reads from TiKV. When the data volume of the table is small but the data is frequently accessed, the data is concentrated on a Region in TiKV and makes it a hotspot Region, which affects the performance. Therefore, the typical usage scenarios of cached tables are as follows: diff --git a/dashboard/dashboard-access.md b/dashboard/dashboard-access.md index 7169be86f219e..35f6e74038eab 100644 --- a/dashboard/dashboard-access.md +++ b/dashboard/dashboard-access.md @@ -14,7 +14,7 @@ To access TiDB Dashboard, visit via your brows ## Access TiDB Dashboard when multiple PD instances are deployed -When multiple multiple PD instances are deployed in your cluster and you can directly access **every** PD instance and port, you can simply replace `127.0.0.1:2379` in the address with **any** PD instance address and port. +When multiple PD instances are deployed in your cluster and you can directly access **every** PD instance and port, you can simply replace `127.0.0.1:2379` in the address with **any** PD instance address and port. > **Note:** > diff --git a/dashboard/dashboard-diagnostics-report.md b/dashboard/dashboard-diagnostics-report.md index defe049f2682c..85232f994ba58 100644 --- a/dashboard/dashboard-diagnostics-report.md +++ b/dashboard/dashboard-diagnostics-report.md @@ -33,7 +33,7 @@ In this report, some small buttons are described as follows: All monitoring metrics basically correspond to those on the TiDB Grafana monitoring dashboard. After a module is found to be abnormal, you can view more monitoring information on the TiDB Grafana. -In addition, the `TOTAL_TIME` and `TOTAL_COUNT` metrics in this report are monitoring data read from Prometheus, so calculation inaccuracy might exits in their statistics. +In addition, the `TOTAL_TIME` and `TOTAL_COUNT` metrics in this report are monitoring data read from Prometheus, so calculation inaccuracy might exist in their statistics. Each part of this report is introduced as follows. diff --git a/dashboard/dashboard-faq.md b/dashboard/dashboard-faq.md index 361451200ac17..ab0f5d7b25b93 100644 --- a/dashboard/dashboard-faq.md +++ b/dashboard/dashboard-faq.md @@ -30,7 +30,7 @@ If you have deployed TiDB using the `tiup cluster` or `tiup playground` command, The **QPS** and **Latency** sections on the **Overview** page require a cluster with Prometheus deployed. Otherwise, the error is shown. You can solve this problem by deploying a Prometheus instance in the cluster. -If you still encounter this problem when the Prometheus instance has been deployed, the possible reason is that your deployment tool is out of date (TiUP or TiDB Operator), and your tool does not automatically report metrics addresses, which makes TiDB Dashboard unable to query metrics. You can upgrade you deployment tool to the latest version and try again. +If you still encounter this problem when the Prometheus instance has been deployed, the possible reason is that your deployment tool is out of date (TiUP or TiDB Operator), and your tool does not automatically report metrics addresses, which makes TiDB Dashboard unable to query metrics. You can upgrade your deployment tool to the latest version and try again. If your deployment tool is TiUP, take the following steps to solve this problem. For other deployment tools, refer to the corresponding documents of those tools. diff --git a/ddl-introduction.md b/ddl-introduction.md index 83ba6d7fffe71..07710780c7bf1 100644 --- a/ddl-introduction.md +++ b/ddl-introduction.md @@ -86,7 +86,7 @@ To improve the user experience of DDL execution, starting from v6.2.0, TiDB enab + DDL statements to be performed on the same table are mutually blocked. + `DROP DATABASE` and DDL statements that affect all objects in the database are mutually blocked. + Adding indexes and column type changes on different tables can be executed concurrently. -+ A logical DDL statement must wait for the previous logical DDL statement to be executed before it can be executed. ++ Starting from v8.2.0, [logical DDL statements](/ddl-introduction.md#types-of-ddl-statements) for different tables can be executed in parallel. + In other cases, DDL can be executed based on the level of availability for concurrent DDL execution. Specifically, TiDB 6.2.0 has enhanced the DDL execution framework in the following aspects: diff --git a/deploy-monitoring-services.md b/deploy-monitoring-services.md index 188027ff3457d..b124889bb8cd7 100644 --- a/deploy-monitoring-services.md +++ b/deploy-monitoring-services.md @@ -6,9 +6,7 @@ aliases: ['/docs/dev/deploy-monitoring-services/','/docs/dev/how-to/monitor/moni # Deploy Monitoring Services for the TiDB Cluster -This document is intended for users who want to manually deploy TiDB monitoring and alert services. - -If you deploy the TiDB cluster using TiUP, the monitoring and alert services are automatically deployed, and no manual deployment is needed. +This document is intended for users who want to manually deploy TiDB monitoring and alert services. If you deploy the TiDB cluster using TiUP, the monitoring and alert services are automatically deployed, and no manual deployment is needed. [TiDB Dashboard](/dashboard/dashboard-intro.md) is built into the PD component and does not require an independent deployment. ## Deploy Prometheus and Grafana diff --git a/develop/dev-guide-build-cluster-in-cloud.md b/develop/dev-guide-build-cluster-in-cloud.md index 249c57f3307bc..f6cfcb08303bb 100644 --- a/develop/dev-guide-build-cluster-in-cloud.md +++ b/develop/dev-guide-build-cluster-in-cloud.md @@ -176,7 +176,7 @@ Expected output: +-------------------+ ``` -If your actual output is similar to the expected output, congratulations, you have successfully execute a SQL statement on TiDB Cloud. +If your actual output is similar to the expected output, congratulations, you have successfully executed a SQL statement on TiDB Cloud. ## Need help? diff --git a/develop/dev-guide-create-table.md b/develop/dev-guide-create-table.md index be32bfb337687..8d8722cbba835 100644 --- a/develop/dev-guide-create-table.md +++ b/develop/dev-guide-create-table.md @@ -5,7 +5,7 @@ summary: Learn the definitions, rules, and guidelines in table creation. # Create a Table -This document introduces how to create tables using the SQL statement and the related best practices. An example of the TiDB-based [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application) is provided to illustrate the best practices. +This document introduces how to create tables using the SQL statement and the related best practices. An example of the TiDB-based [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application is provided to illustrate the best practices. ## Before you start diff --git a/develop/dev-guide-gui-datagrip.md b/develop/dev-guide-gui-datagrip.md index 99a8bf7b7d827..f3089d4e05921 100644 --- a/develop/dev-guide-gui-datagrip.md +++ b/develop/dev-guide-gui-datagrip.md @@ -82,7 +82,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you've sele 8. Click **Test Connection** to validate the connection to the TiDB Cloud Serverless cluster. - ![Test the connection to a TiDB Cloud Serverless clustser](/media/develop/datagrip-test-connection.jpg) + ![Test the connection to a TiDB Cloud Serverless cluster](/media/develop/datagrip-test-connection.jpg) 9. Click **OK** to save the connection configuration. diff --git a/develop/dev-guide-gui-navicat.md b/develop/dev-guide-gui-navicat.md index 1bd675599a5c2..a6f0e2295ef8b 100644 --- a/develop/dev-guide-gui-navicat.md +++ b/develop/dev-guide-gui-navicat.md @@ -62,7 +62,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se > > If you have created a password before, you can either use the original password or click **Reset Password** to generate a new one. -5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. +5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) @@ -99,7 +99,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se 4. Click **CA cert** to download the CA certificate. -5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. +5. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) @@ -124,7 +124,7 @@ Connect to your TiDB cluster depending on the TiDB deployment option you have se
-1. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Venfor Filter** list, and double-click **TiDB** in the right panel. +1. Launch Navicat Premium, click **Connection** in the upper-left corner, select **PingCAP** from the **Vendor Filter** list, and double-click **TiDB** in the right panel. ![Navicat: add new connection](/media/develop/navicat-premium-add-new-connection.png) diff --git a/develop/dev-guide-index-best-practice.md b/develop/dev-guide-index-best-practice.md index a088c91fc5d0f..efb3db870c936 100644 --- a/develop/dev-guide-index-best-practice.md +++ b/develop/dev-guide-index-best-practice.md @@ -32,7 +32,7 @@ CREATE TABLE `books` ( - Create an appropriate index based on your application. In principle, create indexes only on the columns to be used in queries to improve performance. The following cases are suitable for creating an index: - Columns with a high distinction degree can significantly reduce the number of filtered rows. For example, it is recommended to create an index on the personal ID number, but not on the gender. - - Use combined indexes when querying with multiple conditions. Note that columns with equivalent conditions need to be placed in the front of the combined index. Here is an example: if the `select* from t where c1 = 10 and c2 = 100 and c3 > 10` query is frequently used, consider creating a combined index `Index cidx (c1, c2, c3)`, so that a index prefix can be constructed to scan by query conditions. + - Use combined indexes when querying with multiple conditions. Note that columns with equivalent conditions need to be placed in the front of the combined index. Here is an example: if the `select* from t where c1 = 10 and c2 = 100 and c3 > 10` query is frequently used, consider creating a combined index `Index cidx (c1, c2, c3)`, so that an index prefix can be constructed to scan by query conditions. - Name your secondary index meaningfully, and it is recommended to follow the table naming conventions of your company or organization. If such naming conventions do not exist, follow the rules in [Index Naming Specification](/develop/dev-guide-object-naming-guidelines.md). diff --git a/develop/dev-guide-sql-development-specification.md b/develop/dev-guide-sql-development-specification.md index 729f3d955feb5..c19f431c97150 100644 --- a/develop/dev-guide-sql-development-specification.md +++ b/develop/dev-guide-sql-development-specification.md @@ -48,7 +48,7 @@ This document introduces some general development specifications for using SQL. - Replace `OR` with `IN` or `UNION`. The number of `IN` must be less than `300`. - Avoid using the `%` prefix for fuzzy prefix queries. - If the application uses **Multi Statements** to execute SQL, that is, multiple SQLs are joined with semicolons and sent to the client for execution at once, TiDB only returns the result of the first SQL execution. -- When you use expressions, check if the expressions support computing push-down to the storage layer (TiKV or TiFlash). If not, you should expect more memory consumption and even OOM at the TiDB layer. Computing that can be pushe down the storage layer is as follows: +- When you use expressions, check if the expressions support computing push-down to the storage layer (TiKV or TiFlash). If not, you should expect more memory consumption and even OOM at the TiDB layer. Computing that can be pushed down to the storage layer is as follows: - [TiFlash supported push-down calculations](/tiflash/tiflash-supported-pushdown-calculations.md). - [TiKV - List of Expressions for Pushdown](/functions-and-operators/expressions-pushed-down.md). - [Predicate push down](/predicate-push-down.md). diff --git a/develop/dev-guide-use-subqueries.md b/develop/dev-guide-use-subqueries.md index ae7dde78d44f0..9e6fe2c86b23d 100644 --- a/develop/dev-guide-use-subqueries.md +++ b/develop/dev-guide-use-subqueries.md @@ -9,7 +9,7 @@ This document introduces subquery statements and categories in TiDB. ## Overview -An subquery is a query within another SQL query. With subquery, the query result can be used in another query. +A subquery is a query within another SQL query. With subquery, the query result can be used in another query. The following takes the [Bookshop](/develop/dev-guide-bookshop-schema-design.md) application as an example to introduce subquery. diff --git a/dm/dm-continuous-data-validation.md b/dm/dm-continuous-data-validation.md index 1507761b1e76f..d42748d50ecd4 100644 --- a/dm/dm-continuous-data-validation.md +++ b/dm/dm-continuous-data-validation.md @@ -282,7 +282,7 @@ The lifecycle of continuous data validation is as follows: The detailed implementation of continuous data validation is as follows: 1. The validator pulls a binlog event from the upstream and gets the changed rows: - - The validator only checks a event that has been incrementally migrated by the syncer. If the event has not been processed by the syncer, the validator pauses and waits for the syncer to complete processing. + - The validator only checks an event that has been incrementally migrated by the syncer. If the event has not been processed by the syncer, the validator pauses and waits for the syncer to complete processing. - If the event has been processed by the syncer, the validator moves on to the following steps. 2. The validator parses the binlog event and filters out the rows based on the block and allow lists, the table filters, and table routing. After that, the validator submits the changed rows to the validation worker that runs in the background. 3. The validation worker merges the changed rows that affect the same table and the same primary key to avoid validating "expired" data. The changed rows are cached in memory. diff --git a/dm/dm-webui-guide.md b/dm/dm-webui-guide.md index 847d7dd40fbd8..fcf02fd95b3a4 100644 --- a/dm/dm-webui-guide.md +++ b/dm/dm-webui-guide.md @@ -39,7 +39,7 @@ When [OpenAPI](/dm/dm-open-api.md#maintain-dm-clusters-using-openapi) is enabled Before creating a migration task, you need to create the data source information of the upstream for the replication task. You can create the upstream configuration in the **Source** page. When creating sources, pay attention to the following items: -- If there is a auto failover between primary and secondary instance, enable GTID in the upstream MySQL and set GTID to `True` when creating the upstream configuration; otherwise, the migration task will be interrupted during the failover (except for AWS Aurora). +- If there is an auto failover between primary and secondary instance, enable GTID in the upstream MySQL and set GTID to `True` when creating the upstream configuration; otherwise, the migration task will be interrupted during the failover (except for AWS Aurora). - If a MySQL instance needs to be temporarily offline, you can disable the instance. However, when the MySQL instance is being disabled, other MySQL instances running migration tasks should not execute DDL operations; otherwise, the disabled instance cannot properly migrate data after it is enabled. - When multiple migration tasks use the same upstream, it might cause additional stress. Enabling relay log can reduce the impact on the upstream, so it is recommended to enable relay log. diff --git a/dm/maintain-dm-using-tiup.md b/dm/maintain-dm-using-tiup.md index 0fcc68b1bb1f3..0e8ff6302c583 100644 --- a/dm/maintain-dm-using-tiup.md +++ b/dm/maintain-dm-using-tiup.md @@ -389,7 +389,7 @@ tiup dmctl --master-addr master1:8261 operate-source create /tmp/source1.yml All operations above performed on the cluster machine use the SSH client embedded in TiUP to connect to the cluster and execute commands. However, in some scenarios, you might also need to use the SSH client native to the control machine system to perform such cluster operations. For example: -- To use a SSH plug-in for authentication +- To use an SSH plug-in for authentication - To use a customized SSH client Then you can use the `--native-ssh` command-line flag to enable the system-native command-line tool: diff --git a/ecosystem-tool-user-guide.md b/ecosystem-tool-user-guide.md index 3eb8661818bdd..f1a9f1fbc9b81 100644 --- a/ecosystem-tool-user-guide.md +++ b/ecosystem-tool-user-guide.md @@ -75,7 +75,7 @@ The following are the basics of Dumpling: > **Note:** > -> PingCAP previously maintained a fork of the [mydumper project](https://github.com/maxbube/mydumper) with enhancements specific to TiDB. Starting from v7.5.0, [Mydumper](https://docs.pingcap.com/tidb/v4.0/mydumper-overview) is deprecated and most of its features have been replaced by [Dumpling](/dumpling-overview.md). It is strongly recommended that you use Dumpling instead of mydumper. +> PingCAP previously maintained a fork of the [mydumper project](https://github.com/maxbube/mydumper) with enhancements specific to TiDB. Starting from v7.5.0, [Mydumper](https://docs-archive.pingcap.com/tidb/v4.0/mydumper-overview/) is deprecated and most of its features have been replaced by [Dumpling](/dumpling-overview.md). It is strongly recommended that you use Dumpling instead of mydumper. ### Full data import - TiDB Lightning @@ -135,4 +135,4 @@ The following are the basics of sync-diff-inspector: ## OLAP Query tool - TiSpark -[TiSpark](/tispark-overview.md) is a product developed by PingCAP to address the complexiy of OLAP queries. It combines strengths of Spark, and the features of distributed TiKV clusters and TiDB to provide a one-stop Hybrid Transactional and Analytical Processing (HTAP) solution. +[TiSpark](/tispark-overview.md) is a product developed by PingCAP to address the complexity of OLAP queries. It combines strengths of Spark, and the features of distributed TiKV clusters and TiDB to provide a one-stop Hybrid Transactional and Analytical Processing (HTAP) solution. diff --git a/enable-tls-between-components.md b/enable-tls-between-components.md index d7b87cf4d7981..9e604a6e2b218 100644 --- a/enable-tls-between-components.md +++ b/enable-tls-between-components.md @@ -128,11 +128,23 @@ Currently, it is not supported to only enable encrypted transmission of some spe cdc server --pd=https://127.0.0.1:2379 --log-file=ticdc.log --addr=0.0.0.0:8301 --advertise-addr=127.0.0.1:8301 --ca=/path/to/ca.pem --cert=/path/to/ticdc-cert.pem --key=/path/to/ticdc-key.pem ``` + - TiProxy + + Configure in the configuration file, and set the corresponding URL to `https`: + + ```toml + [security] + [server-http-tls] + ca = "/path/to/ca.pem" + cert = "/path/to/tiproxy-server.pem" + key = "/path/to/tiproxy-server-key.pem" + ``` + Now, encrypted transmission among TiDB components is enabled. > **Note:** > - > After enabling encrypted transmission in a TiDB cluster, if you need to connect to the cluster using tidb-ctl, tikv-ctl, or pd-ctl, specify the client certificate. For example: + > After enabling encrypted transmission in a TiDB cluster, if you need to connect to the cluster using tidb-ctl, tikv-ctl, pd-ctl, or tiproxyctl, specify the client certificate. For example: {{< copyable "shell-regular" >}} @@ -169,7 +181,7 @@ To verify the caller's identity for a component, you need to mark the certificat ```toml [security] - cluster-verify-cn = ["tidb", "test-client", "prometheus"] + cluster-verify-cn = ["tidb", "tiproxy", "test-client", "prometheus"] ``` - TiKV @@ -187,7 +199,7 @@ To verify the caller's identity for a component, you need to mark the certificat ```toml [security] - cert-allowed-cn = ["tidb", "pd", "tikv", "tiflash", "test-client", "prometheus"] + cert-allowed-cn = ["tidb", "pd", "tikv", "tiflash", "tiproxy", "test-client", "prometheus"] ``` - TiFlash (New in v4.0.5) @@ -206,11 +218,21 @@ To verify the caller's identity for a component, you need to mark the certificat cert-allowed-cn = ["tidb", "tikv", "tiflash", "prometheus"] ``` +- TiProxy (New in v1.4.0) + + Configure in the configuration file: + + ```toml + [security] + [server-http-tls] + cert-allowed-cn = ["tiproxy", "tidb", "test-client", "prometheus"] + ``` + ## Reload certificates -- If your TiDB cluster is deployed in a local data center, to reload the certificates and keys, TiDB, PD, TiKV, TiFlash, TiCDC, and all kinds of clients reread the current certificates and key files each time a new connection is created, without restarting the TiDB cluster. +- If your TiDB cluster is deployed in a local data center, to reload the certificates and keys, TiDB, PD, TiKV, TiFlash, TiCDC, TiProxy, and all kinds of clients reread the current certificates and key files each time a new connection is created, without restarting the TiDB cluster. -- If your TiDB cluster is deployed on your own managed cloud, make sure that the issuance of TLS certificates is integrated with the certificate management service of the cloud provider. The TLS certificates of the TiDB, PD, TiKV, TiFlash, and TiCDC components can be automatically rotated without restarting the TiDB cluster. +- If your TiDB cluster is deployed on your own managed cloud, make sure that the issuance of TLS certificates is integrated with the certificate management service of the cloud provider. The TLS certificates of the TiDB, PD, TiKV, TiFlash, TiCDC, and TiProxy components can be automatically rotated without restarting the TiDB cluster. ## Certificate validity diff --git a/encryption-at-rest.md b/encryption-at-rest.md index b7f0a3bcc7af5..d8276dad349e9 100644 --- a/encryption-at-rest.md +++ b/encryption-at-rest.md @@ -32,7 +32,7 @@ SM4 encryption is only supported in v6.3.0 and later versions of TiKV. TiKV vers ### TiFlash -TiFlash supports encryption at rest. Data keys are generated by TiFlash. All files (including data files, schema files, and temporary files) written into TiFlash (including TiFlash Proxy) are encrypted using the current data key. The encryption algorithms, the encryption configuration (in the [`tiflash-learner.toml` file](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file) supported by TiFlash, and the meanings of monitoring metrics are consistent with those of TiKV. +TiFlash supports encryption at rest. Data keys are generated by TiFlash. All files (including data files, schema files, and temporary files) written into TiFlash (including TiFlash Proxy) are encrypted using the current data key. The encryption algorithms, the encryption configuration (in the [`tiflash-learner.toml` file](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file) supported by TiFlash), and the meanings of monitoring metrics are consistent with those of TiKV. If you have deployed TiFlash with Grafana, you can check the **TiFlash-Proxy-Details** -> **Encryption** panel. diff --git a/functions-and-operators/json-functions/json-functions-validate.md b/functions-and-operators/json-functions/json-functions-validate.md index a01a47c362c4d..fc27127ebd694 100644 --- a/functions-and-operators/json-functions/json-functions-validate.md +++ b/functions-and-operators/json-functions/json-functions-validate.md @@ -130,7 +130,7 @@ SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables"]}',@j); 1 row in set (0.00 sec) ``` -In the preceding output, you can see that see that validation of the presence of the `fruits` and `vegetables` attributes succeeds. +In the preceding output, you can see that the validation of the presence of the `fruits` and `vegetables` attributes succeeds. ```sql SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j); @@ -145,7 +145,7 @@ SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j); 1 row in set (0.00 sec) ``` -In the preceding output, you can see that see that validation of the presence of the `fruits`, `vegetables` and `grains` attributes fails because `grains` is not present. +In the preceding output, you can see that the validation of the presence of the `fruits`, `vegetables` and `grains` attributes fails because `grains` is not present. Now validate that `fruits` is an array. diff --git a/functions-and-operators/locking-functions.md b/functions-and-operators/locking-functions.md index 08a261cfa241c..14238fefa62aa 100644 --- a/functions-and-operators/locking-functions.md +++ b/functions-and-operators/locking-functions.md @@ -20,6 +20,6 @@ TiDB supports most of the user-level [locking functions](https://dev.mysql.com/d ## MySQL compatibility * The minimum timeout permitted by TiDB is 1 second, and the maximum timeout is 1 hour (3600 seconds). This differs from MySQL, where both 0 second and unlimited timeouts (`timeout=-1`) are permitted. TiDB will automatically convert out-of-range values to the nearest permitted value and convert `timeout=-1` to 3600 seconds. -* TiDB does not automatically detect deadlocks caused by user-level locks. Deadlocked sessions will timeout after a maximum of 1 hour, but can also be manually resolved by using [`KILL`](/sql-statements/sql-statement-kill.md) on one of the affected sessions. You can also prevent deadlocks by always acquiring user-level locks in the same order. +* TiDB does not automatically detect deadlocks caused by user-level locks. Deadlocked sessions will time out after a maximum of 1 hour, but can also be manually resolved by using [`KILL`](/sql-statements/sql-statement-kill.md) on one of the affected sessions. You can also prevent deadlocks by always acquiring user-level locks in the same order. * Locks take effect on all TiDB servers in the cluster. This differs from MySQL Cluster and Group Replication where locks are local to a single server. * `IS_USED_LOCK()` returns `1` if it is called from another session and is unable to return the ID of the process that is holding the lock. diff --git a/functions-and-operators/string-functions.md b/functions-and-operators/string-functions.md index f671ee9d853be..9f1ef27a07c0d 100644 --- a/functions-and-operators/string-functions.md +++ b/functions-and-operators/string-functions.md @@ -134,7 +134,7 @@ SELECT CustomerName, BIT_LENGTH(CustomerName) AS BitLengthOfName FROM Customers; ### [`CHAR()`](https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_char) -The `CHAR()` function is used to get the corresponding character of a specific ASCII value. It performs the opposite operation of `ASCII()`, which returns the ASCII value of a specific character. If multiple arguments are supplied, the function works on all arguments and are then concaternated together. +The `CHAR()` function is used to get the corresponding character of a specific ASCII value. It performs the opposite operation of `ASCII()`, which returns the ASCII value of a specific character. If multiple arguments are supplied, the function works on all arguments and are then concatenated together. Examples: diff --git a/geo-distributed-deployment-topology.md b/geo-distributed-deployment-topology.md index 2a227cc467cfc..2003c653c42f8 100644 --- a/geo-distributed-deployment-topology.md +++ b/geo-distributed-deployment-topology.md @@ -67,7 +67,7 @@ This section describes the key parameter configuration of the TiDB geo-distribut > **Note:** > -> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks' before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. +> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks` before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. #### PD parameters diff --git a/identify-slow-queries.md b/identify-slow-queries.md index 0962505d3ea8d..ff2304f737f25 100644 --- a/identify-slow-queries.md +++ b/identify-slow-queries.md @@ -593,7 +593,7 @@ ADMIN SHOW SLOW TOP [internal | all] N ADMIN SHOW SLOW recent 10 ``` -`top N` shows the slowest N query records recently (within a few days). If the `internal` option is provided, the returned results would be the inner SQL executed by the system; If the `all` option is provided, the returned results would be the user's SQL combinated with inner SQL; Otherwise, this command would only return the slow query records from the user's SQL. +`top N` shows the slowest N query records recently (within a few days). If the `internal` option is provided, the returned results would be the inner SQL executed by the system; If the `all` option is provided, the returned results would be the user's SQL combined with inner SQL; Otherwise, this command would only return the slow query records from the user's SQL. {{< copyable "sql" >}} diff --git a/information-schema/client-errors-summary-by-user.md b/information-schema/client-errors-summary-by-user.md index 797897bae8502..b0cf4bb59e7aa 100644 --- a/information-schema/client-errors-summary-by-user.md +++ b/information-schema/client-errors-summary-by-user.md @@ -13,7 +13,7 @@ The table `CLIENT_ERRORS_SUMMARY_BY_USER` provides a summary of SQL errors and w * Permission errors. * A table that does not exist. -Client errors are returned to the client via the MySQL server protocol, where applications are expected to take appropriate action. The `INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER` table provides an useful method to inspect errors in the scenario where applications are not correctly handling (or logging) errors returned by the TiDB server. +Client errors are returned to the client via the MySQL server protocol, where applications are expected to take appropriate action. The `INFORMATION_SCHEMA.CLIENT_ERRORS_SUMMARY_BY_USER` table provides a useful method to inspect errors in the scenario where applications are not correctly handling (or logging) errors returned by the TiDB server. Because `CLIENT_ERRORS_SUMMARY_BY_USER` summarizes the errors on a per-user basis, it can be useful to diagnose scenarios where one user server is generating more errors than other servers. Possible scenarios include: diff --git a/information-schema/information-schema-sql-diagnostics.md b/information-schema/information-schema-sql-diagnostics.md index ab65d80a104df..5ce5342e38df6 100644 --- a/information-schema/information-schema-sql-diagnostics.md +++ b/information-schema/information-schema-sql-diagnostics.md @@ -19,7 +19,7 @@ The SQL diagnostic system has the following advantages: The SQL diagnostic system consists of three major parts: -+ **Cluster information table**: The SQL diagnostics system introduces cluster information tables that provide a unified way to get the discrete information of each instance. This system fully integrates the cluster topology, hardware information, software information, kernel parameters, monitoring, system information, slow queries, statements, and logs of the entire cluster into the table. So you can query these information using SQL statements. ++ **Cluster information table**: The SQL diagnostics system introduces cluster information tables that provide a unified way to get the discrete information of each instance. This system fully integrates the cluster topology, hardware information, software information, kernel parameters, monitoring, system information, slow queries, statements, and logs of the entire cluster into the table. So you can query this information using SQL statements. + **Cluster monitoring table**: The SQL diagnostic system introduces cluster monitoring tables. All of these tables are in `metrics_schema`, and you can query monitoring information using SQL statements. Compared to the visualized monitoring before v4.0, you can use this SQL-based method to perform correlated queries on all the monitoring information of the entire cluster, and compare the results of different time periods to quickly identify performance bottlenecks. Because the TiDB cluster has many monitoring metrics, the SQL diagnostic system also provides monitoring summary tables, so you can find abnormal monitoring items more easily. diff --git a/information-schema/information-schema-statistics.md b/information-schema/information-schema-statistics.md index 2b02a35794522..b353f7a5fbc0e 100644 --- a/information-schema/information-schema-statistics.md +++ b/information-schema/information-schema-statistics.md @@ -58,7 +58,7 @@ Fields in the `STATISTICS` table are described as follows: * `INDEX_TYPE`: The type of the index. * `COMMENT`: Other information related to the index. * `INDEX_COMMENT`: Any comment with comment attribute provided for the index when creating the index. -* `IS_VISIBLE`: Whether the optimizer can use this index. +* `IS_VISIBLE`: Whether this index is visible or not. See also [Invisible index](/sql-statements/sql-statement-create-index.md#invisible-index). * `Expression` For the index key of the non-expression part, this value is `NULL`; for the index key of the expression part, this value is the expression itself. Refer to [Expression Index](/sql-statements/sql-statement-create-index.md#expression-index). The following statements are equivalent: diff --git a/information-schema/information-schema-tables.md b/information-schema/information-schema-tables.md index d3d3613f2f25f..8ae5df9a46bf1 100644 --- a/information-schema/information-schema-tables.md +++ b/information-schema/information-schema-tables.md @@ -106,7 +106,7 @@ The description of columns in the `TABLES` table is as follows: * `MAX_DATA_LENGTH`: The maximum data length. The value is currently `0`, which means the data length has no upper limit. * `INDEX_LENGTH`: The index length. `INDEX_LENGTH` = `TABLE_ROWS` \* the sum of lengths of the columns in the index tuple. The replicas of TiKV are not taken into account. * `DATA_FREE`: Data fragment. The value is currently `0`. -* `AUTO_INCREMENT`: The current step of the auto- increment primary key. +* `AUTO_INCREMENT`: The current step of the auto-increment primary key. * `CREATE_TIME`: The time at which the table is created. * `UPDATE_TIME`: The time at which the table is updated. * `CHECK_TIME`: The time at which the table is checked. diff --git a/literal-values.md b/literal-values.md index f0048492460a6..d2ca476cb11b5 100644 --- a/literal-values.md +++ b/literal-values.md @@ -94,7 +94,7 @@ Date and time literal values can be represented in several formats, such as quot TiDB supports the following date formats: -* `'YYYY-MM-DD'` or `'YY-MM-DD'`: The `-` delimiter here is not strict. It can be any punctuation. For example, `'2017-08-24'`, `'2017&08&24'`, `'2012@12^31'` are all valid date formats. The only special punctuation is '.', which is is treated as a decimal point to separate the integer and fractional parts. Date and time can be separated by `T` or a white space. For example, `2017-8-24 10:42:00` and `2017-8-24T10:42:00` represents the same date and time. +* `'YYYY-MM-DD'` or `'YY-MM-DD'`: The `-` delimiter here is not strict. It can be any punctuation. For example, `'2017-08-24'`, `'2017&08&24'`, `'2012@12^31'` are all valid date formats. The only special punctuation is '.', which is treated as a decimal point to separate the integer and fractional parts. Date and time can be separated by `T` or a white space. For example, `2017-8-24 10:42:00` and `2017-8-24T10:42:00` represents the same date and time. * `'YYYYMMDDHHMMSS'` or `'YYMMDDHHMMSS'`: For example, `'20170824104520'` and `'170824104520'` are regarded as `'2017-08-24 10:45:20'`. However, if you provide a value out of range, such as `'170824304520'`, it is not treated as a valid date. Note that incorrect formats such as `YYYYMMDD HHMMSS`, `YYYYMMDD HH:MM:DD`, or `YYYY-MM-DD HHMMSS` will fail to insert. * `YYYYMMDDHHMMSS` or `YYMMDDHHMMSS`: Note that these formats have no single or double quotes, but a number. For example, `20170824104520` is interpreted as `'2017-08-24 10:45:20'`. diff --git a/media/tiproxy/tiproxy-balance-label.png b/media/tiproxy/tiproxy-balance-label.png index c291c40ba05ce5f4e2dc38cc3d5f87d8680d836d..44fee918cdcc6a8607a1ec848c205345da1a5cee 100644 GIT binary patch literal 98047 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˾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 diff --git a/optimizer-fix-controls.md b/optimizer-fix-controls.md index 8bed386a38cae..15fa3e1e3ad52 100644 --- a/optimizer-fix-controls.md +++ b/optimizer-fix-controls.md @@ -108,7 +108,7 @@ SET SESSION tidb_opt_fix_control = '44262:ON,44389:ON'; - As stated in the **Note** of [Explain Statements Using Index Merge](/explain-index-merge.md#examples), if the optimizer can choose the single index scan method (other than full table scan) for a query plan, the optimizer will not automatically use index merge. - You can remove this limitation by enabling this fix control. Removing this limitation enables the optimizer to choose index merge automatically in more queries, but might cause the optimizer to ignore the optimal execution plans. Therefore, it is recommended to conduct sufficient tests on actual use cases before removing this limitation to make sure that it will not cause performance regressions. -### [`54337`](https://github.com/pingcap/tidb/issues/54337) New in v8.2.0 +### [`54337`](https://github.com/pingcap/tidb/issues/54337) New in v8.3.0 - Default value: `OFF` - Possible values: `ON`, `OFF` diff --git a/optimizer-hints.md b/optimizer-hints.md index 4c26637579bcb..b54f012db7815 100644 --- a/optimizer-hints.md +++ b/optimizer-hints.md @@ -497,7 +497,7 @@ SELECT /*+ LIMIT_TO_COP() */ * FROM t WHERE a = 1 AND b > 10 ORDER BY c LIMIT 1; ### READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]]) -The `READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]])` hint tells the optimizer to read specific table(s) from specific storage engine(s). Currently, this hint supports two storage engine parameters - `TIKV` and `TIFLASH`. If a table has an alias, use the alias as the parameter of `READ_FROM_STORAGE()`; if the table does not has an alias, use the table's original name as the parameter. For example: +The `READ_FROM_STORAGE(TIFLASH[t1_name [, tl_name ...]], TIKV[t2_name [, tl_name ...]])` hint tells the optimizer to read specific table(s) from specific storage engine(s). Currently, this hint supports two storage engine parameters - `TIKV` and `TIFLASH`. If a table has an alias, use the alias as the parameter of `READ_FROM_STORAGE()`; if the table does not have an alias, use the table's original name as the parameter. For example: {{< copyable "sql" >}} diff --git a/pipelined-dml.md b/pipelined-dml.md index 858cae7b27ae9..7b3c0a1ea6854 100644 --- a/pipelined-dml.md +++ b/pipelined-dml.md @@ -102,6 +102,10 @@ If the `pipelined` field in the output is `true`, it indicates that Pipelined DM - The [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) system variable controls whether Pipelined DML is enabled at the session level. +- The [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) system variable controls the resource usage policy for Pipelined DML. When the following resource contention occurs, consider setting this variable to `conservative` to reduce the impact of Pipelined DML on cluster performance: + - TiKV nodes experience write hotspots and high load. + - The request latency of OLTP applications significantly increases. + - The write throughput of the cluster significantly decreases. - When [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `"bulk"`, the [`pessimistic-auto-commit`](/tidb-configuration-file.md#pessimistic-auto-commit-new-in-v600) configuration item behaves as if it is set to `false`. - Transactions executed using Pipelined DML are not subject to the size limit specified by the TiDB configuration item [`txn-total-size-limit`](/tidb-configuration-file.md#txn-total-size-limit). - For large transactions executed using Pipelined DML, transaction duration might increase. In such cases, the maximum TTL for the transaction lock is the larger value of [`max-txn-ttl`](/tidb-configuration-file.md#max-txn-ttl) or 24 hours. @@ -112,6 +116,10 @@ If the `pipelined` field in the output is `true`, it indicates that Pipelined DM - The [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) system variable controls whether Pipelined DML is enabled at the session level. +- The [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) system variable controls the resource usage policy for Pipelined DML. When the following resource contention occurs, consider setting this variable to `conservative` to reduce the impact of Pipelined DML on cluster performance: + - TiKV nodes experience write hotspots and high load. + - The request latency of OLTP applications significantly increases. + - The write throughput of the cluster significantly decreases. - When [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `"bulk"`, the [`pessimistic-auto-commit`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#pessimistic-auto-commit-new-in-v600) configuration item behaves as if it is set to `false`. - Transactions executed using Pipelined DML are not subject to the size limit specified by the TiDB configuration item [`txn-total-size-limit`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#txn-total-size-limit). - For large transactions executed using Pipelined DML, transaction duration might increase. In such cases, the maximum TTL for the transaction lock is the larger value of [`max-txn-ttl`](https://docs.pingcap.com/tidb/stable/tidb-configuration-file#max-txn-ttl) or 24 hours. diff --git a/privilege-management.md b/privilege-management.md index e9525983fa2cf..c0b1bb3df426c 100644 --- a/privilege-management.md +++ b/privilege-management.md @@ -282,6 +282,8 @@ Dynamic privileges include: * `RESTRICTED_USER_ADMIN` prohibits privilege owners to have their access revoked by SUPER users when SEM is enabled. * `RESTRICTED_CONNECTION_ADMIN` allows privilege owners to kill connections of `RESTRICTED_USER_ADMIN` users. This privilege affects `KILL` and `KILL TIDB` statements. * `RESTRICTED_REPLICA_WRITER_ADMIN` allows privilege owners to perform write or update operations without being affected when the read-only mode is enabled in the TiDB cluster. For details, see [`tidb_restricted_read_only`](/system-variables.md#tidb_restricted_read_only-new-in-v520). +* `TRAFFIC_CAPTURE_ADMIN` allows privilege owners to create, view, and cancel traffic capture jobs. For details, see [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md). +* `TRAFFIC_REPLAY_ADMIN` allows privilege owners to create, view, and cancel traffic replay jobs. For details, see [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md). To see the full set of dynamic privileges, execute the `SHOW PRIVILEGES` statement. Because plugins are permitted to add new privileges, the list of privileges that are assignable might differ based on your TiDB installation. @@ -498,6 +500,26 @@ Requires `SUPER` or `RESOURCE_GROUP_ADMIN` privilege. When the system variable [`tidb_resource_control_strict_mode`](/system-variables.md#tidb_resource_control_strict_mode-new-in-v820) is set to `ON`, you need to have the `SUPER` or `RESOURCE_GROUP_ADMIN` or `RESOURCE_GROUP_USER` privilege to execute this statement. +### TRAFFIC CAPTURE + +Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege. + +### TRAFFIC REPLAY + +Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege. + +### CANCEL TRAFFIC JOBS + +Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege to cancel traffic capture jobs. + +Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege to cancel traffic replay jobs. + +### SHOW TRAFFIC JOBS + +Requires `SUPER` or `TRAFFIC_CAPTURE_ADMIN` privilege to view traffic capture jobs. + +Requires `SUPER` or `TRAFFIC_REPLAY_ADMIN` privilege to view traffic replay jobs. + ## Implementation of the privilege system ### Privilege table diff --git a/releases/release-6.0.0-dmr.md b/releases/release-6.0.0-dmr.md index ff848e7df7941..8ceb69dcc9b65 100644 --- a/releases/release-6.0.0-dmr.md +++ b/releases/release-6.0.0-dmr.md @@ -556,7 +556,7 @@ TiDB v6.0.0 is a DMR, and its version is 6.0.0-DMR. - A `loader..on-duplicate` parameter is added. The default value is `replace`, which means using the new data to replace the existing data. If you want to keep the previous behavior, you can set the value to `error`. This parameter only controls the behavior during the full import phase. - To use DM, you should use the corresponding version of `dmctl` - Due to internal mechanism changes, after upgrading DM to v6.0.0, you should also upgrade `dmctl` to v6.0.0. -- In v5.4 (v5.4 only), TiDB allows incorrect values for some noop system variables. Since v6.0.0, TiDB disallows setting incorrect values for system variables. [#31538](https://github.com/pingcap/tidb/issues/31538) +- For v5.4 and earlier versions, TiDB allows incorrect values for some noop system variables. Starting from v6.0.0, TiDB disallows setting incorrect values for system variables. [#31538](https://github.com/pingcap/tidb/issues/31538) ## Improvements diff --git a/releases/release-8.4.0.md b/releases/release-8.4.0.md index b99d71e6be2fc..6bffd4b467d21 100644 --- a/releases/release-8.4.0.md +++ b/releases/release-8.4.0.md @@ -54,7 +54,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.4/quick-start-with- Concurrent automatic statistics collection - You can set the concurrency within a single automatic statistics collection task using the system variable tidb_auto_analyze_concurrency. TiDB automatically determines the concurrency of scanning tasks based on node scale and hardware specifications. This improves statistics collection efficiency by fully utilizing system resources, reduces manual tuning, and ensures stable cluster performance. + Introduce the system variable tidb_auto_analyze_concurrency to control the number of concurrent auto-analyze operations within a TiDB cluster. TiDB automatically determines the concurrency of scanning tasks based on node scale and hardware specifications. This improves statistics collection efficiency by fully utilizing system resources, reduces manual tuning, and ensures stable cluster performance. SQL @@ -290,7 +290,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.4/quick-start-with- | [`tidb_opt_prefer_range_scan`](/system-variables.md#tidb_opt_prefer_range_scan-new-in-v50) | Modified | Changes the default value from `OFF` to `ON`. For tables with no statistics (pseudo-statistics) or empty tables (zero statistics), the optimizer prefers interval scans over full table scans. | | [`tidb_scatter_region`](/system-variables.md#tidb_scatter_region) | Modified | Before v8.4.0, its type is boolean, it only supports `ON` and `OFF`, and the Region of the newly created table only supports table level scattering after it is enabled. Starting from v8.4.0, the `SESSION` scope is added, the type is changed from boolean to enumeration, the default value is changed from `OFF` to null, and the optional values `TABLE` and `GLOBAL` are added. In addition, it now supports cluster-level scattering policy to avoid the TiKV OOM issues caused by uneven distribution of regions during fast table creation in batches.| | [`tidb_schema_cache_size`](/system-variables.md#tidb_schema_cache_size-new-in-v800) | Modified | Changes the default value from `0` to `536870912` (512 MiB), indicating that this feature is enabled by default. The minimum value allowed is set to `67108864` (64 MiB). | -| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840)| Newly added | Sets the concurrency within a single automatic statistics collection task. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. | +| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840)| Newly added | Sets the concurrency for auto-analyze operations within a TiDB cluster. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. | | [`tidb_enable_instance_plan_cache`](/system-variables.md#tidb_enable_instance_plan_cache-new-in-v840)| Newly added | Controls whether to enable the Instance Plan Cache feature. | | [`tidb_enable_stats_owner`](/system-variables.md#tidb_enable_stats_owner-new-in-v840)| Newly added | Controls whether the corresponding TiDB instance can run automatic statistics update tasks. | | [`tidb_hash_join_version`](/system-variables.md#tidb_hash_join_version-new-in-v840) | Newly added | Controls whether TiDB uses an optimized version of the Hash Join operator. The default value of `legacy` means that the optimized version is not used. If you set it to `optimized`, TiDB uses the optimized version of the Hash Join operator when executing it to improve Hash Join performance. | @@ -375,7 +375,7 @@ The following features are planned for deprecation in future versions: - Add write control to the [`mysql.tidb_runaway_queries`](/mysql-schema/mysql-schema.md#system-tables-related-to-runaway-queries) log table to reduce overhead caused by a large number of concurrent writes [#54434](https://github.com/pingcap/tidb/issues/54434) @[HuSharp](https://github.com/HuSharp) - Support Index Join by default when the inner table has `Selection`, `Projection`, or `Aggregation` operators on it [#47233](https://github.com/pingcap/tidb/issues/47233) @[winoros](https://github.com/winoros) - Reduce the number of column details fetched from TiKV for `DELETE` operations in certain scenarios, lowering the resource overhead of these operations [#38911](https://github.com/pingcap/tidb/issues/38911) @[winoros](https://github.com/winoros) - - Support setting the concurrency within a single automatic statistics collection task using the system variable `tidb_auto_analyze_concurrency` [#53460](https://github.com/pingcap/tidb/issues/53460) @[hawkingrei](https://github.com/hawkingrei) + - Support setting the concurrency for auto-analyze operations within a TiDB cluster using the system variable `tidb_auto_analyze_concurrency` [#53460](https://github.com/pingcap/tidb/issues/53460) @[hawkingrei](https://github.com/hawkingrei) - Optimize the logic of an internal function to improve performance when querying tables with numerous columns [#52112](https://github.com/pingcap/tidb/issues/52112) @[Rustin170506](https://github.com/Rustin170506) - Simplify filter conditions like `a = 1 AND (a > 1 OR (a = 1 AND b = 2))` to `a = 1 AND b = 2` [#56005](https://github.com/pingcap/tidb/issues/56005) @[ghazalfamilyusa](https://github.com/ghazalfamilyusa) - Increase the cost of table scans in the cost model for scenarios with a high risk of suboptimal execution plans, making the optimizer prefer indexes [#56012](https://github.com/pingcap/tidb/issues/56012) @[terry1purcell](https://github.com/terry1purcell) diff --git a/security-compatibility-with-mysql.md b/security-compatibility-with-mysql.md index 7daed60607a32..de39791eac0da 100644 --- a/security-compatibility-with-mysql.md +++ b/security-compatibility-with-mysql.md @@ -190,7 +190,7 @@ Signature is used to sign the Header and Payload data. > **Warning:** > > - The encoding of the Header and Payload in base64 is reversible. Do **Not** attach any sensitive information to them. -> - The `tidb_auth_token` authentication method requires clients to support the [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in plain text. Therefore, you need to [enale TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`. +> - The `tidb_auth_token` authentication method requires clients to support the [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in plain text. Therefore, you need to [enable TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`. #### Usage diff --git a/sql-statements/sql-statement-admin.md b/sql-statements/sql-statement-admin.md index e89b62104bd66..e25d07d3e5d6e 100644 --- a/sql-statements/sql-statement-admin.md +++ b/sql-statements/sql-statement-admin.md @@ -14,6 +14,7 @@ This statement is a TiDB extension syntax, used to view the status of TiDB and c - [`ADMIN REPAIR`](#admin-repair-statement) - [`ADMIN SHOW NEXT_ROW_ID`](#admin-show-next_row_id-statement) - [`ADMIN SHOW SLOW`](#admin-show-slow-statement) +- [`ADMIN CREATE WORKLOAD SNAPSHOT`](#admin-create-workload-snapshot-statement) ## DDL related statement @@ -149,6 +150,28 @@ For details, refer to [`ADMIN SHOW SLOW` command](/identify-slow-queries.md#admi +## `ADMIN CREATE WORKLOAD SNAPSHOT` statement + + + +> **Note:** +> +> This TiDB statement is not applicable to TiDB Cloud. + + + + + +The following SQL statement will trigger a manual snapshot in the [Workload Repository](/workload-repository.md): + + + +```sql +ADMIN CREATE WORKLOAD SNAPSHOT; +``` + +Note that the Workload Repository must be enabled for this statement to take effect. Otherwise, it will generate an error. + ## Synopsis ```ebnf+diagram @@ -186,6 +209,7 @@ AdminStmt ::= | 'FLUSH' ('SESSION' | 'INSTANCE') 'PLAN_CACHE' | 'SET' 'BDR' 'ROLE' ( 'PRIMARY' | 'SECONDARY' ) | 'UNSET' 'BDR' 'ROLE' + | 'CREATE' 'WORKLOAD' 'SNAPSHOT' ) NumList ::= diff --git a/sql-statements/sql-statement-cancel-traffic-jobs.md b/sql-statements/sql-statement-cancel-traffic-jobs.md new file mode 100644 index 0000000000000..dc630ec64dc78 --- /dev/null +++ b/sql-statements/sql-statement-cancel-traffic-jobs.md @@ -0,0 +1,73 @@ +--- +title: CANCEL TRAFFIC JOBS +summary: An overview of the usage of CANCEL TRAFFIC JOBS for the TiDB database. +--- + +# CANCEL TRAFFIC JOBS + +TiDB v9.0.0 introduces the `CANCEL TRAFFIC JOBS` syntax, which is used to cancel all traffic capture or replay jobs being executed by [TiProxy](/tiproxy/tiproxy-overview.md) in the cluster. This operation requires the following privileges: + +- To cancel traffic capture jobs, you need the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. +- To cancel traffic replay jobs, you need the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + +## Synopsis + +```ebnf+diagram +TrafficStmt ::= + "CANCEL" "TRAFFIC" "JOBS" +``` + +## Examples + +Assume that there are currently two TiProxy instances capturing traffic: + +```sql +SHOW TRAFFIC JOBS; +``` + +``` ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | +| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +2 rows in set (0.01 sec) +``` + +Cancel the current jobs: + +```sql +CANCEL TRAFFIC JOBS; +``` + +``` +Query OK, 0 rows affected (0.13 sec) +``` + +Check the jobs again and it shows that the jobs have been canceled: + +```sql +SHOW TRAFFIC JOBS; +``` + +``` ++----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ +| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | ++----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ +| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.10:3080 | capture | 45% | canceled | manually stopped | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | +| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.11:3080 | capture | 45% | canceled | manually stopped | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | ++----------------------------+----------------------------+----------------+---------+----------+----------+------------------+----------------------------------------------------------------------------+ +2 rows in set (0.01 sec) +``` + +## MySQL compatibility + +This statement is a TiDB extension to MySQL syntax. + +## See also + +* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) +* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) +* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) +* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) diff --git a/sql-statements/sql-statement-commit.md b/sql-statements/sql-statement-commit.md index a608592bd3a26..7e051fd9edc4c 100644 --- a/sql-statements/sql-statement-commit.md +++ b/sql-statements/sql-statement-commit.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-commit/','/docs/dev/reference/ # COMMIT -This statement commits a transaction inside of the TIDB server. +This statement commits a transaction inside of the TiDB server. In the absence of a `BEGIN` or `START TRANSACTION` statement, the default behavior of TiDB is that every statement will be its own transaction and autocommit. This behavior ensures MySQL compatibility. diff --git a/sql-statements/sql-statement-drop-view.md b/sql-statements/sql-statement-drop-view.md index 6201a03ddf301..7ee75dae73eb3 100644 --- a/sql-statements/sql-statement-drop-view.md +++ b/sql-statements/sql-statement-drop-view.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-drop-view/','/docs/dev/referen # DROP VIEW -This statement drops an view object from the currently selected database. It does not effect any base tables that a view references. +This statement drops a view object from the currently selected database. It does not affect any base tables that a view references. ## Synopsis diff --git a/sql-statements/sql-statement-rollback.md b/sql-statements/sql-statement-rollback.md index 5a08335a17243..cfcca4cf8364c 100644 --- a/sql-statements/sql-statement-rollback.md +++ b/sql-statements/sql-statement-rollback.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/sql-statements/sql-statement-rollback/','/docs/dev/referenc # ROLLBACK -This statement reverts all changes in the current transaction inside of TIDB. It is the opposite of a `COMMIT` statement. +This statement reverts all changes in the current transaction inside of TiDB. It is the opposite of a `COMMIT` statement. ## Synopsis diff --git a/sql-statements/sql-statement-show-placement-for.md b/sql-statements/sql-statement-show-placement-for.md index 99b49e33ef7b8..9df40d6b3665d 100644 --- a/sql-statements/sql-statement-show-placement-for.md +++ b/sql-statements/sql-statement-show-placement-for.md @@ -13,7 +13,7 @@ summary: The usage of SHOW PLACEMENT FOR in TiDB. The statement returns a result set in which the `Scheduling_State` field indicates the current progress that the Placement Driver (PD) has made in scheduling the placement: -* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores that are candidates for followers. +* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores that are candidates for followers. * `INPROGRESS`: The PD is currently scheduling the placement. * `SCHEDULED`: The PD has successfully scheduled the placement. diff --git a/sql-statements/sql-statement-show-placement.md b/sql-statements/sql-statement-show-placement.md index 628fb8d2b4e97..289b5842aabeb 100644 --- a/sql-statements/sql-statement-show-placement.md +++ b/sql-statements/sql-statement-show-placement.md @@ -13,7 +13,7 @@ summary: The usage of SHOW PLACEMENT in TiDB. The statement returns a result set in which the `Scheduling_State` field indicates the current progress that the Placement Driver (PD) has made in scheduling the placement: -* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores which are candidates for followers. +* `PENDING`: The PD has not yet started scheduling the placement. This might indicate that the placement rules are semantically correct, but cannot currently be satisfied by the cluster. For example, if `FOLLOWERS=4` but there are only 3 TiKV stores which are candidates for followers. * `INPROGRESS`: The PD is currently scheduling the placement. * `SCHEDULED`: The PD has successfully scheduled the placement. diff --git a/sql-statements/sql-statement-show-traffic-jobs.md b/sql-statements/sql-statement-show-traffic-jobs.md new file mode 100644 index 0000000000000..0173a05499ade --- /dev/null +++ b/sql-statements/sql-statement-show-traffic-jobs.md @@ -0,0 +1,77 @@ +--- +title: SHOW TRAFFIC JOBS +summary: An overview of the usage of SHOW TRAFFIC JOBS for the TiDB database. +--- + +# SHOW TRAFFIC JOBS + +TiDB v9.0.0 introduces the `SHOW TRAFFIC JOBS` syntax, which is used to show all traffic capture or replay jobs executed by [TiProxy](/tiproxy/tiproxy-overview.md) in the cluster. In the output, each row represents a job of a TiProxy instance. Each TiProxy instance stores up to 10 most recent jobs. + +The shown results vary depending on the privileges the current user has. + +- A user with the [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege can view traffic capture jobs. +- A user with the [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege can view traffic replay jobs. +- A user with the `SUPER` privilege or both preceding privileges can view both traffic capture and traffic replay jobs at the same time. + +The `SHOW TRAFFIC JOBS` statement returns the following columns: + +| Column name | Description | +| :-------- | :------------- | +| `START_TIME` | The start time of the job | +| `END_TIME` | The end time if the job has completed. Otherwise, it is empty. | +| `INSTANCE` | The address of the TiProxy instance | +| `TYPE` | The job type. `capture` indicates a traffic capture job, `replay` indicates a traffic replay job | +| `PROGRESS` | The completion percentage of the job | +| `STATUS` | The current status of the job. `running` indicates in progress, `done` indicates normal completion, and `canceled` indicates job failure. | +| `FAIL_REASON` | If the job fails, this column contains the reason for the failure. Otherwise, it is empty. For example, `manually stopped` means the user manually canceled the job by executing `CANCEL TRAFFIC JOBS`. | +| `PARAMS` | The parameters of the job | + +## Synopsis + +```ebnf+diagram +TrafficStmt ::= + "SHOW" "TRAFFIC" "JOBS" +``` + +## Examples + +Show the traffic capture or replay jobs: + +```sql +SHOW TRAFFIC JOBS; +``` + +The following output example shows that two TiProxy instances are capturing traffic, and the progress is 45% for both: + +``` ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | +| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +2 rows in set (0.01 sec) +``` + +The following output example shows that the traffic replay jobs of two TiProxy instances are manually canceled: + +``` ++----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ +| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | ++----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ +| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:42.000000 | 10.1.0.10:3080 | replay | 70% | canceled | manually stopped | INPUT="/tmp/traffic", USER="root", SPEED=0.000000, READ_ONLY=false | +| 2024-12-17 10:54:41.000000 | 2024-12-17 11:34:43.000000 | 10.1.0.11:3080 | replay | 69% | canceled | manually stopped | INPUT="/tmp/traffic", USER="root", SPEED=0.000000, READ_ONLY=false | ++----------------------------+----------------------------+----------------+--------+----------+----------+------------------+--------------------------------------------------------------------+ +2 rows in set (0.01 sec) +``` + +## MySQL compatibility + +This statement is a TiDB extension to MySQL syntax. + +## See also + +* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) +* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) +* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) +* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) diff --git a/sql-statements/sql-statement-traffic-capture.md b/sql-statements/sql-statement-traffic-capture.md new file mode 100644 index 0000000000000..96e3d26b4250c --- /dev/null +++ b/sql-statements/sql-statement-traffic-capture.md @@ -0,0 +1,67 @@ +--- +title: TRAFFIC CAPTURE +summary: An overview of the usage of TRAFFIC CAPTURE for the TiDB database. +--- + +# TRAFFIC CAPTURE + +TiDB v9.0.0 introduces the `TRAFFIC CAPTURE` syntax, which is used to send requests to all [TiProxy](/tiproxy/tiproxy-overview.md) instances in the cluster, allowing TiProxy to capture client traffic and save it to traffic files. + +TiProxy supports capturing traffic to local and external storage. When using local storage, you need to manually copy the traffic files to the TiProxy cluster for replay. When using external storage, no manual copying is needed. + +TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, and other S3-compatible file storage services. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). + +`TRAFFIC CAPTURE` supports the following options: + +- `DURATION`: (required) specifies the duration of capture. The unit is one of `m` (minutes), `h` (hours), or `d` (days). For example, `DURATION="1h"` captures traffic for one hour. +- `COMPRESS`: (optional) specifies whether to compress traffic files. `true` means compression, and the compression format is gzip. `false` means no compression. The default value is `true`. +- `ENCRYPTION_METHOD`: (optional) specifies the algorithm for encrypting traffic files. Only `""`, `plaintext`, and `aes256-ctr` are supported. `""` and `plaintext` indicate no encryption, and `aes256-ctr` indicates encryption using the `AES256-CTR` algorithm. When specifying encryption, you also need to configure [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path). The default value is `""`. + +To capture traffic, the current user must have the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + +## Synopsis + +```ebnf+diagram +TrafficStmt ::= + "TRAFFIC" "CAPTURE" "TO" stringLit TrafficCaptureOptList + +TrafficCaptureOptList ::= + TrafficCaptureOpt +| TrafficCaptureOptList TrafficCaptureOpt + +TrafficCaptureOpt ::= + "DURATION" EqOpt stringLit +| "ENCRYPTION_METHOD" EqOpt stringLit +| "COMPRESS" EqOpt Boolean +``` + +## Examples + +Capture traffic for one day and save it to the local `/tmp/traffic` directory on the TiProxy instance: + +```sql +TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1d"; +``` + +Capture traffic for 10 minutes and save it to S3: + +```sql +TRAFFIC CAPTURE TO "s3://external/traffic?access-key=${access-key}&secret-access-key=${secret-access-key}" DURATION="10m"; +``` + +Capture traffic with automatic encryption but without compression: + +```sql +TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1h" COMPRESS=false ENCRYPTION_METHOD="aes256-ctr"; +``` + +## MySQL compatibility + +This statement is a TiDB extension to MySQL syntax. + +## See also + +* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) +* [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) +* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) +* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) diff --git a/sql-statements/sql-statement-traffic-replay.md b/sql-statements/sql-statement-traffic-replay.md new file mode 100644 index 0000000000000..edc5203c4a094 --- /dev/null +++ b/sql-statements/sql-statement-traffic-replay.md @@ -0,0 +1,71 @@ +--- +title: TRAFFIC REPLAY +summary: An overview of the usage of TRAFFIC REPLAY for the TiDB database. +--- + +# TRAFFIC REPLAY + +TiDB v9.0.0 introduces the `TRAFFIC REPLAY` syntax, which is used to send requests to all [TiProxy](/tiproxy/tiproxy-overview.md) instances in the cluster, allowing TiProxy to replay traffic from the traffic file to TiDB. + +To replay traffic, the current user must have the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + +`TRAFFIC REPLAY` supports the following options: + +- `USER`: (required) specifies the database username for replay. +- `PASSWORD`: (optional) specifies the password for the username. The default value is an empty string `""`. +- `SPEED`: (optional) specifies the replay speed multiplier. The range is `[0.1, 10]`. The default value is `1`, indicating replay at the original speed. +- `READ_ONLY`: (optional) specifies whether to replay only read-only SQL statements. `true` means to replay only read-only SQL statements, `false` means to replay all SQL statements. The default value is `false`. + +## Synopsis + +```ebnf+diagram +TrafficStmt ::= + "TRAFFIC" "REPLAY" "FROM" stringLit TrafficReplayOptList + +TrafficReplayOptList ::= + TrafficReplayOpt +| TrafficReplayOptList TrafficReplayOpt + +TrafficReplayOpt ::= + "USER" EqOpt stringLit +| "PASSWORD" EqOpt stringLit +| "SPEED" EqOpt NumLiteral +| "READ_ONLY" EqOpt Boolean +``` + +## Examples + +Replay traffic from the local `/tmp/traffic` directory of the TiProxy instance, using the TiDB user `u1`, whose password is `"123456"`: + +```sql +TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456"; +``` + +Replay traffic from the traffic files stored in the S3 storage: + +```sql +TRAFFIC REPLAY FROM "s3://external/traffic?access-key=${access-key}&secret-access-key=${secret-access-key}" USER="u1" PASSWORD="123456"; +``` + +Replay traffic at double speed: + +```sql +TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" SPEED=2; +``` + +Replay only read-only statements, not write statements: + +```sql +TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" READ_ONLY=true; +``` + +## MySQL compatibility + +This statement is a TiDB extension to MySQL syntax. + +## See also + +* [TiProxy traffic replay](/tiproxy/tiproxy-traffic-replay.md) +* [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) +* [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) +* [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) diff --git a/stale-read.md b/stale-read.md index bb1d2fb33ed38..b124e3977969e 100644 --- a/stale-read.md +++ b/stale-read.md @@ -35,7 +35,7 @@ TiDB provides the methods of performing Stale Read at the statement level, the s - Session level - Specifying a time range: In a session, if you need TiDB to read the data as new as possible within a time range in subsequent queries without violating the isolation level, you can specify the time range by setting the `tidb_read_staleness` system variable. For detailed usage, refer to [`tidb_read_staleness`](/tidb-read-staleness.md). -Besides, TiDB provides a way to specify an exact point in time by setting the [`tidb_external_ts`](/system-variables.md#tidb_external_ts-new-in-v640) system variable on session or global level. For detailed usage, refer to [Perform Stale Read Using `tidb_external_ts`](/tidb-external-ts.md). +Besides, TiDB provides a way to specify an exact point in time at the session or global level by setting the [`tidb_external_ts`](/system-variables.md#tidb_external_ts-new-in-v640) and [`tidb_enable_external_ts_read`](/system-variables.md#tidb_enable_external_ts_read-new-in-v640) system variables. For detailed usage, refer to [Perform Stale Read Using `tidb_external_ts`](/tidb-external-ts.md). ### Reduce Stale Read latency diff --git a/statement-summary-tables.md b/statement-summary-tables.md index 5e3b42eb7172d..ed295570c17b9 100644 --- a/statement-summary-tables.md +++ b/statement-summary-tables.md @@ -415,6 +415,17 @@ Fields related to Resource Control: - `MAX_QUEUED_RC_TIME`: the maximum waiting time for available RU when executing SQL statements. - `RESOURCE_GROUP`: the resource group bound to SQL statements. +Fields related to network traffic: + +- `SUM_UNPACKED_BYTES_SENT_TIKV_TOTAL`: total bytes sent from SQL statements to TiKV. +- `SUM_UNPACKED_BYTES_RECEIVED_TIKV_TOTAL`: total bytes received by SQL statements from TiKV. +- `SUM_UNPACKED_BYTES_SENT_TIKV_CROSS_ZONE`: bytes sent from SQL statements to TiKV across availability zones. +- `SUM_UNPACKED_BYTES_RECEIVED_TIKV_CROSS_ZONE`: bytes received by SQL statements from TiKV across availability zones. +- `SUM_UNPACKED_BYTES_SENT_TIFLASH_TOTAL`: total bytes sent from SQL statements to TiFlash, including bytes sent between TiFlash nodes. +- `SUM_UNPACKED_BYTES_RECEIVED_TIFLASH_TOTAL`: total bytes received by SQL statements from TiFlash, including bytes received between TiFlash nodes. +- `SUM_UNPACKED_BYTES_SENT_TIFLASH_CROSS_ZONE`: bytes sent from SQL statements to TiFlash across availability zones, including bytes sent between TiFlash nodes across availability zones. +- `SUM_UNPACKED_BYTES_RECEIVED_TIFLASH_CROSS_ZONE`: bytes received by SQL statements from TiFlash across availability zones, including bytes received between TiFlash nodes across availability zones. + ### `statements_summary_evicted` fields description - `BEGIN_TIME`: Records the starting time. diff --git a/statistics.md b/statistics.md index 06e5a8ba5c56e..f16cf14580911 100644 --- a/statistics.md +++ b/statistics.md @@ -32,13 +32,15 @@ Based upon the number of changes to a table, TiDB will automatically schedule [` | System Variable | Default Value | Description | |---|---|---| +| [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840) | `1` | The concurrency for auto-analyze operations within a TiDB cluster. | | [`tidb_auto_analyze_end_time`](/system-variables.md#tidb_auto_analyze_end_time) | `23:59 +0000` | The end time in a day when TiDB can perform automatic updates. | +| [`tidb_auto_analyze_partition_batch_size`](/system-variables.md#tidb_auto_analyze_partition_batch_size-new-in-v640) | `8192` | The number of partitions that TiDB automatically analyzes when analyzing a partitioned table (that is, when automatically updating statistics on a partitioned table). | | [`tidb_auto_analyze_ratio`](/system-variables.md#tidb_auto_analyze_ratio) | `0.5` | The threshold value of automatic update. | | [`tidb_auto_analyze_start_time`](/system-variables.md#tidb_auto_analyze_start_time) | `00:00 +0000` | The start time in a day when TiDB can perform automatic update. | -| [`tidb_auto_analyze_partition_batch_size`](/system-variables.md#tidb_auto_analyze_partition_batch_size-new-in-v640) | `128` | The number of partitions that TiDB automatically analyzes when analyzing a partitioned table (that is, when automatically updating statistics on a partitioned table). | | [`tidb_enable_auto_analyze`](/system-variables.md#tidb_enable_auto_analyze-new-in-v610) | `ON` | Controls whether TiDB automatically executes `ANALYZE`. | | [`tidb_enable_auto_analyze_priority_queue`](/system-variables.md#tidb_enable_auto_analyze_priority_queue-new-in-v800) | `ON` | Controls whether to enable the priority queue to schedule the tasks of automatically collecting statistics. When this variable is enabled, TiDB prioritizes collecting statistics for tables that are more valuable to collect, such as newly created indexes and partitioned tables with partition changes. Additionally, TiDB prioritizes tables with lower health scores, placing them at the front of the queue. | | [`tidb_enable_stats_owner`](/system-variables.md#tidb_enable_stats_owner-new-in-v840) | `ON` | Controls whether the corresponding TiDB instance can run automatic statistics update tasks. | +| [`tidb_max_auto_analyze_time`](/system-variables.md#tidb_max_auto_analyze_time-new-in-v610) | `43200` (12 hours) | The maximum execution time of automatic `ANALYZE` tasks. The unit is second. | When the ratio of the number of modified rows to the total number of rows of `tbl` in a table is greater than `tidb_auto_analyze_ratio`, and the current time is between `tidb_auto_analyze_start_time` and `tidb_auto_analyze_end_time`, TiDB executes the `ANALYZE TABLE tbl` statement in the background to automatically update the statistics on this table. diff --git a/system-variable-reference.md b/system-variable-reference.md index e64d96b8072eb..970d7cb8f00a4 100644 --- a/system-variable-reference.md +++ b/system-variable-reference.md @@ -4035,6 +4035,26 @@ Referenced in: - [SHOW [GLOBAL|SESSION] VARIABLES](/sql-statements/sql-statement-show-variables.md) - [System Variables](/system-variables.md#tidb_window_concurrency-new-in-v40) +### tidb_workload_repository_dest + +- [TiDB Workload Repository](/workload-repository.md#enable-the-workload-repository) +- [System Variables](/system-variables.md#tidb_workload_repository_dest-new-in-v900) + +### tidb_workload_repository_active_sampling_interval + +- [TiDB Workload Repository](/workload-repository.md#time-based-sampling-process-every-5-seconds-by-default) +- [System Variables](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) + +### tidb_workload_repository_retention_days + +- [TiDB Workload Repository](/workload-repository.md#data-retention) +- [System Variables](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) + +### tidb_workload_repository_snapshot_interval + +- [TiDB Workload Repository](/workload-repository.md#snapshot-sampling-process-hourly-by-default) +- [System Variables](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) + ### tiflash_fastscan Referenced in: @@ -4145,15 +4165,6 @@ Referenced in: - [System Variables](/system-variables.md#tx_read_ts) -### txn_scope - -Referenced in: - -- [Limited SQL features on TiDB Cloud](https://docs.pingcap.com/tidbcloud/limited-sql-features) -- [System Variables](/system-variables.md#txn_scope) -- [TiDB Configuration File](/tidb-configuration-file.md) -- [Use Resource Control to Achieve Resource Group Limitation and Flow Control](/tidb-resource-control-ru-groups.md) - ### validate_password.check_user_name Referenced in: diff --git a/system-variables.md b/system-variables.md index 15cfe1b9be5de..c31bde4afb2b9 100644 --- a/system-variables.md +++ b/system-variables.md @@ -1224,7 +1224,7 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - Type: Integer - Default value: `1` - Range: `[1, 2147483647]` -- This variable is used to set the concurrency within a single automatic statistics collection task. Before v8.4.0, this concurrency is fixed at `1`. To speed up statistics collection tasks, you can increase this concurrency based on your cluster's available resources. +- This variable controls the number of concurrent auto-analyze operations that can run in a TiDB cluster. Before v8.4.0, this concurrency is fixed at 1. To accelerate statistics collection tasks, you can increase this concurrency based on the available resources in your cluster. ### tidb_auto_analyze_end_time @@ -1742,7 +1742,7 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - Default value: `0` - Range: `[0, 1PiB]` - This variable limits the write bandwidth for each TiKV node and only takes effect when index creation acceleration is enabled (controlled by the [`tidb_ddl_enable_fast_reorg`](#tidb_ddl_enable_fast_reorg-new-in-v630) variable). When the data size in your cluster is quite large (such as billions of rows), limiting the write bandwidth for index creation can effectively reduce the impact on application workloads. -- The default value `0` means no write bandwidth limit. +- The default value `0` means no write bandwidth limit. - You can specify the value of this variable either with a unit or without a unit. - When you specify the value without a unit, the default unit is bytes per second. For example, `67108864` represents `64MiB` per second. - When you specify the value with a unit, supported units include KiB, MiB, GiB, and TiB. For example, `'1GiB`' represents 1 GiB per second, and `'256MiB'` represents 256 MiB per second. @@ -2578,6 +2578,14 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; +### tidb_enable_point_get_cache + +- Scope: SESSION +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): YES +- Type: Boolean +- Default value: `OFF` +- When you set the table lock type of [`LOCK TABLES`](/sql-statements/sql-statement-lock-tables-and-unlock-tables.md) to `READ`, setting this variable to `ON` enables caching of point query results, reducing the overhead of repeated queries and improving point query performance. + ### tidb_enable_prepared_plan_cache New in v6.1.0 - Scope: SESSION | GLOBAL @@ -3171,7 +3179,7 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - This variable is used to set whether to record all SQL statements in the [log](/tidb-configuration-file.md#logfile). This feature is disabled by default. If maintenance personnel needs to trace all SQL statements when locating issues, they can enable this feature. -- If the [`log.general-log-file`](/tidb-configuration-file.md#general-log-file-new-in-v800) configuration item is specified, the general log is written to the specified file separately. +- If the [`log.general-log-file`](/tidb-configuration-file.md#general-log-file-new-in-v800) configuration item is specified, the general log is written to the specified file separately. - The [`log.format`](/tidb-configuration-file.md#format) configuration item enables you to configure the log message format, whether the general log is in a separate file or combined with other logs. @@ -3542,7 +3550,6 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Default value: "" - This is a read-only variable. It is internally used in TiDB to query the transaction information of the last DML statement. The information includes: - - `txn_scope`: The scope of the transaction, which can be `global` or `local`. - `start_ts`: The start timestamp of the transaction. - `for_update_ts`: The `for_update_ts` of the previously executed DML statement. This is an internal term of TiDB used for tests. Usually, you can ignore this information. - `error`: The error message, if any. @@ -3669,7 +3676,7 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Persists to cluster: Yes - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Type: Integer -- Default value: `43200` +- Default value: `43200` (12 hours) - Range: `[0, 2147483647]` - Unit: Seconds - This variable is used to specify the maximum execution time of automatic `ANALYZE` tasks. When the execution time of an automatic `ANALYZE` task exceeds the specified time, the task will be terminated. When the value of this variable is `0`, there is no limit to the maximum execution time of automatic `ANALYZE` tasks. @@ -3779,6 +3786,22 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - Range: `[100, 16384]` - This variable is used to set the maximum number of schema versions (the table IDs modified for corresponding versions) allowed to be cached. The value range is 100 ~ 16384. +### tidb_max_dist_task_nodes New in v9.0.0 + +- Scope: SESSION | GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: Integer +- Default value: `-1` +- Range: `-1` or `[1, 128]` +- This variable defines the maximum number of TiDB nodes that the Distributed eXecution Framework (DXF) tasks can use. The default value is `-1`, which indicates that automatic mode is enabled. In automatic mode, TiDB dynamically calculates the value as `min(3, tikv_nodes / 3)`, where `tikv_nodes` represents the number of TiKV nodes in the cluster. + +> **Note:** +> +> If you explicitly set the [`tidb_service_scope`](#tidb_service_scope-new-in-v740) system variable for some TiDB nodes, the Distributed eXecution Framework schedules tasks only to these nodes. In this case, even if you set `tidb_max_dist_task_nodes` to a larger value, the framework uses no more than the number of nodes explicitly configured with `tidb_service_scope`. +> +> For example, if the cluster has 10 TiDB nodes, and 4 of them are configured with `tidb_service_scope = group1`, then even if you set `tidb_max_dist_task_nodes = 5`, only 4 nodes participate in task execution. + ### tidb_max_paging_size New in v6.3.0 - Scope: SESSION | GLOBAL @@ -4936,6 +4959,22 @@ SHOW WARNINGS; > - This option only takes effect on statements that need to lock a single key. If a statement needs to lock multiple rows at the same time, this option will not take effect on such statements. > - This feature is introduced in v6.6.0 by the [`tidb_pessimistic_txn_aggressive_locking`](https://docs-archive.pingcap.com/tidb/v6.6/system-variables#tidb_pessimistic_txn_aggressive_locking-new-in-v660) variable, which is disabled by default. +### tidb_pipelined_dml_resource_policy New in v9.0.0 + +- Scope: SESSION | GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): Yes +- Type: String +- Default value: `"standard"` +- Possible values: `"standard"`, `"conservative"`, and `"custom{...}"` +- This variable controls the resource usage policy for [Pipelined DML](/pipelined-dml.md). It takes effect only when [`tidb_dml_type`](#tidb_dml_type-new-in-v800) is set to `bulk`. The meaning of each possible value is as follows: + - `"standard"`: the default resource usage policy. + - `"conservative"`: Pipelined DML uses fewer resources, but its execution speed is slower than the default policy, suitable for scenarios with sensitive resource usage. + - `"custom{option1=value1,option2=value2,...}"`: a custom resource usage policy. You can specify only the required options. For example, `"custom{concurrency=8,write_throttle_ratio=0.5}"`. Make sure that the value is enclosed in double quotes. The supported custom options include the following: + - `concurrency`: specifies the concurrency of the flush operation, which affects the execution speed and resource usage of Pipelined DML. The value range is `[1, 8192]`. + - `resolve_concurrency`: specifies the concurrency of the asynchronous resolve lock operations. It affects the resource usage of Pipelined DML but not its execution speed. The value range is `[1, 8192]`. + - `write_throttle_ratio`: specifies the ratio of the active throttle time to the total time. The larger the value, the higher the ratio of throttle time in total time, and the more resources are saved. `0` means no throttle. The value range is `[0, 1)`. + ### tidb_placement_mode New in v6.0.0 > **Note:** @@ -6245,6 +6284,98 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - This variable is used to set the concurrency degree of the window operator. - A value of `-1` means that the value of `tidb_executor_concurrency` will be used instead. +### tidb_workload_repository_dest New in v9.0.0 + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: String +- Default value: `''` + + + +- This variable is used to set the destination of the [Workload Repository](/workload-repository.md). +- The value can be either `'table'` (enabling the workload repository) or `''` (disabling the workload repository). + + + + + +- This variable is used to set the destination of the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository). +- The value can be either `'table'` (enabling the workload repository) or `''` (disabling the workload repository). + + + +### tidb_workload_repository_active_sampling_interval New in v9.0.0 + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: Integer +- Default value: `5` +- Range: `[0, 600]` +- Unit: Seconds + + + +- Sets the sampling interval for the [Workload Repository](/workload-repository.md)'s time-based sampling process. +- Setting the value to `0` disables the time-based sampling process. + + + + + +- Sets the sampling interval for the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository)'s time-based sampling process. +- Setting the value to `0` disables the time-based sampling process. + + + +### tidb_workload_repository_retention_days New in v9.0.0 + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: Integer +- Default value: `7` +- Range: `[0, 365]` +- Unit: Days + + + +- Sets the number of days that [Workload Repository](/workload-repository.md) data is retained. +- Setting the value to `0` disables automatic purging of old data. + + + + + +- Sets the number of days that [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository) data is retained. +- Setting the value to `0` disables automatic purging of old data. + + + +### tidb_workload_repository_snapshot_interval New in v9.0.0 + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: Integer +- Default value: `3600` +- Range: `[900, 7200]` +- Unit: Seconds + + + +- Sets the sampling interval for the [Workload Repository](/workload-repository.md)'s snapshot sampling process. + + + + + +- Sets the sampling interval for the [Workload Repository](https://docs.pingcap.com/tidb/dev/workload-repository)'s snapshot sampling process. + + + ### tiflash_fastscan New in v6.3.0 - Scope: SESSION | GLOBAL @@ -6260,7 +6391,7 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Default value: `8192` - Range: `[1, 18446744073709551615]` - When Fine Grained Shuffle is enabled, the window function pushed down to TiFlash can be executed in parallel. This variable controls the batch size of the data sent by the sender. -- Impact on performance: set a reasonable size according to your business requirements. Improper setting affects the performance. If the value is set too small, for example `1`, it causes one network transfer per Block. If the value is set too large, for example, the total number of rows of the table, it causes the receiving end to spend most of the time waiting for data, and the piplelined computation cannot work. To set a proper value, you can observe the distribution of the number of rows received by the TiFlash receiver. If most threads receive only a few rows, for example a few hundred, you can increase this value to reduce the network overhead. +- Impact on performance: set a reasonable size according to your business requirements. Improper setting affects the performance. If the value is set too small, for example `1`, it causes one network transfer per Block. If the value is set too large, for example, the total number of rows of the table, it causes the receiving end to spend most of the time waiting for data, and the pipelined computation cannot work. To set a proper value, you can observe the distribution of the number of rows received by the TiFlash receiver. If most threads receive only a few rows, for example a few hundred, you can increase this value to reduce the network overhead. ### tiflash_fine_grained_shuffle_stream_count New in v6.2.0 @@ -6408,19 +6539,6 @@ Internally, the TiDB parser transforms the `SET TRANSACTION ISOLATION LEVEL [REA - In the Stale Read scenarios, this session variable is used to help record the Stable Read timestamp value. - This variable is used for the internal operation of TiDB. It is **NOT recommended** to set this variable. -### txn_scope - -> **Note:** -> -> This variable is read-only for [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless). - -- Scope: SESSION -- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No -- Default value: `global` -- Value options: `global` and `local` -- This variable is used to set whether the current session transaction is a global transaction or a local transaction. -- This variable is used for the internal operation of TiDB. It is **NOT recommended** to set this variable. - ### validate_password.check_user_name New in v6.5.0 - Scope: GLOBAL diff --git a/three-data-centers-in-two-cities-deployment.md b/three-data-centers-in-two-cities-deployment.md index 6ce2d698453aa..6b473cc1d431f 100644 --- a/three-data-centers-in-two-cities-deployment.md +++ b/three-data-centers-in-two-cities-deployment.md @@ -179,7 +179,7 @@ In the deployment of three AZs in two regions, to optimize performance, you need > **Note:** > -> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks' before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. +> Using `raftstore.raft-min-election-timeout-ticks` and `raftstore.raft-max-election-timeout-ticks` to configure larger election timeout ticks for a TiKV node can significantly decrease the likelihood of Regions on that node becoming Leaders. However, in a disaster scenario where some TiKV nodes are offline and the remaining active TiKV nodes lag behind in Raft logs, only Regions on this TiKV node with large election timeout ticks can become Leaders. Because Regions on this TiKV node must wait for at least the duration set by `raftstore.raft-min-election-timeout-ticks` before initiating an election, it is recommended to avoid setting these values excessively large to prevent potential impact on the cluster availability in such scenarios. - Configure scheduling. After the cluster is enabled, use the `tiup ctl:v{CLUSTER_VERSION} pd` tool to modify the scheduling policy. Modify the number of TiKV Raft replicas. Configure this number as planned. In this example, the number of replicas is five. diff --git a/ticdc/ticdc-avro-protocol.md b/ticdc/ticdc-avro-protocol.md index 46a816fd2207e..74d0cc0880caa 100644 --- a/ticdc/ticdc-avro-protocol.md +++ b/ticdc/ticdc-avro-protocol.md @@ -205,6 +205,7 @@ If one column can be NULL, the Column data format can be: | ENUM | ENUM | string | - | | SET | SET | string | - | | DECIMAL | DECIMAL | bytes | When `avro-decimal-handling-mode` is string, AVRO_TYPE is string. | +| TiDBVECTORFloat32 | TiDBVECTORFloat32 | string | - | In the Avro protocol, two other `sink-uri` parameters might affect the Column data format as well: `avro-decimal-handling-mode` and `avro-bigint-unsigned-handling-mode`. diff --git a/ticdc/ticdc-canal-json.md b/ticdc/ticdc-canal-json.md index 1b5151ddea5ac..100a9f5ff9eac 100644 --- a/ticdc/ticdc-canal-json.md +++ b/ticdc/ticdc-canal-json.md @@ -213,6 +213,7 @@ In the `sqlType` field, the Canal-JSON format records Java SQL Type of each colu | Set | -7 | | Bit | -7 | | JSON | 12 | +| TiDBVectorFloat32 | 12 | ## Integer types diff --git a/ticdc/ticdc-csv.md b/ticdc/ticdc-csv.md index 12278eec59ca0..40d6de9161fb8 100644 --- a/ticdc/ticdc-csv.md +++ b/ticdc/ticdc-csv.md @@ -102,3 +102,4 @@ When `include-commit-ts = true` and `output-old-value = true`, the DML events of | `DECIMAL` | String | `"129012.1230000"` | - | | `ENUM` | String | `"a"` | - | | `SET` | String | `"a,b"` | - | +| `TiDBVectorFloat32` | String | `"[1.23, -0.4]"` | - | diff --git a/ticdc/ticdc-glossary.md b/ticdc/ticdc-glossary.md index b054da51db7db..5f3de3a515cf2 100644 --- a/ticdc/ticdc-glossary.md +++ b/ticdc/ticdc-glossary.md @@ -5,7 +5,7 @@ summary: Learn the terms about TiCDC and their definitions. # TiCDC Glossary -This glossary provides TiCDC-related terms and definitions. These terms appears in TiCDC logs, monitoring metrics, configurations, and documents. +This glossary provides TiCDC-related terms and definitions. These terms appear in TiCDC logs, monitoring metrics, configurations, and documents. For TiDB-related terms and definitions, see [TiDB glossary](/glossary.md). diff --git a/ticdc/ticdc-manage-changefeed.md b/ticdc/ticdc-manage-changefeed.md index 814d55fcd7ecb..1095fbc3962fe 100644 --- a/ticdc/ticdc-manage-changefeed.md +++ b/ticdc/ticdc-manage-changefeed.md @@ -170,7 +170,7 @@ cdc cli changefeed resume --server=http://10.0.10.25:8300 --changefeed-id simple ``` - `--changefeed-id=uuid` represents the ID of the changefeed that corresponds to the replication task you want to resume. -- `--overwrite-checkpoint-ts`: starting from v6.2.0, you can specify the starting TSO of resuming the replication task. TiCDC starts pulling data from the specified TSO. The argument accepts `now` or a specific TSO (such as 434873584621453313). The specified TSO must be in the range of (GC safe point, CurrentTSO]. If this argument is not specified, TiCDC replicates data from the current `checkpoint-ts` by default. +- `--overwrite-checkpoint-ts`: starting from v6.2.0, you can specify the starting TSO of resuming the replication task. TiCDC starts pulling data from the specified TSO. The argument accepts `now` or a specific TSO (such as 434873584621453313). The specified TSO must be in the range of (GC safe point, CurrentTSO]. If this argument is not specified, TiCDC replicates data from the current `checkpoint-ts` by default. You can use the `cdc cli changefeed list` command to check the current value of `checkpoint-ts`. - `--no-confirm`: when the replication is resumed, you do not need to confirm the related information. Defaults to `false`. > **Note:** diff --git a/ticdc/ticdc-open-protocol.md b/ticdc/ticdc-open-protocol.md index 03105a3f6e367..d15a92a0b5fcf 100644 --- a/ticdc/ticdc-open-protocol.md +++ b/ticdc/ticdc-open-protocol.md @@ -308,6 +308,7 @@ Currently, TiCDC does not provide the standard parsing library for TiCDC Open Pr | LONGTEXT/LONGBLOB | 251 | {"t":251,"v":"5rWL6K+VdGV4dA=="} | The value is encoded in Base64. | | TEXT/BLOB | 252 | {"t":252,"v":"5rWL6K+VdGV4dA=="} | The value is encoded in Base64. | | CHAR/BINARY | 254 | {"t":254,"v":"test"} / {"t":254,"v":"\\\\x89PNG\\\\r\\\\n\\\\x1a\\\\n"} | The value is encoded in UTF-8. When the upstream type is BINARY, invisible characters are escaped. | +| TiDBVectorFloat32 | 225 | {"t":225,"v":"[1.23, -0.4]"} | | | GEOMETRY | 255 | | Unsupported | ## DDL Type Code diff --git a/ticdc/ticdc-simple-protocol.md b/ticdc/ticdc-simple-protocol.md index 7a3f4a03cc4af..db1ad3bc98fc6 100644 --- a/ticdc/ticdc-simple-protocol.md +++ b/ticdc/ticdc-simple-protocol.md @@ -708,6 +708,7 @@ The following table describes the value range of the `mysqlType` field in the Ti | bit | / | uint64 | long | | json | / | string | string | | bool | / | int64 | long | +| TiDBVectorFloat32 | / | string | string | ### Avro schema definition diff --git a/ticdc/ticdc-sink-to-cloud-storage.md b/ticdc/ticdc-sink-to-cloud-storage.md index 7ef21594919a9..2ce91106228d3 100644 --- a/ticdc/ticdc-sink-to-cloud-storage.md +++ b/ticdc/ticdc-sink-to-cloud-storage.md @@ -176,7 +176,13 @@ Data change records are saved to the following path: > **Note:** > -> The table version changes only after a DDL operation is performed on the upstream table, and the new table version is the TSO when the upstream TiDB completes the execution of the DDL. However, the change of the table version does not mean the change of the table schema. For example, adding a comment to a column does not cause the schema file content to change. +> The table version changes in the following scenarios: +> +> - The upstream TiDB performs a DDL operation on the table. +> - TiCDC schedules the table across nodes. +> - The changefeed to which the table belongs restarts. +> +> Note that the change of the table version does not mean the change of the table schema. For example, adding a comment to a column does not cause the schema file content to change. ### Index files diff --git a/ticdc/ticdc-sink-to-mysql.md b/ticdc/ticdc-sink-to-mysql.md index 64f8157bc74c6..8e2dfeed7f86b 100644 --- a/ticdc/ticdc-sink-to-mysql.md +++ b/ticdc/ticdc-sink-to-mysql.md @@ -176,5 +176,5 @@ cdc redo apply --tmp-dir="/tmp/cdc/redo/apply" \ In this command: - `tmp-dir`: Specifies the temporary directory for downloading TiCDC incremental data backup files. -- `storage`: Specifies the address for storing the TiCDC incremental data backup files, either an URI of object storage or an NFS directory. +- `storage`: Specifies the address for storing the TiCDC incremental data backup files, either a URI of object storage or an NFS directory. - `sink-uri`: Specifies the secondary cluster address to restore the data to. Scheme can only be `mysql`. diff --git a/tidb-cloud/high-availability-with-multi-az.md b/tidb-cloud/high-availability-with-multi-az.md index 1741634147c42..4260fae5b4d26 100644 --- a/tidb-cloud/high-availability-with-multi-az.md +++ b/tidb-cloud/high-availability-with-multi-az.md @@ -7,7 +7,7 @@ summary: TiDB Cloud supports high availability with Multi-AZ deployments. TiDB uses the Raft consensus algorithm to ensure that data is highly available and safely replicated throughout storage in Raft Groups. Data is redundantly copied between storage nodes and placed in different availability zones to protect against machine or data center failures. With automatic failover, TiDB ensures that your service is always on. -TiDB Cloud clusters consist of three major components: TiDB node, TiKV node, and TiFlash node. The highly availability implementation of each component for TiDB Cloud Dedicated is as follows: +TiDB Cloud clusters consist of three major components: TiDB node, TiKV node, and TiFlash node. The high availability implementation of each component for TiDB Cloud Dedicated is as follows: * **TiDB node** diff --git a/tidb-cloud/integrate-tidbcloud-with-n8n.md b/tidb-cloud/integrate-tidbcloud-with-n8n.md index bf5fb005b2014..eb4a615bb2070 100644 --- a/tidb-cloud/integrate-tidbcloud-with-n8n.md +++ b/tidb-cloud/integrate-tidbcloud-with-n8n.md @@ -140,7 +140,7 @@ This trigger will execute your workflow every morning at 8 AM. 1. Click **+** to the right of the RSS Read node. 2. Search `TiDB Cloud` and add it to the workspace. -3. Select the credentials that you entered in the previous TiDB Cloud node. +3. Select the credentials that you entered the previous TiDB Cloud node. 4. In the **Project** list, select your project. 5. In the **Operation** list, select `Insert`. 6. In **Cluster**, **User**, **Database** and **Password** boxes, enter the corresponding values. diff --git a/tidb-cloud/limited-sql-features.md b/tidb-cloud/limited-sql-features.md index 455d756445c26..96d63fc7d2ca9 100644 --- a/tidb-cloud/limited-sql-features.md +++ b/tidb-cloud/limited-sql-features.md @@ -205,7 +205,6 @@ TiDB Cloud works with almost all workloads that TiDB supports, but there are som | `tidb_txn_mode` | No limitation | Read-only [^10] | | `tidb_wait_split_region_finish` | No limitation | Read-only [^10] | | `tidb_wait_split_region_timeout` | No limitation | Read-only [^10] | -| `txn_scope` | No limitation | Read-only [^10] | | `validate_password.enable` | No limitation | Always enabled [^9] | | `validate_password.length` | No limitation | At least `8` [^9] | | `validate_password.mixed_case_count` | No limitation | At least `1` [^9] | diff --git a/tidb-cloud/ticloud-config-edit.md b/tidb-cloud/ticloud-config-edit.md index 83389b8c148db..be5a2c24962ac 100644 --- a/tidb-cloud/ticloud-config-edit.md +++ b/tidb-cloud/ticloud-config-edit.md @@ -15,7 +15,7 @@ If you are using Windows, after you execute the preceding command, the path of t > **Note:** > -> To avoid format errors and execution failures, it is NOT recommended to manually edit the configuration file. Instead, you can use [`ticloud config create`](/tidb-cloud/ticloud-config-create.md), [`ticloud config delete`](/tidb-cloud/ticloud-config-delete.md), or [`ticloud config set`](/tidb-cloud/ticloud-config-set.md) to modify the confiturations. +> To avoid format errors and execution failures, it is NOT recommended to manually edit the configuration file. Instead, you can use [`ticloud config create`](/tidb-cloud/ticloud-config-create.md), [`ticloud config delete`](/tidb-cloud/ticloud-config-delete.md), or [`ticloud config set`](/tidb-cloud/ticloud-config-set.md) to modify the configurations. ## Examples diff --git a/tidb-cloud/troubleshoot-import-access-denied-error.md b/tidb-cloud/troubleshoot-import-access-denied-error.md index d418157f2f5cd..4a861ce6ee0ac 100644 --- a/tidb-cloud/troubleshoot-import-access-denied-error.md +++ b/tidb-cloud/troubleshoot-import-access-denied-error.md @@ -229,7 +229,7 @@ To solve the `AccessDenied` error in this situation, click the key ARN or manual > **Note:** > -> If the objects in your bucket have been copied from an existing encrypted bucket, you also need to include the key of the source bucket in the AWS KMS key ARN. This is because the objects in the your bucket use the same encryption method as the source object encryption. For more information, see the AWS document [Using default encryption with replication](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html). +> If the objects in your bucket have been copied from an existing encrypted bucket, you also need to include the key of the source bucket in the AWS KMS key ARN. This is because the objects in your bucket use the same encryption method as the source object encryption. For more information, see the AWS document [Using default encryption with replication](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html). ### Check the AWS article for instruction diff --git a/tidb-configuration-file.md b/tidb-configuration-file.md index 22dbd2d5c288c..7ff5e9b48cdf6 100644 --- a/tidb-configuration-file.md +++ b/tidb-configuration-file.md @@ -261,7 +261,7 @@ The TiDB configuration file supports more options than command-line parameters. > **Note:** > -> - In TiDB, the `zone` label is specially used to specify the zone where a server is located. If `zone` is set to a non-null value, the corresponding value is automatically used by features such as [`txn-score`](/system-variables.md#txn_scope) and [`Follower read`](/follower-read.md). +> - In TiDB, the `zone` label is specially used to specify the zone where a server is located. If `zone` is set to a non-null value, the corresponding value is automatically used by [`Follower read`](/follower-read.md). > - The `group` label has a special use in TiDB Operator. For clusters deployed using [TiDB Operator](/tidb-operator-overview.md), it is **NOT** recommended that you specify the `group` label manually. ## log @@ -828,7 +828,7 @@ Configuration related to the status of TiDB service. ### `record-db-label` - Determines whether to transmit the database-related QPS metrics to Prometheus. -- Supports more metircs types than `record-db-qps`, for example, duration and statements. +- Supports more metrics types than `record-db-qps`, for example, duration and statements. - Default value: `false` ## pessimistic-txn diff --git a/tidb-control.md b/tidb-control.md index 36bb981b1b9e4..8822a5f1ecaef 100644 --- a/tidb-control.md +++ b/tidb-control.md @@ -179,7 +179,7 @@ tidb-ctl base64decode [table_id] [base64_data] alter table t add column e varchar(20); ``` -2. Obtian MVCC data using the HTTP API interface: +2. Obtain MVCC data using the HTTP API interface: ```shell $ curl "http://$IP:10080/mvcc/index/test/t/a/1?a=1" diff --git a/tidb-monitoring-framework.md b/tidb-monitoring-framework.md index ea91beabaeaa0..786d25d70bdac 100644 --- a/tidb-monitoring-framework.md +++ b/tidb-monitoring-framework.md @@ -1,12 +1,12 @@ --- title: TiDB Monitoring Framework Overview -summary: Use Prometheus and Grafana to build the TiDB monitoring framework. +summary: Use Prometheus, Grafana, and TiDB Dashboard to build the TiDB monitoring framework. aliases: ['/docs/dev/tidb-monitoring-framework/','/docs/dev/how-to/monitor/overview/'] --- # TiDB Monitoring Framework Overview -The TiDB monitoring framework adopts two open source projects: Prometheus and Grafana. TiDB uses [Prometheus](https://prometheus.io) to store the monitoring and performance metrics and [Grafana](https://grafana.com/grafana) to visualize these metrics. +The TiDB monitoring framework adopts two open source projects: Prometheus and Grafana. TiDB uses [Prometheus](https://prometheus.io) to store the monitoring and performance metrics and [Grafana](https://grafana.com/grafana) to visualize these metrics. TiDB also provides a built-in [TiDB Dashboard](/dashboard/dashboard-intro.md) for monitoring and diagnosing TiDB clusters. ## About Prometheus in TiDB @@ -51,3 +51,7 @@ Grafana is an open source project for analyzing and visualizing metrics. TiDB us Each group has multiple panel labels of monitoring metrics, and each panel contains detailed information of multiple monitoring metrics. For example, the **Overview** monitoring group has five panel labels, and each labels corresponds to a monitoring panel. See the following UI: ![Grafana Overview](/media/grafana-monitor-overview.png) + +## TiDB Dashboard + +TiDB Dashboard is a web UI for monitoring, diagnosing, and managing the TiDB cluster, which is introduced in v4.0. It is built into the PD component and does not require an independent deployment. For more information, see [TiDB Dashboard introduction](/dashboard/dashboard-intro.md). diff --git a/tidb-resource-control-ru-groups.md b/tidb-resource-control-ru-groups.md index 21bd38f973b07..3fdd338db65bd 100644 --- a/tidb-resource-control-ru-groups.md +++ b/tidb-resource-control-ru-groups.md @@ -333,11 +333,11 @@ Example: ``` ``` - +------------------------------------------------------------------------------------------------------------------------+ - | @@tidb_last_query_info | - +------------------------------------------------------------------------------------------------------------------------+ - | {"txn_scope":"global","start_ts":446809472210829315,"for_update_ts":446809472210829315,"ru_consumption":4.34885578125} | - +------------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------+ + | @@tidb_last_query_info | + +---------------------------------------------------------------------------------------------------+ + | {"start_ts":446809472210829315,"for_update_ts":446809472210829315,"ru_consumption":4.34885578125} | + +---------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) ``` diff --git a/tidb-troubleshooting-map.md b/tidb-troubleshooting-map.md index 7112cf9f0d31e..b85ee4e0762f9 100644 --- a/tidb-troubleshooting-map.md +++ b/tidb-troubleshooting-map.md @@ -267,7 +267,7 @@ Check the specific cause for busy by viewing the monitor **Grafana** -> **TiKV** - `append log duration` is high, which causes slow processing of messages. You can refer to [4.5](#45-tikv-write-is-slow) to analyze why `append log duration` is high. - raftstore receives a large batch of messages in an instant (check in the TiKV Raft messages dashboard), and fails to process them. Usually the short-term `channel full` status does not affect the service. -- 4.3.4 TiKV coprocessor is in a queue. The number of piled up tasks exceeds `coprocessor threads * readpool.coprocessor.max-tasks-per-worker-[normal|low|high]`. Too many large queries leads to the tasks piling up in coprocessor. You need to check whether a execution plan change causes a large number of table scan operations. Refer to [3.3](#33-wrong-execution-plan). +- 4.3.4 TiKV coprocessor is in a queue. The number of piled up tasks exceeds `coprocessor threads * readpool.coprocessor.max-tasks-per-worker-[normal|low|high]`. Too many large queries leads to the tasks piling up in coprocessor. You need to check whether an execution plan change causes a large number of table scan operations. Refer to [3.3](#33-wrong-execution-plan). ### 4.4 Some TiKV nodes drop Leader frequently diff --git a/tiflash-upgrade-guide.md b/tiflash-upgrade-guide.md index ad7c9000a168f..3425ffff49247 100644 --- a/tiflash-upgrade-guide.md +++ b/tiflash-upgrade-guide.md @@ -65,7 +65,7 @@ When you upgrade TiFlash from v5.x or v6.0 to v6.1, pay attention to the functio TiFlash Proxy is upgraded in v6.1.0 (aligned with TiKV v6.0.0). The new version has upgraded the RocksDB version. After you upgrade TiFlash to v6.1, the data format is converted to the new version automatically. -In regular upgrades, the data conversion does not involve any risks. However, if you need to downgrade TiFlash from v6.1 to any earlier version in special scenarios (for example, testing or verification scenarios), the earlier version might fail to parse the new RocksDB configuration. As as result, TiFlash will fail to restart. It is recommended that you fully test and verify the upgrade process and prepare an emergency plan. +In regular upgrades, the data conversion does not involve any risks. However, if you need to downgrade TiFlash from v6.1 to any earlier version in special scenarios (for example, testing or verification scenarios), the earlier version might fail to parse the new RocksDB configuration. As result, TiFlash will fail to restart. It is recommended that you fully test and verify the upgrade process and prepare an emergency plan. **Workaround for downgrading TiFlash in testing or other special scenarios** @@ -128,6 +128,10 @@ Starting from v7.4, to reduce the read and write amplification generated during Starting from v8.4, the underlying storage format of TiFlash is updated to support [vector search](/vector-search/vector-search-overview.md). Therefore, after TiFlash is upgraded to v8.4 or a later version, in-place downgrading to the original version is not supported. +## From v8.x to v9.0 or a later version + +Starting from v9.0.0, TiFlash optimizes the storage format of string data to improve the string read and write performance. Therefore, after TiFlash is upgraded to v9.0.0 or a later version, in-place downgrading to the original version is not supported. + **Workaround for downgrading TiFlash in testing or other special scenarios** To downgrade TiFlash in testing or other special scenarios, you can forcibly scale in the target TiFlash node and then replicate data from TiKV again. For detailed steps, see [Scale in a TiFlash cluster](/scale-tidb-using-tiup.md#scale-in-a-tiflash-cluster). diff --git a/tiflash/tiflash-overview.md b/tiflash/tiflash-overview.md index ffce1d3373b38..c7e5a8e06cfbb 100644 --- a/tiflash/tiflash-overview.md +++ b/tiflash/tiflash-overview.md @@ -6,7 +6,7 @@ aliases: ['/docs/dev/tiflash/tiflash-overview/','/docs/dev/reference/tiflash/ove # TiFlash Overview -[TiFlash](https://github.com/pingcap/tiflash) is the key component that makes TiDB essentially an Hybrid Transactional/Analytical Processing (HTAP) database. As a columnar storage extension of TiKV, TiFlash provides both good isolation level and strong consistency guarantee. +[TiFlash](https://github.com/pingcap/tiflash) is the key component that makes TiDB essentially a Hybrid Transactional/Analytical Processing (HTAP) database. As a columnar storage extension of TiKV, TiFlash provides both good isolation level and strong consistency guarantee. In TiFlash, the columnar replicas are asynchronously replicated according to the Raft Learner consensus algorithm. When these replicas are read, the Snapshot Isolation level of consistency is achieved by validating Raft index and multi-version concurrency control (MVCC). diff --git a/tikv-configuration-file.md b/tikv-configuration-file.md index 7ec9e0937b6e7..9c132d69eff77 100644 --- a/tikv-configuration-file.md +++ b/tikv-configuration-file.md @@ -427,7 +427,7 @@ Configuration items related to storage. > > This feature is experimental. It is not recommended that you use it in the production environment. This feature might be changed or removed without prior notice. If you find a bug, you can report an [issue](https://github.com/pingcap/tidb/issues) on GitHub. -+ Specifies the engine type. This configuration can only be specified when creating a new cluster and cannot be modifies once being specified. ++ Specifies the engine type. This configuration can only be specified when creating a new cluster and cannot be modified once being specified. + Default value: `"raft-kv"` + Value options: diff --git a/tiproxy/tiproxy-command-line-flags.md b/tiproxy/tiproxy-command-line-flags.md index 7f4f00b2d7549..ab75c0fcad55a 100644 --- a/tiproxy/tiproxy-command-line-flags.md +++ b/tiproxy/tiproxy-command-line-flags.md @@ -165,6 +165,8 @@ Options: - `--output`: (required) specifies the directory to store traffic files. - `--duration`: (required) specifies the duration of capture. The unit is one of `m` (minutes), `h` (hours), or `d` (days). For example, `--duration=1h` captures traffic for one hour. +- `--compress`: (optional) specifies whether to compress traffic files. `true` means compression, and the compression format is gzip. `false` means no compression. The default value is `true`. +- `--encryption-method`: (optional) specifies the algorithm for encrypting traffic files. Only `""`, `plaintext`, and `aes256-ctr` are supported. `""` and `plaintext` indicate no encryption, and `aes256-ctr` indicates encryption using the `AES256-CTR` algorithm. When specifying encryption, you also need to configure [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path). The default value is `""`. Example: @@ -181,9 +183,10 @@ The `tiproxyctl traffic replay` command is used to replay captured traffic. Options: - `--username`: (required) specifies the database username for replay. -- `--password`: (optional) specifies the password for the username. The default value is an empty string `""`. +- `--password`: (optional) specifies the password for the username. If not specified, you need to enter the password in an interactive mode. - `--input`: (required) specifies the directory containing traffic files. - `--speed`: (optional) specifies the replay speed multiplier. The range is `[0.1, 10]`. The default value is `1`, indicating replay at the original speed. +- `--read-only`: (optional) specifies whether to replay only read-only SQL statements. `true` means to replay only read-only SQL statements, and `false` means to replay all SQL statements. The default value is `false`. Example: @@ -195,17 +198,26 @@ tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --passwor #### `traffic cancel` -The `tiproxyctl traffic cancel` command is used to cancel the current capture or replay task. +The `tiproxyctl traffic cancel` command is used to cancel the current capture or replay job. #### `traffic show` -The `tiproxyctl traffic show` command is used to display historical capture and replay tasks. - -The `status` field in the output indicates the task status, with the following possible values: - -- `done`: the task completed normally. -- `canceled`: the task was canceled. You can check the `error` field for the reason. -- `running`: the task is running. You can check the `progress` field for the completion percentage. +The `tiproxyctl traffic show` command is used to display historical capture and replay jobs. It outputs an array of objects, and each object represents a job. Each job has the following fields: + +- `type`: the job type. `capture` indicates a traffic capture job, `replay` indicates a traffic replay job +- `status`: the current status of the job. `running` indicates in progress, `done` indicates normal completion, and `canceled` indicates job failure. +- `start_time`: the start time of the job +- `end_time`: the end time if the job has completed. Otherwise, it is empty. +- `progress`: the completion percentage of the job +- `error`: if the job fails, this column contains the reason for the failure. Otherwise, it is empty. For example, `manually stopped` means the user manually cancels the job by executing `CANCEL TRAFFIC JOBS`. +- `output`: the output traffic file path of the capture job +- `duration`: the duration of the traffic capture job +- `compress`: whether the traffic files are compressed +- `encryption_method`: the encryption method of the traffic file +- `input`: the input traffic file path of the replay job +- `username`: the database username for traffic replay +- `speed`: the replay speed multiplier +- `read_only`: whether only replays read-only statements Example output: @@ -213,30 +225,31 @@ Example output: [ { "type": "capture", + "status": "done", "start_time": "2024-09-01T14:30:40.99096+08:00", "end_time": "2024-09-01T16:30:40.99096+08:00", - "duration": "2h", - "output": "/tmp/traffic", "progress": "100%", - "status": "done" + "output": "/tmp/traffic", + "duration": "2h", + "compress": true }, { "type": "capture", + "status": "canceled", "start_time": "2024-09-02T18:30:40.99096+08:00", "end_time": "2024-09-02T19:00:40.99096+08:00", - "duration": "2h", - "output": "/tmp/traffic", "progress": "25%", - "status": "canceled", - "error": "canceled manually" + "error": "manually stopped", + "output": "/tmp/traffic", + "duration": "2h" }, { "type": "capture", + "status": "running", "start_time": "2024-09-03T13:31:40.99096+08:00", - "duration": "2h", - "output": "/tmp/traffic", "progress": "45%", - "status": "running" + "output": "/tmp/traffic", + "duration": "2h" } ] ``` diff --git a/tiproxy/tiproxy-configuration.md b/tiproxy/tiproxy-configuration.md index 28bbdcabd4cc7..4e9084af3fde6 100644 --- a/tiproxy/tiproxy-configuration.md +++ b/tiproxy/tiproxy-configuration.md @@ -128,6 +128,13 @@ Configurations for the load balancing policy of TiProxy. + Possible values: `resource`, `location`, `connection` + Specifies the load balancing policy. For the meaning of each possible value, see [TiProxy load balancing policies](/tiproxy/tiproxy-load-balance.md#configure-load-balancing-policies). +### `enable-traffic-replay` + ++ Default value: `true` ++ Support hot-reload: yes ++ Possible values: `true`, `false` ++ Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. + ### ha High availability configurations for TiProxy. @@ -136,7 +143,7 @@ High availability configurations for TiProxy. + Default value: `""` + Support hot-reload: no -+ Specifies the virtual IP address in the CIDR format, such as `"10.0.1.10/24"`. In a cluster with multiple TiProxy instances, only one instance binds to the virtual IP. If this instance goes offline, another TiProxy instance will automatically bind to the IP, ensuring clients can always connect to an available TiProxy through the virtual IP. ++ Specifies the virtual IP address in the CIDR format, such as `"10.0.1.10/24"`. When multiple TiProxy instances in a cluster are configured with the same virtual IP, only one TiProxy instance will be bound to the virtual IP. If this instance goes offline, another TiProxy instance will automatically bind to the IP, ensuring clients can always connect to an available TiProxy through the virtual IP. The following is an example configuration: @@ -147,6 +154,8 @@ server_configs: ha.interface: "eth0" ``` +When you need to isolate computing layer resources, you can configure multiple virtual IP addresses and use [label-based load balancing](/tiproxy/tiproxy-load-balance.md#label-based-load-balancing) in combination. For examples, see [label-based load balancing](/tiproxy/tiproxy-load-balance.md#label-based-load-balancing). + > **Note:** > > - Virtual IP is only supported on Linux operating systems. @@ -229,6 +238,7 @@ TLS object fields: + `ca`: specifies the CA + `cert`: specifies the certificate + `key`: specifies the private key ++ `cert-allowed-cn`: when other components connect to TiProxy with TLS, TiProxy can prevent unauthorized access by verifying the `Common Name` in the caller's certificate. This item specifies a list of `Common Name` of valid callers. After setting this item, this TLS object must enable TLS; otherwise, the item does not take effect. For more information on verifying component caller's identity, see [verify component caller's identity](/enable-tls-between-components.md#verify-component-callers-identity). + `auto-certs`: mostly used for tests. It generates certificates if no certificate or key is specified. + `skip-ca`: skips verifying certificates using CA on client object or skips server-side verification on server object. + `min-tls-version`: sets the minimum TLS version. Possible values are `1.0`、`1.1`、`1.2`, and `1.3`. The default value is `1.2`, which allows v1.2 or higher TLS versions. @@ -241,7 +251,7 @@ For client TLS object: - You must set either `ca` or `skip-ca` to skip verifying server certificates. - Optionally, you can set `cert` or `key` to pass server-side client verification. -- Useless fields: auto-certs. +- Useless fields: `cert-allowed-cn`, `auto-certs`, `rsa-key-size`, `autocert-expire-duration`. For server TLS object: @@ -252,6 +262,16 @@ For server TLS object: A client TLS object. It is used to access TiDB or PD. +#### `encryption-key-path` + ++ Default value: `""` ++ Support hot-reload: yes ++ Specifies the file path of the key used to encrypt the traffic files during traffic capture. The TiProxy instance used for replay needs to be configured with the same key file. The file must contain a 256-bit (32-byte) hexadecimal string with no additional content. An example of the file content is as follows: + +``` +3b5896b5be691006e0f71c3040a2949 +``` + #### `require-backend-tls` + Default value: `false` diff --git a/tiproxy/tiproxy-load-balance.md b/tiproxy/tiproxy-load-balance.md index 29a8d706eea10..583a1e8986ba9 100644 --- a/tiproxy/tiproxy-load-balance.md +++ b/tiproxy/tiproxy-load-balance.md @@ -38,10 +38,11 @@ After configuration, TiProxy uses the label name specified in `balance.label-nam Consider an application that handles both transaction and BI workloads. To prevent these workloads from interfering with each other, configure your cluster as follows: 1. Set [`balance.label-name`](/tiproxy/tiproxy-configuration.md#label-name) to `"app"` in TiProxy, indicating that TiDB servers will be matched by the label name `"app"`, and connections will be routed to TiDB servers with matching label values. -2. Configure two TiProxy instances, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tiproxy/tiproxy-configuration.md#labels) configuration items. -3. Divide TiDB instances into two groups, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tidb-configuration-file.md#labels) configuration items. -4. Optional: For storage layer isolation, configure [Placement Rules](/configure-placement-rules.md) or [Resource Control](/tidb-resource-control-ru-groups.md). -5. Direct transaction and BI clients to connect to their respective TiProxy instance addresses. +2. Deploy at least two TiProxy instances. Configure the TiProxy instance used for transaction business with [`labels`](/tiproxy/tiproxy-configuration.md#labels) as `{"app"="Order"}`, and the instance used for BI business with [`labels`](/tiproxy/tiproxy-configuration.md#labels) as `{"app"="BI"}`. +3. If high availability of TiProxy is required, deploy at least four TiProxy instances, and configure different virtual IP addresses for different businesses. For example, configure two TiProxy instances used for transaction business with virtual IP `10.0.1.10/24`, and two TiProxy instances used for BI business with virtual IP `10.0.1.20/24`. +4. Divide TiDB instances into two groups, adding `"app"="Order"` and `"app"="BI"` to their respective [`labels`](/tidb-configuration-file.md#labels) configuration items. +5. Optional: For storage layer isolation, configure [Placement Rules](/configure-placement-rules.md) or [Resource Control](/tidb-resource-control-ru-groups.md). +6. Direct transaction and BI clients to connect to their respective virtual IP addresses. Label-based Load Balancing @@ -50,35 +51,54 @@ Example configuration for this topology: ```yaml component_versions: tiproxy: "v1.1.0" + server_configs: tiproxy: balance.label-name: "app" tidb: graceful-wait-before-shutdown: 15 + tiproxy_servers: - host: tiproxy-host-1 config: - labels: {app: "Order"} + labels: {"app": "Order"} + ha.virtual-ip: "10.0.1.10/24" + ha.interface: "eth0" - host: tiproxy-host-2 config: - labels: {app: "BI"} + labels: {"app": "Order"} + ha.virtual-ip: "10.0.1.10/24" + ha.interface: "eth0" + - host: tiproxy-host-3 + config: + labels: {"app": "BI"} + ha.virtual-ip: "10.0.1.20/24" + ha.interface: "eth0" + - host: tiproxy-host-4 + config: + labels: {"app": "BI"} + ha.virtual-ip: "10.0.1.20/24" + ha.interface: "eth0" + tidb_servers: - host: tidb-host-1 config: - labels: {app: "Order"} + labels: {"app": "Order"} - host: tidb-host-2 config: - labels: {app: "Order"} + labels: {"app": "Order"} - host: tidb-host-3 config: - labels: {app: "BI"} + labels: {"app": "BI"} - host: tidb-host-4 config: - labels: {app: "BI"} + labels: {"app": "BI"} + tikv_servers: - host: tikv-host-1 - host: tikv-host-2 - host: tikv-host-3 + pd_servers: - host: pd-host-1 - host: pd-host-2 diff --git a/tiproxy/tiproxy-traffic-replay.md b/tiproxy/tiproxy-traffic-replay.md index 1a0e93d494b56..e453db837651a 100644 --- a/tiproxy/tiproxy-traffic-replay.md +++ b/tiproxy/tiproxy-traffic-replay.md @@ -5,11 +5,7 @@ summary: Introduce the use cases and steps for the TiProxy traffic replay featur # TiProxy Traffic Replay -> **Warning:** -> -> Currently, the TiProxy traffic replay feature is experimental. It is not recommended that you use it in production environments. This feature might be changed or removed without prior notice. If you find a bug, you can report an [issue](https://github.com/pingcap/tiproxy/issues) on GitHub. - -Starting from TiProxy v1.3.0, you can use TiProxy to capture access traffic in a TiDB production cluster and replay it in a test cluster at a specified rate. This feature enables you to reproduce actual workloads from the production cluster in a test environment, verifying SQL statement execution results and performance. +Starting from TiProxy v1.3.0, you can use TiProxy to capture access traffic in a TiDB production cluster and replay it in a test cluster at a specified rate. This feature enables you to reproduce actual workloads from the production cluster in a test environment, verifying SQL statement execution results and performance. Starting from v1.4.0, the TiProxy traffic replay feature becomes generally available (GA). TiProxy traffic replay @@ -29,6 +25,60 @@ Traffic replay is not suitable for the following scenarios: ## Usage +Before TiDB v9.0.0, only `tiproxyctl` is supported to connect to TiProxy for traffic capture and replay. Starting from TiDB v9.0.0, it is recommended to use SQL statements to capture and replay traffic. + + +
+ +1. Prepare the test environment: + + 1. Create a test cluster. For more information, see [Deploy a TiDB Cluster Using TiUP](/production-deployment-using-tiup.md). + 2. Replicate data from the production cluster to the test cluster. For more information, see [Data Migration Overview](/migration-overview.md). + 3. Run the [`ANALYZE`](/sql-statements/sql-statement-analyze-table.md) statement in the test cluster to update statistics. + +2. Use the [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md) statement to capture traffic. + + TiProxy supports capturing traffic to local and external storage. When capturing traffic to local, you need to manually copy the traffic file to the TiProxy cluster for replay after capturing the traffic, but when using external storage, there is no need to manually copy. TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, or other S3-compatible file storage services. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). + + To capture traffic, the current user must have the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + + > **Note:** + > + > - TiProxy captures traffic on all connections, including existing and newly created ones. + > - The higher the CPU usage of TiProxy, the greater the impact of traffic capture on QPS. To reduce the impact on the production cluster, it is recommended to reserve at least 30% of CPU capacity, which results in an approximately 3% decrease in average QPS. For detailed performance data, see [Traffic capture test](/tiproxy/tiproxy-performance-test.md#traffic-capture-test). + > - TiProxy does not automatically delete previous capture files when capturing traffic again. You need to manually delete them. + + For example, the following statement enables all TiProxy instances to capture traffic for one hour and save the traffic to the `/tmp/traffic` directory of each TiProxy instance: + + ```sql + TRAFFIC CAPTURE TO "/tmp/traffic" DURATION="1h" + ``` + + Traffic files are automatically rotated and compressed. For more options, see [`TRAFFIC CAPTURE`](/sql-statements/sql-statement-traffic-capture.md). + +3. If the traffic files are captured to the TiProxy local storage, copy the traffic file directory to the TiProxy instances in the test cluster. + +4. Use the [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md) statement to replay traffic. + + Replaying traffic requires the current user to have the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + + By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load. + + For example, the following statement connects to all TiProxy instances with username `u1` and password `123456`, reads the traffic files from the `/tmp/traffic` directory of each instance, and replays the traffic: + + ```sql + TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" + ``` + + Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. If the production cluster has a [resource group](/tidb-resource-control-ru-groups.md#manage-resource-groups), TiProxy automatically sets the resource group of each session to the same as when it was captured. Therefore, configure the [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) [privilege](/sql-statements/sql-statement-set-resource-group.md#privilege) for `u1`. + + If you replay all statements, before replaying again, you may need to restore the data to before the last replay to avoid errors caused by data duplication. You can also add the `READ_ONLY=true` option to replay only read-only statements to avoid restoring data before each replay. + + For more information, see [`TRAFFIC REPLAY`](/sql-statements/sql-statement-traffic-replay.md). + +
+
+ 1. Prepare the test environment: 1. Create a test cluster. For more information, see [Deploy a TiDB Cluster Using TiUP](/production-deployment-using-tiup.md). @@ -38,11 +88,12 @@ Traffic replay is not suitable for the following scenarios: 2. Use the [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture) command to connect to the production cluster's TiProxy instance and start capturing traffic. + TiProxy supports capturing traffic to local and external storage. When capturing traffic to local, you need to manually copy the traffic file to the TiProxy cluster for replay after capturing the traffic, but when using external storage, there is no need to manually copy. TiProxy supports external storage including Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, or other file storage services that implement the S3 protocol. For more information about external storage, see [URI formats of external storage services](/external-storage-uri.md). + > **Note:** > > - TiProxy captures traffic on all connections, including existing and newly created ones. - > - In TiProxy primary-secondary mode, connect to the primary TiProxy instance. - > - If TiProxy is configured with a virtual IP, it is recommended to connect to the virtual IP address. + > - If TiProxy is configured with a virtual IP, it is recommended to connect to the virtual IP address. If there are multiple active TiProxy instances, connect to each TiProxy instance to execute. > - The higher the CPU usage of TiProxy, the greater the impact of traffic capture on QPS. To reduce the impact on the production cluster, it is recommended to reserve at least 30% of CPU capacity, which results in an approximately 3% decrease in average QPS. For detailed performance data, see [Traffic capture test](/tiproxy/tiproxy-performance-test.md#traffic-capture-test). > - TiProxy does not automatically delete previous capture files when capturing traffic again. You need to manually delete them. @@ -52,19 +103,12 @@ Traffic replay is not suitable for the following scenarios: tiproxyctl traffic capture --host 10.0.1.10 --port 3080 --output="/tmp/traffic" --duration=1h ``` - Traffic files are automatically rotated and compressed. Example files in the `/tmp/traffic` directory: - - ```shell - ls /tmp/traffic - # meta traffic-2024-08-29T17-37-12.477.log.gz traffic-2024-08-29T17-43-11.166.log.gz traffic.log - ``` - - For more information, see [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture). + Traffic files are automatically rotated and compressed. For more options, see [`tiproxyctl traffic capture`](/tiproxy/tiproxy-command-line-flags.md#traffic-capture). -3. Copy the traffic file directory to the test cluster's TiProxy instance. +3. If the traffic files are captured to the TiProxy local storage, copy the traffic file directory to the TiProxy instances in the test cluster. 4. Use [`tiproxyctl traffic replay`](/tiproxy/tiproxy-command-line-flags.md#traffic-replay) to connect to the test cluster's TiProxy instance and start replaying traffic. - By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load and ensure consistent transaction execution order. + By default, SQL statements are executed at the same rate as in the production cluster, and each database connection corresponds to a connection in the production cluster to simulate the production load. For example, the following command connects to the TiProxy instance at `10.0.1.10:3080` using username `u1` and password `123456`, reads traffic files from the `/tmp/traffic` directory on the TiProxy instance, and replays the traffic: @@ -72,72 +116,94 @@ Traffic replay is not suitable for the following scenarios: tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --password="123456" --input="/tmp/traffic" ``` - Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. + Because all traffic runs under user `u1`, ensure `u1` can access all databases and tables. If no such user exists, create one. If the production cluster has a [resource group](/tidb-resource-control-ru-groups.md#manage-resource-groups), TiProxy automatically sets the resource group of each session to the same as when it was captured. Therefore, configure the [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) [privilege](/sql-statements/sql-statement-set-resource-group.md#privilege) for `u1`. + + If you replay all statements, before replaying again, you might need to restore the data to before the last replay to avoid errors caused by data duplication. You can also add the `--read-only=true` option to replay only read-only statements to avoid restoring data before each replay. For more information, see [`tiproxyctl traffic replay`](/tiproxy/tiproxy-command-line-flags.md#traffic-replay). -5. View the replay report. +
+
- After replay completion, the report is stored in the `tiproxy_traffic_replay` database on the test cluster. This database contains two tables: `fail` and `other_errors`. +## View the replay report - The `fail` table stores failed SQL statements, with the following fields: +After replay completion, the report is stored in the `tiproxy_traffic_replay` database on the test cluster. This database contains two tables: `fail` and `other_errors`. - - `cmd_type`: the type of a failed command, such as `Query` (execute an ordinary statement), `Prepare` (prepare a statement), and `Execute` (execute a prepared statement). - - `digest`: the digest of the failed SQL statement. - - `sample_stmt`: the SQL text when the statement first failed. - - `sample_err_msg`: the error message when the SQL statement failed. - - `sample_conn_id`: the connection ID recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. - - `sample_capture_time`: the execution time recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. - - `sample_replay_time`: the time when the SQL statement failed during replay. You can use this to view error information in the TiDB log file. - - `count`: the number of times the SQL statement failed. +The `fail` table stores failed SQL statements, with the following fields: - The following is an example output of the `fail` table: +- `replay_start_time`: the start time of the replay job, which is used to uniquely identify a replay job. It can be used to filter replay jobs. +- `cmd_type`: the type of a failed command, such as `Query` (execute an ordinary statement), `Prepare` (prepare a statement), and `Execute` (execute a prepared statement). +- `digest`: the digest of the failed SQL statement. +- `sample_stmt`: the SQL text when the statement first failed. +- `sample_err_msg`: the error message when the SQL statement failed. +- `sample_conn_id`: the connection ID recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. +- `sample_capture_time`: the execution time recorded in the traffic file for the SQL statement. You can use this to view the execution context in the traffic file. +- `sample_replay_time`: the time when the SQL statement failed during replay. You can use this to view error information in the TiDB log file. +- `count`: the number of times the SQL statement failed. - ```sql - SELECT * FROM tiproxy_traffic_replay.fail LIMIT 1\G - ``` +The following is an example output of the `fail` table: - ``` - *************************** 1. row *************************** - cmd_type: StmtExecute - digest: 89c5c505772b8b7e8d5d1eb49f4d47ed914daa2663ed24a85f762daa3cdff43c - sample_stmt: INSERT INTO new_order (no_o_id, no_d_id, no_w_id) VALUES (?, ?, ?) params=[3077 6 1] - sample_err_msg: ERROR 1062 (23000): Duplicate entry '1-6-3077' for key 'new_order.PRIMARY' - sample_conn_id: 1356 - sample_capture_time: 2024-10-17 12:59:15 - sample_replay_time: 2024-10-17 13:05:05 - count: 4 - ``` +```sql +SELECT * FROM tiproxy_traffic_replay.fail LIMIT 1\G +``` - The `other_errors` table stores unexpected errors, such as network errors or database connection errors, with the following fields: +``` +*************************** 1. row *************************** + replay_start_time: 2024-10-17 13:05:03 + cmd_type: StmtExecute + digest: 89c5c505772b8b7e8d5d1eb49f4d47ed914daa2663ed24a85f762daa3cdff43c + sample_stmt: INSERT INTO new_order (no_o_id, no_d_id, no_w_id) VALUES (?, ?, ?) params=[3077 6 1] + sample_err_msg: ERROR 1062 (23000): Duplicate entry '1-6-3077' for key 'new_order.PRIMARY' + sample_conn_id: 1356 +sample_capture_time: 2024-10-17 12:59:15 + sample_replay_time: 2024-10-17 13:05:05 + count: 4 +``` - - `err_type`: the type of error, presented as a brief error message. For example, `i/o timeout`. - - `sample_err_msg`: the complete error message when the error first occurred. - - `sample_replay_time`: the time when the error occurred during replay. You can use this to view error information in the TiDB log file. - - `count`: the number of occurrences for this error. +The `other_errors` table stores unexpected errors, such as network errors or database connection errors, with the following fields: - The following is an example output of the `other_errors` table: +- `replay_start_time`: the start time of the replay job, which is used to uniquely identify a replay job. It can be used to filter replay jobs. +- `err_type`: the type of error, presented as a brief error message. For example, `i/o timeout`. +- `sample_err_msg`: the complete error message when the error first occurred. +- `sample_replay_time`: the time when the error occurred during replay. You can use this to view error information in the TiDB log file. +- `count`: the number of occurrences for this error. - ```sql - SELECT * FROM tiproxy_traffic_replay.other_errors LIMIT 1\G - ``` +The following is an example output of the `other_errors` table: - ``` - *************************** 1. row *************************** - err_type: failed to read the connection: EOF - sample_err_msg: this is an error from the backend connection: failed to read the connection: EOF - sample_replay_time: 2024-10-17 12:57:39 - count: 1 - ``` +```sql +SELECT * FROM tiproxy_traffic_replay.other_errors LIMIT 1\G +``` - > **Note:** - > - > - The table schema of `tiproxy_traffic_replay` might change in future versions. It is not recommended to directly read data from `tiproxy_traffic_replay` in your application or tool development. - > - Replay does not guarantee that the transaction execution order between connections exactly matches the capture sequence. This might lead to incorrect error reports. - > - TiProxy does not automatically delete the previous replay report when replaying traffic. You need to manually delete it. +``` +*************************** 1. row *************************** + replay_start_time: 2024-10-17 12:57:35 + err_type: failed to read the connection: EOF + sample_err_msg: this is an error from the backend connection: failed to read the connection: EOF +sample_replay_time: 2024-10-17 12:57:39 + count: 1 +``` + +> **Note:** +> +> - The table schema of `tiproxy_traffic_replay` might change in future versions. It is not recommended to directly read data from `tiproxy_traffic_replay` in your application or tool development. +> - Replay does not guarantee that the transaction execution order between connections exactly matches the capture sequence. This might lead to incorrect error reports. ## Test throughput + +
+ +To test cluster throughput, use the `SPEED` option to adjust the replay rate. + +For example, `SPEED=2` executes SQL statements at twice the rate, reducing the total replay time by half: + +```sql +TRAFFIC REPLAY FROM "/tmp/traffic" USER="u1" PASSWORD="123456" SPEED=2 +``` + +
+
+ To test cluster throughput, use the `--speed` option to adjust the replay rate. For example, `--speed=2` executes SQL statements at twice the rate, reducing the total replay time by half: @@ -146,34 +212,79 @@ For example, `--speed=2` executes SQL statements at twice the rate, reducing the tiproxyctl traffic replay --host 10.0.1.10 --port 3080 --username="u1" --password="123456" --input="/tmp/traffic" --speed=2 ``` +
+
+ Increasing the replay rate only reduces idle time between SQL statements and does not increase the number of connections. When session idle time is already short, increasing the speed might not effectively improve throughput. In such cases, you can deploy multiple TiProxy instances to replay the same traffic files simultaneously, increasing concurrency to improve throughput. -## View and manage tasks +## View and manage jobs + + +
+ +During capture and replay, jobs automatically stop if unknown errors occur. To view the current job progress or error information from the last job, use the [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md) statement: + +```sql +SHOW TRAFFIC JOBS +``` + +The shown results vary depending on the privileges the current user has. + +- If the user has the [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege, this statement shows traffic capture jobs. +- If the user has the [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege, this statement shows traffic replay jobs. +- If the user has the `SUPER` privilege or both above privileges, this statement shows both traffic capture and traffic replay jobs. + +For example, the following output indicates that 2 TiProxy instances are capturing traffic: + +``` ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| START_TIME | END_TIME | INSTANCE | TYPE | PROGRESS | STATUS | FAIL_REASON | PARAMS | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +| 2024-12-17 10:54:41.000000 | | 10.1.0.10:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | +| 2024-12-17 10:54:41.000000 | | 10.1.0.11:3080 | capture | 45% | running | | OUTPUT="/tmp/traffic", DURATION="90m", COMPRESS=true, ENCRYPTION_METHOD="" | ++----------------------------+----------+----------------+---------+----------+---------+-------------+----------------------------------------------------------------------------+ +2 rows in set (0.01 sec) +``` -During capture and replay, tasks automatically stop if unknown errors occur. To view the current task progress or error information from the last task, use the [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show) command: +For more information, see [`SHOW TRAFFIC JOBS`](/sql-statements/sql-statement-show-traffic-jobs.md). + +To cancel the current capture or replay job, use the [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md) statement: + +```sql +CANCEL TRAFFIC JOBS +``` + +Canceling traffic capture jobs requires the `SUPER` or [`TRAFFIC_CAPTURE_ADMIN`](/privilege-management.md#dynamic-privileges) privilege and canceling traffic replay jobs requires the `SUPER` or [`TRAFFIC_REPLAY_ADMIN`](/privilege-management.md#dynamic-privileges) privilege. + +For more information, see [`CANCEL TRAFFIC JOBS`](/sql-statements/sql-statement-cancel-traffic-jobs.md). + +
+
+ +During capture and replay, jobs automatically stop if unknown errors occur. To view the current job progress or error information from the last job, use the [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show) command: ```shell tiproxyctl traffic show --host 10.0.1.10 --port 3080 ``` -For example, the following output indicates a running capture task: +For example, the following output indicates a running capture job: ```json [ { "type": "capture", + "status": "running", "start_time": "2024-09-03T09:10:58.220644+08:00", - "duration": "2h", - "output": "/tmp/traffic", "progress": "45%", - "status": "running" + "output": "/tmp/traffic", + "duration": "2h" } ] ``` For more information, see [`tiproxyctl traffic show`](/tiproxy/tiproxy-command-line-flags.md#traffic-show). -To cancel the current capture or replay task, use the [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel) command: +To cancel the current capture or replay job, use the [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel) command: ```shell tiproxyctl traffic cancel --host 10.0.1.10 --port 3080 @@ -181,12 +292,22 @@ tiproxyctl traffic cancel --host 10.0.1.10 --port 3080 For more information, see [`tiproxyctl traffic cancel`](/tiproxy/tiproxy-command-line-flags.md#traffic-cancel). +
+
+ ## Limitations - TiProxy only supports replaying traffic files captured by TiProxy and does not support other file formats. Therefore, make sure to capture traffic from the production cluster using TiProxy first. -- TiProxy traffic replay does not support filtering SQL types and DML and DDL statements are replayed. Therefore, you need to restore the cluster data to its pre-replay state before replaying again. -- TiProxy traffic replay does not support testing [Resource Control](/tidb-resource-control-ru-groups.md) and [privilege management](/privilege-management.md) because TiProxy uses the same username to replay traffic. - TiProxy does not support replaying [`LOAD DATA`](/sql-statements/sql-statement-load-data.md) statements. +- For security reasons, the following statements will not be captured and replayed: + + - `CREATE USER` statement + - `ALTER USER` statement + - `SET PASSWORD` statement + - `GRANT` statement + - `BACKUP` statement + - `RESTORE` statement + - `IMPORT` statement ## More resources diff --git a/tiup/tiup-cluster-topology-reference.md b/tiup/tiup-cluster-topology-reference.md index 0f7f604a2749a..b9ae6807af547 100644 --- a/tiup/tiup-cluster-topology-reference.md +++ b/tiup/tiup-cluster-topology-reference.md @@ -404,7 +404,7 @@ tikv_servers: - `resource_control`: Resource control for the service. If this field is configured, the field content is merged with the `resource_control` content in `global` (if the two fields overlap, the content of this field takes effect). Then, a systemd configuration file is generated and sent to the machine specified in `host`. The configuration rules of `resource_control` are the same as the `resource_control` content in `global`. -After the deployment, for the fields above, you can only add directories to `data_dir`; for the fields below, you cannot modified these fields: +After the deployment, for the fields above, you can only add directories to `data_dir`; for the fields below, you cannot modify these fields: - `host` - `tcp_port` diff --git a/tiup/tiup-cluster.md b/tiup/tiup-cluster.md index f5ca368a3d154..234437c44757c 100644 --- a/tiup/tiup-cluster.md +++ b/tiup/tiup-cluster.md @@ -700,7 +700,7 @@ Environment checks are not necessary for deploying a cluster. For the production All operations above performed on the cluster machine use the SSH client embedded in TiUP to connect to the cluster and execute commands. However, in some scenarios, you might also need to use the SSH client native to the control machine system to perform such cluster operations. For example: -- To use a SSH plug-in for authentication +- To use an SSH plug-in for authentication - To use a customized SSH client Then you can use the `--ssh=system` command-line flag to enable the system-native command-line tool: diff --git a/tiup/tiup-command-mirror-rotate.md b/tiup/tiup-command-mirror-rotate.md index 699ef31f144ca..1a1e8a1b2e71e 100644 --- a/tiup/tiup-command-mirror-rotate.md +++ b/tiup/tiup-command-mirror-rotate.md @@ -35,7 +35,7 @@ TiUP uses the command `tiup mirror rotate` to automate the above process. > **Note:** > -> + For TiUP versions earlier than v1.5.0, running this command does not returns a correct new `root.json` file. See [#983](https://github.com/pingcap/tiup/issues/983). +> + For TiUP versions earlier than v1.5.0, running this command does not return a correct new `root.json` file. See [#983](https://github.com/pingcap/tiup/issues/983). > + Before using this command, make sure that all TiUP clients are upgraded to v1.5.0 or a later version. ## Syntax diff --git a/tiup/tiup-command-mirror-sign.md b/tiup/tiup-command-mirror-sign.md index cfa6846a3491b..53767fc35281a 100644 --- a/tiup/tiup-command-mirror-sign.md +++ b/tiup/tiup-command-mirror-sign.md @@ -5,7 +5,7 @@ summary: The `tiup mirror sign` command is used to sign metadata files in TiUP m # tiup mirror sign -The `tiup mirror sign` command is used to sign the metadata files (*.json)defined in TiUP [mirror](/tiup/tiup-mirror-reference.md). These metadata files might be stored on the local file system or remotely stored using the HTTP protocol to provide a signature entry. +The `tiup mirror sign` command is used to sign the metadata files (*.json) defined in TiUP [mirror](/tiup/tiup-mirror-reference.md). These metadata files might be stored on the local file system or remotely stored using the HTTP protocol to provide a signature entry. ## Syntax diff --git a/tiup/tiup-component-cluster-enable.md b/tiup/tiup-component-cluster-enable.md index 9d54e4484d118..c2d7dc3ba2671 100644 --- a/tiup/tiup-component-cluster-enable.md +++ b/tiup/tiup-component-cluster-enable.md @@ -9,7 +9,7 @@ The `tiup cluster enable` command is used to set the auto-enabling of the cluste > **Note:** > -> When all clusters are shut down and restarted, the order of service startup is determined by the node's operating system startup order. When the restart order is incorrect, in some cases, the restarted cluster still cannot provide services. For example, if TiKV is started first but PD is not started, systemd gives up if TiKV is restarted multiple times while PD is not found). +> When all clusters are shut down and restarted, the order of service startup is determined by the node's operating system startup order. When the restart order is incorrect, in some cases, the restarted cluster still cannot provide services. For example, if TiKV is started first but PD is not started, systemd gives up if TiKV is restarted multiple times while PD is not found. ## Syntax diff --git a/tiup/tiup-component-cluster-patch.md b/tiup/tiup-component-cluster-patch.md index d91ddd96b6df8..3fe0b7a9ae694 100644 --- a/tiup/tiup-component-cluster-patch.md +++ b/tiup/tiup-component-cluster-patch.md @@ -70,7 +70,7 @@ After you have completed the preceding steps, you can use `/tmp/${component}-hot ### --overwrite -- After you patch a certain component (such as TiDB or TiKV), when the tiup cluster scales out the component, TiUP uses the original component version by default. To use the version that you patch when the cluster scales out in the future, you need to specified the option `--overwrite` in the command. +- After you patch a certain component (such as TiDB or TiKV), when the tiup cluster scales out the component, TiUP uses the original component version by default. To use the version that you patch when the cluster scales out in the future, you need to specify the option `--overwrite` in the command. - Data type: `BOOLEAN` - This option is disabled by default with the `false` value. To enable this option, add this option to the command, and either pass the `true` value or do not pass any value. diff --git a/tiup/tiup-component-dm-patch.md b/tiup/tiup-component-dm-patch.md index 46512ba2ffa50..64489416a273c 100644 --- a/tiup/tiup-component-dm-patch.md +++ b/tiup/tiup-component-dm-patch.md @@ -79,7 +79,7 @@ The following example shows how to apply `v5.3.0-hotfix` to the `v5.3.0` cluster > **Note:** > -> Hotfix is used only for emergency fixes. Its daily maintenance is complicated. It is recommend that you upgrade the DM cluster to an official version as soon as it is released. +> Hotfix is used only for emergency fixes. Its daily maintenance is complicated. It is recommended that you upgrade the DM cluster to an official version as soon as it is released. ### Preparations diff --git a/tiup/tiup-component-dm.md b/tiup/tiup-component-dm.md index 0a9e6aacb1c34..5f483af57247b 100644 --- a/tiup/tiup-component-dm.md +++ b/tiup/tiup-component-dm.md @@ -39,7 +39,7 @@ tiup dm [command] [flags] - Specifies the maximum waiting time (in seconds) for each step in the operation process. The operation process consists of many steps, such as specifying systemctl to start or stop services, and waiting for ports to be online or offline. Each step may take several seconds. If the execution time of a step exceeds the specified timeout, the step exits with an error. - Data type: `UINT` -- If this option is not specified in the command, the maximum waiting time for each steps is `120` seconds. +- If this option is not specified in the command, the maximum waiting time for each step is `120` seconds. ### -y, --yes diff --git a/tune-operating-system.md b/tune-operating-system.md index 9007714bcc7b0..d54e9d5e409fb 100644 --- a/tune-operating-system.md +++ b/tune-operating-system.md @@ -10,7 +10,7 @@ This document introduces how to tune each subsystem of CentOS 7. > **Note:** > -> + The default configuration of the CentOS 7 operating system is suitable for most services running under moderate workloads. Adjusting the performance of a particular subsystem might negatively affects other subsystems. Therefore, before tuning the system, back up all the user data and configuration information. +> + The default configuration of the CentOS 7 operating system is suitable for most services running under moderate workloads. Adjusting the performance of a particular subsystem might negatively affect other subsystems. Therefore, before tuning the system, back up all the user data and configuration information. > + Fully test all the changes in the test environment before applying them to the production environment. ## Performance analysis methods diff --git a/vector-search/vector-search-index.md b/vector-search/vector-search-index.md index c5bd4021c520f..312f6a8ca3ba3 100644 --- a/vector-search/vector-search-index.md +++ b/vector-search/vector-search-index.md @@ -5,9 +5,9 @@ summary: Learn how to build and use the vector search index to accelerate K-Near # Vector Search Index -K-nearest neighbors (KNN) search is the method for finding the K closest points to a given point in a vector space. The most straightforward approach to perform KNN search is a brute force search, which calculates the distance between the given vector and all other vectors in the space. This approach guarantees perfect accuracy, but it is usually too slow for real-world use. Therefore, approximate algorithms are commonly used in KNN search to enhance speed and efficiency. +As described in the [Vector Search](/vector-search/vector-search-overview.md) document, vector search identifies the Top K-Nearest Neighbors (KNN) to a given vector by calculating the distance between the given vector and all vectors stored in the database. While this approach provides accurate results, it can be slow when the table contains a large number of vectors because it involves a full table scan. -In TiDB, you can create and use vector search indexes for such approximate nearest neighbor (ANN) searches over columns with [vector data types](/vector-search/vector-search-data-types.md). By using vector search indexes, vector search queries could be finished in milliseconds. +To improve search efficiency, you can create vector search indexes in TiDB for approximate KNN (ANN) search. When using vector indexes for vector search, TiDB can greatly improve query performance with only a slight reduction in accuracy, generally maintaining a search recall rate above 90%. diff --git a/vector-search/vector-search-integrate-with-llamaindex.md b/vector-search/vector-search-integrate-with-llamaindex.md index e074a46eaf361..fc0901a895211 100644 --- a/vector-search/vector-search-integrate-with-llamaindex.md +++ b/vector-search/vector-search-integrate-with-llamaindex.md @@ -108,7 +108,7 @@ For a TiDB Cloud Serverless cluster, take the following steps to obtain the clus 5. Configure environment variables. - This document uses [OpenAI](https://platform.openai.com/docs/introduction) as the embedding model provider. In this step, you need to provide the connection string obtained from from the previous step and your [OpenAI API key](https://platform.openai.com/docs/quickstart/step-2-set-up-your-api-key). + This document uses [OpenAI](https://platform.openai.com/docs/introduction) as the embedding model provider. In this step, you need to provide the connection string obtained from the previous step and your [OpenAI API key](https://platform.openai.com/docs/quickstart/step-2-set-up-your-api-key). To configure the environment variables, run the following code. You will be prompted to enter your connection string and OpenAI API key: diff --git a/workload-repository.md b/workload-repository.md new file mode 100644 index 0000000000000..81fcc5a6383b6 --- /dev/null +++ b/workload-repository.md @@ -0,0 +1,117 @@ +--- +title: TiDB Workload Repository +summary: Introduces the workload repository system for collecting and storing historical workload data from a TiDB cluster. +--- + +# TiDB Workload Repository + +The workload repository is a system for collecting and storing historical workload data from a TiDB cluster. It periodically samples various system tables to track cluster performance and usage patterns over time. + +## Enable the Workload Repository + +To enable the Workload Repository, set the [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900) system variable: + +```sql +SET GLOBAL tidb_workload_repository_dest = 'table'; +``` + +To disable it: + +```sql +SET GLOBAL tidb_workload_repository_dest = ''; +``` + +## Data collection + +The Workload Repository stores data in tables under the `WORKLOAD_SCHEMA` database. It collects data via two different methods: + +* The snapshot sampling process, which runs at configurable intervals, hourly by default, and can be triggered manually. +* The time-based sampling process, which runs at shorter intervals, typically every 5 seconds. + +## Snapshot sampling process (hourly by default) + +The snapshot sampling process, which runs every 15 minutes to 2 hours, samples data from various cumulative metrics tables. Snapshots are initiated from one of the TiDB nodes at the specified intervals, and the process is as follows: + +1. From the initiating node, a row is inserted into `WORKLOAD_SCHEMA.HIST_SNAPSHOTS`, capturing the snapshot ID, start and end timestamps, and server version details. +2. On each TiDB node, all rows from the source tables are copied to the corresponding target tables with the `HIST_` prefix. The copied data includes the original columns from the source tables plus additional columns for the timestamp, instance ID, and snapshot ID. + +Note that the sampled tables return data specific to the TiDB node from which they are queried. + +Data is sampled from the following tables: + +| Source table | Destination table | Description | +| --- | --- | --- | +| [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) | `HIST_TIDB_INDEX_USAGE` | Index usage statistics | +| [`TIDB_STATEMENTS_STATS`](/statement-summary-tables.md) | `HIST_TIDB_STATEMENTS_STATS` | Statement statistics | +| [`CLIENT_ERRORS_SUMMARY_BY_HOST`](/information-schema/client-errors-summary-by-host.md) | `HIST_CLIENT_ERRORS_SUMMARY_BY_HOST` | Client error summaries by host | +| [`CLIENT_ERRORS_SUMMARY_BY_USER`](/information-schema/client-errors-summary-by-user.md) | `HIST_CLIENT_ERRORS_SUMMARY_BY_USER` | Client error summaries by user | +| [`CLIENT_ERRORS_SUMMARY_GLOBAL`](/information-schema/client-errors-summary-global.md) | `HIST_CLIENT_ERRORS_SUMMARY_GLOBAL` | Client error summaries by global | + +The snapshot sampling interval can be controlled with [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900): + +```sql +SET GLOBAL tidb_workload_repository_snapshot_interval = 900; -- set the interval to 15 minutes +``` + +## Manual snapshots + +Note that while the snapshot sampling process runs automatically based on the configured interval, you can also trigger a manual snapshot using the following SQL statement: + +```sql +ADMIN CREATE WORKLOAD SNAPSHOT; +``` + +Manually triggering snapshots does not change the interval or timing of automatic snapshots. + +## Time-based sampling process (every 5 seconds by default) + +The time-based sampling process samples data from various non-cumulative metrics tables at intervals ranging from 1 to 600 seconds. + +When the time-base sampling process runs, all rows from the source tables are copied to the corresponding target tables with the `HIST_` prefix. The copied data includes the original columns from the source tables plus additional columns for the timestamp and instance ID. + +Unlike the snapshot sampling process, a row will not be added to the `HIST_SNAPSHOTS` table. + +Note that the sampled tables return data specific to the TiDB node from which they are queried. + +Data is sampled from the following tables: + +| Source table | Destination table | Description | +| --- | --- | --- | +| [`PROCESSLIST`](/information-schema/information-schema-processlist.md) | `HIST_PROCESSLIST` | Active sessions | +| [`DATA_LOCK_WAITS`](/information-schema/information-schema-data-lock-waits.md) | `HIST_DATA_LOCK_WAITS` | Data lock waits | +| [`TIDB_TRX`](/information-schema/information-schema-tidb-trx.md) | `HIST_TIDB_TRX` | Active transactions | +| [`MEMORY_USAGE`](/information-schema/information-schema-memory-usage.md) | `HIST_MEMORY_USAGE` | Memory usage | +| [`DEADLOCKS`](/information-schema/information-schema-deadlocks.md) | `HIST_DEADLOCKS` | Deadlock information | + +The time-based sampling interval can be controlled with [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900): + +```sql +SET GLOBAL tidb_workload_repository_active_sampling_interval = 20; -- set the interval to 20 seconds +``` + +Setting this global variable to `0` disables the time-based sampling process. + +## Data retention + +Historical data in the Workload Repository is retained for seven days by default. The system automatically purges data based on the retention period setting, using partitions for efficient data management. + +By default the Workload Repository retains historical data for seven days, but the [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) variable can be used to control the length of this period. For example, to keep data for 30 days, run the following: + +```sql +SET GLOBAL tidb_workload_repository_retention_days = 30; +``` + +A higher value for this variable allows for longer data retention, which might be beneficial for workload analysis, but will increase storage requirements. + +## Notes + +- Enabling the Workload Repository might have a small performance impact on the system. +- Setting sampling intervals too short might increase system overhead. +- Setting retention days to `0` disables automatic purging of old data. + +## Best practices + +- Start with default settings and adjust based on your monitoring needs. +- Set reasonable retention periods based on your storage capacity. +- Monitor the size of the `WORKLOAD_SCHEMA` database. +- Use longer sampling intervals in production environments to minimize overhead. diff --git a/wrong-index-solution.md b/wrong-index-solution.md index eb47888f9677a..46a9cc4706dd5 100644 --- a/wrong-index-solution.md +++ b/wrong-index-solution.md @@ -29,7 +29,7 @@ The near 100% health state suggests that the `ANALYZE` statement is just complet For equivalence queries, the cause might be [Count-Min Sketch](/statistics.md#count-min-sketch). You can check whether Count-Min Sketch is the cause and take corresponding solutions. -If the cause above does not apply to your problem, you can force-select indexes by using the `USE_INDEX` or `use index` optimzer hint (see [USE_INDEX](/optimizer-hints.md#use_indext1_name-idx1_name--idx2_name-) for details). Also, you can change the query behavior by using [SQL Plan Management](/sql-plan-management.md) in a non-intrusive way. +If the cause above does not apply to your problem, you can force-select indexes by using the `USE_INDEX` or `use index` optimizer hint (see [USE_INDEX](/optimizer-hints.md#use_indext1_name-idx1_name--idx2_name-) for details). Also, you can change the query behavior by using [SQL Plan Management](/sql-plan-management.md) in a non-intrusive way. ### Other situations From 8feb43a00548c8031515dc8a0a17591b91f74ede Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Mon, 21 Apr 2025 13:31:06 +0800 Subject: [PATCH 26/51] Update releases/release-9.0.0.md --- releases/release-9.0.0.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index d510ded21004e..f25b69e00abec 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -228,10 +228,10 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | [`tidb_pipelined_dml_resource_policy`](/system-variables.md#tidb_pipelined_dml_resource_policy-new-in-v900) | Newly added | Controls the resource usage policy for [Pipelined DML](/pipelined-dml.md). It takes effect only when [`tidb_dml_type`](/system-variables.md#tidb_dml_type-new-in-v800) is set to `bulk`. | | [`tidb_accelerate_user_creation_update`](/system-variables.md/#tidb_accelerate_user_creation_update-new-in-v900)| Newly added | Improves the performance of creating and modifying users in scenarios with hundreds of thousands to millions of users. | | [`tidb_max_dist_task_nodes`](/system-variables.md/#tidb_max_dist_task_nodes-new-in-v900)| Newly added | Controls the maximum number of TiDB nodes available for the Distributed eXecution Framework (DXF) tasks. The default value is `-1`, which enables automatic mode. In this mode, the system automatically selects an appropriate number of nodes. | -| [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Time-based Sampling Process. | -| [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900)| Newly added | Controls the destination of the [Workload Repository](/workloadrepo.md. The default value is `''`, which means to disable the workload repository. The value `'table'` enables the workload repository to write data into TiKV.| -| [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) | Newly added | Controls the number of days that [Workload Repository](/workloadrepo.md) data is retained. | -| [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workloadrepo.md)'s Snapshot Sampling Process. | +| [`tidb_workload_repository_active_sampling_interval`](/system-variables.md#tidb_workload_repository_active_sampling_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workload-repository.md)'s Time-based Sampling Process. | +| [`tidb_workload_repository_dest`](/system-variables.md#tidb_workload_repository_dest-new-in-v900)| Newly added | Controls the destination of the [Workload Repository](/workload-repository.md. The default value is `''`, which means to disable the workload repository. The value `'table'` enables the workload repository to write data into TiKV.| +| [`tidb_workload_repository_retention_days`](/system-variables.md#tidb_workload_repository_retention_days-new-in-v900) | Newly added | Controls the number of days that [Workload Repository](/workload-repository.md) data is retained. | +| [`tidb_workload_repository_snapshot_interval`](/system-variables.md#tidb_workload_repository_snapshot_interval-new-in-v900) | Newly added | Controls the sampling interval for the [Workload Repository](/workload-repository.md)'s Snapshot Sampling Process. | | | | | | | | | | | | | From 94359f90e70e6b90d6294db79e831bc7d5cd8f9f Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Mon, 21 Apr 2025 14:11:04 +0800 Subject: [PATCH 27/51] Apply suggestions from code review --- releases/release-9.0.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index f25b69e00abec..4525443401a46 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -105,7 +105,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * Introduce a new system variable `max_user_connections` to limit the number of connections that different users can establish [#59203](https://github.com/pingcap/tidb/issues/59203) @[joccau](https://github.com/joccau) tw@hfxsd - Starting from v9.0.0, you can use the `max_user_connections` system variable to limit the number of connections a single user can establish to a single TiDB node. This helps prevent issues where excessive [token](/tidb-configuration-file.md/#token-limit) consumption by one user causes delays in responding to requests from other users. + Starting from v9.0.0, you can use the `max_user_connections` system variable to limit the number of connections a single user can establish to a single TiDB node. This helps prevent issues where excessive [token](/tidb-configuration-file.md#token-limit) consumption by one user causes delays in responding to requests from other users. For more information, see [documentation](/system-variables.md/#max_user_connections-new-in-v900) @@ -170,7 +170,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * Optimize the `execution info` in the output of `EXPLAIN ANALYZE` [#56232](https://github.com/pingcap/tidb/issues/56232) @[yibin87](https://github.com/yibin87) tw@hfxsd - [`EXPLAIN ANALYZE`](https://github.com/sql-statements/sql-statement-explain-analyze.md) executes SQL statements and records execution details in the `execution info` column. The same information is captured in the [slow query log](https://github.com/identify-slow-queries.md). These details are crucial for analyzing and understanding the time spent on SQL execution. + [`EXPLAIN ANALYZE`](/sql-statements/sql-statement-explain-analyze.md) executes SQL statements and records execution details in the `execution info` column. The same information is captured in the [slow query log](/identify-slow-queries.md). These details are crucial for analyzing and understanding the time spent on SQL execution. In v9.0.0, the `execution info` output is optimized for clearer representation of each metric. For example, `time` now refers to the wall-clock time for operator execution, `loops` indicates how many times the current operator is called by its parent operator, and `total_time` represents the cumulative duration of all concurrent executions. These optimizations help you better understand the SQL execution process and devise more targeted optimization strategies. From c767416e08bc3f2dd44098906429c17570b23994 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Mon, 21 Apr 2025 14:30:38 +0800 Subject: [PATCH 28/51] Update release-9.0.0.md --- releases/release-9.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 4525443401a46..615892c09b67e 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -246,7 +246,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- | TiKV | [`storage.max-ts.max-drift`](/tikv-configuration-file.md#max-drift-new-in-v900) | Newly added | Specifies the maximum time by which the timestamp of a read or write request can exceed the PD TSO cached in TiKV. The default value is `"60s"`. | | TiFlash| [`format_version`](/tiflash/tiflash-configuration.md#format_version) | Modified | Changes the default value from `7` to `8`, which means the default DTFile file format for v9.0.0 or a later version is `8`. This new format supports a new string serialization scheme that improves string read and write performance. | | TiCDC | [`newarch`](/ticdc/ticdc-server-config.md#newarch) | Newly added | Controls whether to enable the [TiCDC new architecture](/ticdc/ticdc-new-arch.md). By default, `newarch` is not specified, indicating that the old architecture is used. `newarch` applies only to the new architecture. If `newarch` is added to the configuration file of the TiCDC old architecture, it might cause parsing failures. | -| BR | [`--checkpoint-storage`](br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | +| BR | [`--checkpoint-storage`](/br/br-checkpoint-restore.md#implementation-details-store-checkpoint-data-in-the-external-storage) | Newly added | Specifies the external storage for BR to store checkpoint data. | | DM | [`redact-info-log`](/dm/dm-worker-configuration-file.md#redact-info-log-new-in-v900) | Newly added | Controls whether to enable DM log redaction. | | TiProxy | [`enable-traffic-replay`](/tiproxy/tiproxy-configuration.md#enable-traffic-replay) | Newly added | Specifies whether to enable [traffic replay](/tiproxy/tiproxy-traffic-replay.md). If it is set to `false`, traffic capture and replay operations will result in errors. | | TiProxy | [`encryption-key-path`](/tiproxy/tiproxy-configuration.md#encryption-key-path) | Newly added | Specifies the file path of the key used to encrypt the traffic files during traffic capture. | From 648384e92be7afafc786d0011286e8aa4b72d2cd Mon Sep 17 00:00:00 2001 From: Xin Shi Date: Sun, 20 Apr 2025 23:50:41 -0700 Subject: [PATCH 29/51] docs: add attribution for KNN vector search description (#20809) --- vector-search/vector-search-index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector-search/vector-search-index.md b/vector-search/vector-search-index.md index 312f6a8ca3ba3..f922c940f9379 100644 --- a/vector-search/vector-search-index.md +++ b/vector-search/vector-search-index.md @@ -5,7 +5,7 @@ summary: Learn how to build and use the vector search index to accelerate K-Near # Vector Search Index -As described in the [Vector Search](/vector-search/vector-search-overview.md) document, vector search identifies the Top K-Nearest Neighbors (KNN) to a given vector by calculating the distance between the given vector and all vectors stored in the database. While this approach provides accurate results, it can be slow when the table contains a large number of vectors because it involves a full table scan. +As described in the [Vector Search](/vector-search/vector-search-overview.md) document, vector search identifies the Top K-Nearest Neighbors (KNN) to a given vector by calculating the distance between the given vector and all vectors stored in the database. While this approach provides accurate results, it can be slow when the table contains a large number of vectors because it involves a full table scan. [^1] To improve search efficiency, you can create vector search indexes in TiDB for approximate KNN (ANN) search. When using vector indexes for vector search, TiDB can greatly improve query performance with only a slight reduction in accuracy, generally maintaining a search recall rate above 90%. @@ -261,3 +261,5 @@ See [`EXPLAIN`](/sql-statements/sql-statement-explain.md), [`EXPLAIN ANALYZE`](/ - [Improve Vector Search Performance](/vector-search/vector-search-improve-performance.md) - [Vector Data Types](/vector-search/vector-search-data-types.md) + +[^1]: The explanation of KNN search is adapted from the [Approximate Nearest Neighbor Search Indexes](https://github.com/ClickHouse/ClickHouse/pull/50661/files#diff-7ebd9e71df96e74230c9a7e604fa7cb443be69ba5e23bf733fcecd4cc51b7576) document authored by [rschu1ze](https://github.com/rschu1ze) in ClickHouse documentation, licensed under the Apache License 2.0. From 642b4dfd434cd436b62eb1d006a94fe92eb7c336 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Mon, 21 Apr 2025 15:48:53 +0800 Subject: [PATCH 30/51] cloud: remove outdated cloud roadmap (#20797) (#20798) --- TOC-tidb-cloud.md | 1 - _docHome.md | 6 ------ tidb-cloud/tidb-cloud-roadmap.md | 4 ++++ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/TOC-tidb-cloud.md b/TOC-tidb-cloud.md index 14d5c3813d210..c044132ab5db4 100644 --- a/TOC-tidb-cloud.md +++ b/TOC-tidb-cloud.md @@ -7,7 +7,6 @@ - [Architecture](/tidb-cloud/tidb-cloud-intro.md#architecture) - [High Availability](/tidb-cloud/high-availability-with-multi-az.md) - [MySQL Compatibility](/mysql-compatibility.md) - - [Roadmap](/tidb-cloud/tidb-cloud-roadmap.md) - Get Started - [Try Out TiDB Cloud](/tidb-cloud/tidb-cloud-quickstart.md) - [Try Out TiDB + AI](/vector-search/vector-search-get-started-using-python.md) diff --git a/_docHome.md b/_docHome.md index daf011ffaa3b0..8a686884bb021 100644 --- a/_docHome.md +++ b/_docHome.md @@ -38,12 +38,6 @@ Explore native support of Vector Search in TiDB Cloud Serverless to build your A - - -Planned features and releases for TiDB Cloud. - - - diff --git a/tidb-cloud/tidb-cloud-roadmap.md b/tidb-cloud/tidb-cloud-roadmap.md index 95cc3bc30f4b3..202280b0c1204 100644 --- a/tidb-cloud/tidb-cloud-roadmap.md +++ b/tidb-cloud/tidb-cloud-roadmap.md @@ -5,6 +5,10 @@ summary: Learn about TiDB Cloud's roadmap for the next few months. See the new f # TiDB Cloud Roadmap +> **Warning:** +> +> This roadmap might contain outdated information. We are working on updating it to reflect the latest product plans and development priorities. + The TiDB Cloud roadmap brings you what's coming in the near future, so you can see the new features or improvements in advance, follow the progress, and learn about the key milestones on the way. In the course of development, this roadmap is subject to change based on user needs, feedback, and our assessment. ✅: The feature or improvement is already available in TiDB Cloud. From 621de480ed580d2b1394e002f4eda5eaefdbf2f5 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Mon, 21 Apr 2025 19:15:08 +0800 Subject: [PATCH 31/51] add saas scenario best practices (#20668) --- TOC.md | 1 + best-practices/saas-best-practices.md | 97 +++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 best-practices/saas-best-practices.md diff --git a/TOC.md b/TOC.md index c862fcd2083dd..2efa39d5bf5b6 100644 --- a/TOC.md +++ b/TOC.md @@ -432,6 +432,7 @@ - [Local Read Under Three Data Centers Deployment](/best-practices/three-dc-local-read.md) - [Use UUIDs](/best-practices/uuid.md) - [Read-Only Storage Nodes](/best-practices/readonly-nodes.md) + - [SaaS Multi-Tenant Scenarios](/best-practices/saas-best-practices.md) - [Use Placement Rules](/configure-placement-rules.md) - [Use Load Base Split](/configure-load-base-split.md) - [Use Store Limit](/configure-store-limit.md) diff --git a/best-practices/saas-best-practices.md b/best-practices/saas-best-practices.md new file mode 100644 index 0000000000000..ddda7a97d6adb --- /dev/null +++ b/best-practices/saas-best-practices.md @@ -0,0 +1,97 @@ +--- +title: Best Practices for SaaS Multi-Tenant Scenarios +summary: Learn best practices for TiDB in SaaS (Software as a Service) multi-tenant scenarios, especially for environments where the number of tables in a single cluster exceeds one million. +--- + +# Best Practices for SaaS Multi-Tenant Scenarios + +This document introduces best practices for TiDB in SaaS (Software as a Service) multi-tenant environments, especially in scenarios where the **number of tables in a single cluster exceeds one million**. By making reasonable configurations and choices, you can enable TiDB to run efficiently and stably in SaaS scenarios while reducing resource consumption and costs. + +> **Note:** +> +> It is recommended to use TiDB v8.5.0 or later versions. + +## TiDB hardware recommendations + +It is recommended to use high-memory TiDB instances. For example: + +- For one million tables, use 32 GiB or more memory. +- For three million tables, use 64 GiB or more memory. + +High-memory TiDB instances allocate more cache space for Infoschema, Statistics, and execution plan caches, thereby improving cache hit rates and consequently enhancing business performance. Larger memory also mitigates performance fluctuations and stability issues caused by TiDB GC. + +Recommended hardware configurations for TiKV and PD are as follows: + +* TiKV: 8 vCPUs and 32 GiB or more memory. +* PD: 8 CPUs and 16 GiB or more memory. + +## Control the number of Regions + +If you need to create a large number of tables (for example, more than 100,000), it is recommended to set the TiDB configuration item [`split-table`](/tidb-configuration-file.md#split-table) to `false` to reduce the number of Regions, thus alleviating memory pressure on TiKV. + +## Configure caches + +* Starting from TiDB v8.4.0, TiDB loads table information involved in SQL statements into the Infoschema cache on demand during SQL execution. + + - You can monitor the size and hit rate of the Infoschema cache by observing the **Infoschema v2 Cache Size** and **Infoschema v2 Cache Operation** sub-panels under the **Schema Load** panel in TiDB Dashboard. + - You can use the [`tidb_schema_cache_size`](/system-variables.md#tidb_schema_cache_size-new-in-v800) system variable to adjust the memory limit of the Infoschema cache to meet business needs. The size of the Infoschema cache is linearly related to the number of different tables involved in SQL execution. In actual tests, fully caching metadata for one million tables (each with four columns, one primary key, and one index) requires about 2.4 GiB of memory. + +* TiDB loads table statistics involved in SQL statements into the Statistics cache on demand during SQL execution. + + - You can monitor the size and hit rate of the Statistics cache by observing the **Stats Cache Cost** and **Stats Cache OPS** sub-panels under the **Statistics & Plan Management** panel in TiDB Dashboard. + - You can use the [`tidb_stats_cache_mem_quota`](/system-variables.md#tidb_stats_cache_mem_quota-new-in-v610) system variable to adjust the memory limit of the Statistics cache to meet business needs. In actual tests, executing simple SQL (using the `IndexRangeScan` operator) on 100,000 tables consumes about 3.96 GiB of memory in the Statistics cache. + +## Collect statistics + +* Starting from TiDB v8.4.0, TiDB introduces the [`tidb_auto_analyze_concurrency`](/system-variables.md#tidb_auto_analyze_concurrency-new-in-v840) system variable to control the number of concurrent auto-analyze operations that can run in a TiDB cluster. In multi-table scenarios, you can increase this concurrency as needed to improve the throughput of automatic analysis. As the concurrency value increases, the throughput and the CPU usage of the TiDB Owner node increase linearly. In actual tests, using a concurrency value of 16 allows automatic analysis of 320 tables (each with 10,000 rows, 4 columns, and 1 index) within one minute, consuming one CPU core of the TiDB Owner node. +* The [`tidb_auto_build_stats_concurrency`](/system-variables.md#tidb_auto_build_stats_concurrency-new-in-v650) and [`tidb_build_sampling_stats_concurrency`](/system-variables.md#tidb_build_sampling_stats_concurrency-new-in-v750) system variables control the concurrency of TiDB statistics construction. You can adjust them based on your scenario: + - For scenarios with many partitioned tables, prioritize increasing the value of `tidb_auto_build_stats_concurrency`. + - For scenarios with many columns, prioritize increasing the value of `tidb_build_sampling_stats_concurrency`. +* To avoid excessive resource usage, ensure that the product of `tidb_auto_analyze_concurrency`, `tidb_auto_build_stats_concurrency`, and `tidb_build_sampling_stats_concurrency` does not exceed the number of TiDB CPU cores. + +## Query system tables efficiently + +When querying system tables, it is recommended to add filters such as `TABLE_SCHEMA`, `TABLE_NAME`, or `TIDB_TABLE_ID` to avoid scanning a large amount of irrelevant data. This improves query speed and reduces resource consumption. + +For example, in a scenario with three million tables: + +- Executing the following SQL statement consumes about 8 GiB of memory. + + ```sql + SELECT COUNT(*) FROM information_schema.tables; + ``` + +- Executing the following SQL statement takes about 20 minutes. + + ```sql + SELECT COUNT(*) FROM information_schema.views; + ``` + +By adding appropriate filter conditions to the preceding SQL statements, memory consumption becomes negligible, and query time is reduced to milliseconds. + +## Handle connection-intensive scenarios + +In SaaS multi-tenant scenarios, each user usually connects to TiDB to operate data in their own tenant (database). To support a high number of connections: + +* Increase the TiDB configuration item [`token-limit`](/tidb-configuration-file.md#token-limit) (`1000` by default) to support more concurrent requests. +* The memory usage of TiDB is roughly linear with the number of connections. In actual tests, 200,000 idle connections increase TiDB memory usage by about 30 GiB. It is recommended to increase TiDB memory specifications based on actual connection numbers. +* If you use `PREPARED` statements, each connection maintains a session-level Prepared Plan Cache. If the `DEALLOCATE` statement is not executed for a long time, the cache might accumulate too many plans, increasing memory usage. In actual tests, 400,000 execution plans involving `IndexRangeScan` consume approximately 5 GiB of memory. It is recommended to increase memory specifications accordingly. + +## Use stale read carefully + +When you use [Stale Read](/stale-read.md), an outdated schema version might trigger a full load of historical schemas, which can significantly impact performance. To mitigate this issue, increase the value of [`tidb_schema_version_cache_limit`](/system-variables.md#tidb_schema_version_cache_limit-new-in-v740) (for example, to `255`). + +## Optimize BR backup and restore + +* When restoring a full backup with millions of tables, it is recommended to use high-memory BR instances. For example: + - For one million tables, use BR instances with 32 GiB or more memory. + - For three million tables, use BR instances with 64 GiB or more memory. +* BR log backup and snapshot restore consume additional TiKV memory. It is recommended to use TiKV instances with 32 GiB or more memory. +* Adjust BR configurations [`pitr-batch-count` and `pitr-concurrency`](/br/use-br-command-line-tool.md#common-options) as needed to improve log restore speed. + +## Import data with TiDB Lightning + +When importing millions of tables using [TiDB Lightning](/tidb-lightning/tidb-lightning-overview.md), follow these recommendations: + +- For large tables (over 100 GiB), use TiDB Lightning [physical import mode](/tidb-lightning/tidb-lightning-physical-import-mode.md). +- For small tables (typically numerous in quantity), use TiDB Lightning [logical import mode](/tidb-lightning/tidb-lightning-logical-import-mode.md). From 5685cadb11fcaa31ad68c1cc4a1aeb14dad3b24d Mon Sep 17 00:00:00 2001 From: djshow832 Date: Mon, 21 Apr 2025 19:38:46 +0800 Subject: [PATCH 32/51] tiproxy: add a guide to enable tiproxy using tiup (#20799) --- tiproxy/tiproxy-overview.md | 97 +++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/tiproxy/tiproxy-overview.md b/tiproxy/tiproxy-overview.md index 830b08187d24c..0edde8cf21974 100644 --- a/tiproxy/tiproxy-overview.md +++ b/tiproxy/tiproxy-overview.md @@ -61,44 +61,42 @@ It is recommended that you use TiProxy for the scenarios that TiProxy is suitabl ## Installation and usage -This section describes how to deploy and change TiProxy using TiUP. +This section describes how to deploy and change TiProxy using TiUP. You can either [create a new cluster with TiProxy](#create-a-cluster-with-tiproxy) or [enable TiProxy for an existing cluster](#enable-tiproxy-for-an-existing-cluster) by scaling out TiProxy. + +> **Note:** +> +> Make sure that TiUP is v1.16.1 or later. For other deployment methods, refer to the following documents: - To deploy TiProxy using TiDB Operator, see the [TiDB Operator](https://docs.pingcap.com/zh/tidb-in-kubernetes/stable/deploy-tiproxy) documentation. - To quickly deploy TiProxy locally using TiUP, see [Deploy TiProxy](/tiup/tiup-playground.md#deploy-tiproxy). -### Deploy TiProxy - -1. Before TiUP v1.15.0, you need to manually generate a self-signed certificate. - - Generate a self-signed certificate for the TiDB instance and place the certificate on all TiDB instances to ensure that all TiDB instances have the same certificate. For detailed steps, see [Generate self-signed certificates](/generate-self-signed-certificates.md). +### Create a cluster with TiProxy -2. Configure the TiDB instances. +The following steps describe how to deploy TiProxy when creating a new cluster. - When using TiProxy, you also need to configure the following items for the TiDB instances: +1. Configure the TiDB instances. - - Before TiUP v1.15.0, configure the [`security.session-token-signing-cert`](/tidb-configuration-file.md#session-token-signing-cert-new-in-v640) and [`security.session-token-signing-key`](/tidb-configuration-file.md#session-token-signing-key-new-in-v640) of TiDB instances to the path of the certificate. Otherwise, the connection cannot be migrated. - - Configure the [`graceful-wait-before-shutdown`](/tidb-configuration-file.md#graceful-wait-before-shutdown-new-in-v50) of TiDB instances to a value greater than the longest transaction duration of the application. Otherwise, the client might disconnect when the TiDB server is offline. You can view the transaction duration through the [Transaction metrics on the TiDB monitoring dashboard](/grafana-tidb-dashboard.md#transaction). For details, see [TiProxy usage limitations](#limitations). + When using TiProxy, you need to configure [`graceful-wait-before-shutdown`](/tidb-configuration-file.md#graceful-wait-before-shutdown-new-in-v50) for TiDB. This value must be greater than the duration of the longest transaction of the application, which can avoid client connection interruption when the TiDB server goes offline. You can view the transaction duration through the [Transaction metrics on the TiDB monitoring dashboard](/grafana-tidb-dashboard.md#transaction). For details, see [Limitations](#limitations). A configuration example is as follows: ```yaml server_configs: tidb: - security.session-token-signing-cert: "/var/sess/cert.pem" - security.session-token-signing-key: "/var/sess/key.pem" graceful-wait-before-shutdown: 15 ``` -3. Define the TiProxy instances. +2. Configure the TiProxy instances. - When selecting the model and number of TiProxy instances, consider the following factors: + To ensure the high availability of TiProxy, it is recommended to deploy at least two TiProxy instances and configure a virtual IP by setting [`ha.virtual-ip`](/tiproxy/tiproxy-configuration.md#virtual-ip) and [`ha.interface`](/tiproxy/tiproxy-configuration.md#interface) to route the traffic to the available TiProxy instance. - - For the workload type and maximum QPS, see [TiProxy Performance Test Report](/tiproxy/tiproxy-performance-test.md). - - Because the number of TiProxy instances is less than that of TiDB servers, the network bandwidth of TiProxy is more likely to become a bottleneck than that of TiDB servers. Therefore, you also need to consider the network bandwidth. For example, in AWS, the baseline network bandwidth of the same series of EC2 is not proportional to the number of CPU cores. For details, see [Network performance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/compute-optimized-instances.html#compute-network-performance). In such cases, when the network bandwidth becomes a bottleneck, splitting the TiProxy instance into more and smaller instances can improve QPS. + Note the following: - It is recommended to specify the version number of TiProxy in the topology configuration so that TiProxy will not be upgraded when you upgrade the TiDB cluster through [`tiup cluster upgrade`](/tiup/tiup-component-cluster-upgrade.md). Otherwise, the client connection might be disconnected during TiProxy upgrade. + - Select the model and number of TiProxy instances based on the workload type and maximum QPS. For details, see [TiProxy Performance Test Report](/tiproxy/tiproxy-performance-test.md). + - Because there are usually fewer TiProxy instances than TiDB server instances, the network bandwidth of TiProxy is more likely to become a bottleneck. For example, on AWS, the baseline network bandwidth EC2 instances in the same series is not proportional to the number of CPU cores. When network bandwidth becomes a bottleneck, you can split the TiProxy instance into more and smaller instances to increase QPS. For details, see [Network specifications](https://docs.aws.amazon.com/ec2/latest/instancetypes/co.html#co_network). + - It is recommended to specify the TiProxy version in the topology configuration file. This will prevent TiProxy from being upgraded automatically when you execute [`tiup cluster upgrade`](/tiup/tiup-component-cluster-upgrade.md) to upgrade the TiDB cluster, thus preventing client connections from being disconnected due to the TiProxy upgrade. For more information about the template for TiProxy, see [A simple template for the TiProxy topology](https://github.com/pingcap/docs/blob/master/config-templates/simple-tiproxy.yaml). @@ -109,6 +107,10 @@ For other deployment methods, refer to the following documents: ```yaml component_versions: tiproxy: "v1.2.0" + server_configs: + tiproxy: + ha.virtual-ip: "10.0.1.10/24" + ha.interface: "eth0" tiproxy_servers: - host: 10.0.1.11 port: 6000 @@ -118,28 +120,73 @@ For other deployment methods, refer to the following documents: status_port: 3080 ``` -4. Configure the TiProxy instances. +3. Start the cluster. - To ensure the high availability of TiProxy, it is recommended to deploy at least two TiProxy instances and configure a virtual IP by setting [`ha.virtual-ip`](/tiproxy/tiproxy-configuration.md#virtual-ip) and [`ha.interface`](/tiproxy/tiproxy-configuration.md#interface) to route the traffic to the available TiProxy instance. + To start the cluster using TiUP, see [TiUP documentation](/tiup/tiup-documentation-guide.md). - To configure TiProxy configuration items, see [TiProxy Configuration File](/tiproxy/tiproxy-configuration.md). For more configurations of TiUP deployment topology, see [tiproxy-servers configurations](/tiup/tiup-cluster-topology-reference.md#tiproxy_servers). +4. Connect to TiProxy. - A configuration example is as follows: + After the cluster is deployed, the TiDB server port and TiProxy port will be exposed at the same time. The client should connect to the TiProxy port instead of directly connecting to the TiDB server. + +### Enable TiProxy for an existing cluster + +For clusters that do not have TiProxy deployed, you can enable TiProxy by scaling out TiProxy instances. + +1. Configure the TiProxy instance. + + Configure TiProxy in a separate topology file, such as `tiproxy.toml`: ```yaml + component_versions: + tiproxy: "v1.2.0" server_configs: tiproxy: ha.virtual-ip: "10.0.1.10/24" ha.interface: "eth0" + tiproxy_servers: + - host: 10.0.1.11 + deploy_dir: "/tiproxy-deploy" + port: 6000 + status_port: 3080 + - host: 10.0.1.12 + deploy_dir: "/tiproxy-deploy" + port: 6000 + status_port: 3080 ``` -5. Start the cluster. +2. Scale out TiProxy. - To start the cluster using TiUP, see [TiUP documentation](/tiup/tiup-documentation-guide.md). + Use the [`tiup cluster scale-out`](/tiup/tiup-component-cluster-scale-out.md) command to scale out the TiProxy instances. For example: + + ```shell + tiup cluster scale-out tiproxy.toml + ``` + + When you scale out TiProxy, TiUP automatically configures a self-signed certificate [`security.session-token-signing-cert`](/tidb-configuration-file.md#session-token-signing-cert-new-in-v640) and [`security.session-token-signing-key`](/tidb-configuration-file.md#session-token-signing-key-new-in-v640) for TiDB. The certificate is used for connection migration. + +3. Modify the TiDB configuration. + + When using TiProxy, you need to configure [`graceful-wait-before-shutdown`](/tidb-configuration-file.md#graceful-wait-before-shutdown-new-in-v50) for TiDB. This value must be greater than the duration of the longest transaction of the application to avoid client connection interruption when the TiDB server goes offline. You can view the transaction duration through the [Transaction metrics on the TiDB monitoring dashboard](/grafana-tidb-dashboard.md#transaction). For details, see [Limitations](#limitations). + + A configuration example is as follows: + + ```yaml + server_configs: + tidb: + graceful-wait-before-shutdown: 15 + ``` + +4. Reload TiDB configuration. + + Because TiDB is configured with a self-signed certificate and `graceful-wait-before-shutdown`, you need to use the [`tiup cluster reload`](/tiup/tiup-component-cluster-reload.md) command to reload the configuration for them to take effect. Note that after reloading the configuration, TiDB will perform a rolling restart, and the client connection will be disconnected. + + ```shell + tiup cluster reload -R tidb + ``` -6. Connect to TiProxy. +5. Connect to TiProxy. - After the cluster is deployed, the cluster exposes the ports of TiDB server and TiProxy at the same time. The client should connect to the port of TiProxy instead of the port of TiDB server. + After you enable TiProxy, the client should connect to the TiProxy port instead of the TiDB server port. ### Modify TiProxy configuration From fe33d9804fc84fcfa2232fd83a72708223611b82 Mon Sep 17 00:00:00 2001 From: Aolin Date: Tue, 22 Apr 2025 13:30:53 +0800 Subject: [PATCH 33/51] update the default collation of GBK from gbk_bin to gbk_chinese_ci (#20818) --- character-set-and-collation.md | 2 +- character-set-gbk.md | 44 +++++-------------- .../sql-statement-show-character-set.md | 21 ++++----- 3 files changed, 22 insertions(+), 45 deletions(-) diff --git a/character-set-and-collation.md b/character-set-and-collation.md index f3dc38a98a932..1adfc1bf63283 100644 --- a/character-set-and-collation.md +++ b/character-set-and-collation.md @@ -104,7 +104,7 @@ SHOW CHARACTER SET; +---------+-------------------------------------+-------------------+--------+ | ascii | US ASCII | ascii_bin | 1 | | binary | binary | binary | 1 | -| gbk | Chinese Internal Code Specification | gbk_bin | 2 | +| gbk | Chinese Internal Code Specification | gbk_chinese_ci | 2 | | latin1 | Latin1 | latin1_bin | 1 | | utf8 | UTF-8 Unicode | utf8_bin | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_bin | 4 | diff --git a/character-set-gbk.md b/character-set-gbk.md index 3abd11246f251..a767af5fcdbba 100644 --- a/character-set-gbk.md +++ b/character-set-gbk.md @@ -5,7 +5,9 @@ summary: This document provides details about the TiDB support of the GBK charac # GBK -Since v5.4.0, TiDB supports the GBK character set. This document provides the TiDB support and compatibility information of the GBK character set. +Starting from v5.4.0, TiDB supports the GBK character set. This document provides the TiDB support and compatibility information of the GBK character set. + +Starting from v6.0.0, TiDB enables the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations) by default. The default collation for TiDB GBK character set is `gbk_chinese_ci`, which is consistent with MySQL. ```sql SHOW CHARACTER SET WHERE CHARSET = 'gbk'; @@ -15,7 +17,7 @@ SHOW CHARACTER SET WHERE CHARSET = 'gbk'; +---------+-------------------------------------+-------------------+--------+ | Charset | Description | Default collation | Maxlen | +---------+-------------------------------------+-------------------+--------+ -| gbk | Chinese Internal Code Specification | gbk_bin | 2 | +| gbk | Chinese Internal Code Specification | gbk_chinese_ci | 2 | +---------+-------------------------------------+-------------------+--------+ 1 row in set (0.00 sec) ``` @@ -40,48 +42,22 @@ This section provides the compatibility information between MySQL and TiDB. ### Collations -The default collation of the GBK character set in MySQL is `gbk_chinese_ci`. Unlike MySQL, the default collation of the GBK character set in TiDB is `gbk_bin`. Additionally, because TiDB converts GBK to `utf8mb4` and then uses a binary collation, the `gbk_bin` collation in TiDB is not the same as the `gbk_bin` collation in MySQL. - -To make TiDB compatible with the collations of MySQL GBK character set, when you first initialize the TiDB cluster, you need to set the TiDB option [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) to `true` to enable the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations). This is the default setting for new deployments. +The default collation of the GBK character set in MySQL is `gbk_chinese_ci`. The default collation for the GBK character set in TiDB depends on the value of the TiDB configuration item [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap): + +- By default, the TiDB configuration item [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) is set to `true`, which means that the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations) is enabled and the default collation for the GBK character set is `gbk_chinese_ci`. +- When the TiDB configuration item [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) is set to `false`, the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations) is disabled, and the default collation for the GBK character set is `gbk_bin`. -To make TiDB compatible with the collations of MySQL GBK character set, when you first initialize the TiDB cluster, TiDB Cloud enables the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations) by default. +By default, TiDB Cloud enables the [new framework for collations](/character-set-and-collation.md#new-framework-for-collations) and the default collation for the GBK character set is `gbk_chinese_ci`. -After enabling the new framework for collations, if you check the collations corresponding to the GBK character set, you can see that the TiDB GBK default collation is changed to `gbk_chinese_ci`. - -```sql -SHOW CHARACTER SET WHERE CHARSET = 'gbk'; -``` - -``` -+---------+-------------------------------------+-------------------+--------+ -| Charset | Description | Default collation | Maxlen | -+---------+-------------------------------------+-------------------+--------+ -| gbk | Chinese Internal Code Specification | gbk_chinese_ci | 2 | -+---------+-------------------------------------+-------------------+--------+ -1 row in set (0.00 sec) -``` - -```sql -SHOW COLLATION WHERE CHARSET = 'gbk'; -``` - -``` -+----------------+---------+----+---------+----------+---------+---------------+ -| Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | -+----------------+---------+----+---------+----------+---------+---------------+ -| gbk_bin | gbk | 87 | | Yes | 1 | PAD SPACE | -| gbk_chinese_ci | gbk | 28 | Yes | Yes | 1 | PAD SPACE | -+----------------+---------+----+---------+----------+---------+---------------+ -2 rows in set (0.00 sec) -``` +Additionally, because TiDB converts GBK to `utf8mb4` and then uses a binary collation, the `gbk_bin` collation in TiDB is not the same as the `gbk_bin` collation in MySQL. ### Illegal character compatibility diff --git a/sql-statements/sql-statement-show-character-set.md b/sql-statements/sql-statement-show-character-set.md index f6b192afaca3c..7e4016969078b 100644 --- a/sql-statements/sql-statement-show-character-set.md +++ b/sql-statements/sql-statement-show-character-set.md @@ -26,16 +26,17 @@ SHOW CHARACTER SET; ``` ``` -+---------+---------------+-------------------+--------+ -| Charset | Description | Default collation | Maxlen | -+---------+---------------+-------------------+--------+ -| utf8 | UTF-8 Unicode | utf8_bin | 3 | -| utf8mb4 | UTF-8 Unicode | utf8mb4_bin | 4 | -| ascii | US ASCII | ascii_bin | 1 | -| latin1 | Latin1 | latin1_bin | 1 | -| binary | binary | binary | 1 | -+---------+---------------+-------------------+--------+ -5 rows in set (0.00 sec) ++---------+-------------------------------------+-------------------+--------+ +| Charset | Description | Default collation | Maxlen | ++---------+-------------------------------------+-------------------+--------+ +| ascii | US ASCII | ascii_bin | 1 | +| binary | binary | binary | 1 | +| gbk | Chinese Internal Code Specification | gbk_chinese_ci | 2 | +| latin1 | Latin1 | latin1_bin | 1 | +| utf8 | UTF-8 Unicode | utf8_bin | 3 | +| utf8mb4 | UTF-8 Unicode | utf8mb4_bin | 4 | ++---------+-------------------------------------+-------------------+--------+ +6 rows in set (0.00 sec) ``` ```sql From d85c4644004ae63988edc40c26d50aff0406521f Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Wed, 23 Apr 2025 09:00:20 +0800 Subject: [PATCH 34/51] release notes: fix version in links (#20835) --- releases/release-8.5.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-8.5.1.md b/releases/release-8.5.1.md index 9706ef981f655..0f1f2df32cfa5 100644 --- a/releases/release-8.5.1.md +++ b/releases/release-8.5.1.md @@ -9,7 +9,7 @@ Release date: January 17, 2025 TiDB version: 8.5.1 -Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.1/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v8.1/production-deployment-using-tiup) +Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v8.5/production-deployment-using-tiup) ## Operating system and platform requirement changes From 6f015e592490febbc087802b2aff1987ae9a74ed Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 23 Apr 2025 14:02:11 +0800 Subject: [PATCH 35/51] Apply suggestions from code review Co-authored-by: Aolin --- releases/release-9.0.0.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 615892c09b67e..93b9bfa7b2cef 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -66,11 +66,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- * Support pushing down window functions that contain the following aggregation functions to TiFlash [#7376](https://github.com/pingcap/tiflash/issues/7376) @[xzhangxian1008](https://github.com/xzhangxian1008) **tw@qiancai** - * `MAX` - * `MIN` - * `COUNT` - * `SUM` - * `AVG` + * `MAX()` + * `MIN()` + * `COUNT()` + * `SUM()` + * `AVG()` For more information, see [documentation](/tiflash/tiflash-supported-pushdown-calculations.md). @@ -89,7 +89,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- - For newly deployed TiDB clusters with v9.0.0 or a later version, TiFlash uses the new storage format by default. - For TiDB clusters upgraded to v9.0.0 or a later version, it is recommended to read [TiFlash upgrade guide](/tiflash-upgrade-guide.md) before the upgrade. - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is not specified for TiFlash before the upgrade, TiFlash uses the new storage format by default after the upgrade. - - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is specified for TiFlash before the upgrade, the value of `format_version` remains unchanged after the upgrade, and TiFlash continues to use the storage format specified by `format_version`. To enable the new storage format in this case, set the `format_version` parameter to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. + - If [`format_version`](/tiflash/tiflash-configuration.md#format_version) is specified for TiFlash before the upgrade, the value of `format_version` remains unchanged after the upgrade, and TiFlash continues to use the storage format specified by `format_version`. To enable the new storage format in this case, set the `format_version` configuration item to `8` in the TiFlash configuration file. After the configuration takes effect, new data written to TiFlash will use the new storage format, while the storage format of existing data will remain unchanged. For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). From 1a43e2c43912f53aac48fc90a0c26eef12eedcb5 Mon Sep 17 00:00:00 2001 From: zeminzhou Date: Wed, 23 Apr 2025 16:51:53 +0800 Subject: [PATCH 36/51] serverless support import into (#20832) --- sql-statements/sql-statement-cancel-import-job.md | 4 ---- sql-statements/sql-statement-import-into.md | 10 +++++----- sql-statements/sql-statement-show-import-job.md | 4 ---- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/sql-statements/sql-statement-cancel-import-job.md b/sql-statements/sql-statement-cancel-import-job.md index 97a5e4a436ad2..d4b911d846384 100644 --- a/sql-statements/sql-statement-cancel-import-job.md +++ b/sql-statements/sql-statement-cancel-import-job.md @@ -7,10 +7,6 @@ summary: An overview of the usage of CANCEL IMPORT in TiDB. The `CANCEL IMPORT` statement is used to cancel a data import job created in TiDB. -> **Note:** -> -> This feature is not available on [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless) clusters. - ## Required privileges To cancel a data import job, you need to be the creator of the import job or have the `SUPER` privilege. diff --git a/sql-statements/sql-statement-import-into.md b/sql-statements/sql-statement-import-into.md index d85270ca1e684..1bb57618741ae 100644 --- a/sql-statements/sql-statement-import-into.md +++ b/sql-statements/sql-statement-import-into.md @@ -159,11 +159,7 @@ The supported options are described as follows: ## `IMPORT INTO ... FROM FILE` usage -> **Note:** -> -> `IMPORT INTO ... FROM FILE` is not available on [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless) clusters. - -For TiDB Self-Managed, `IMPORT INTO ... FROM FILE` supports importing data from files stored in Amazon S3, GCS, and the TiDB local storage. For [TiDB Cloud Dedicated](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-dedicated), `IMPORT INTO ... FROM FILE` supports importing data from files stored in Amazon S3 and GCS. +For TiDB Self-Managed, `IMPORT INTO ... FROM FILE` supports importing data from files stored in Amazon S3, GCS, and the TiDB local storage. For [TiDB Cloud Dedicated](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-dedicated), `IMPORT INTO ... FROM FILE` supports importing data from files stored in Amazon S3 and GCS. For [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless), `IMPORT INTO ... FROM FILE` supports importing data from files stored in Amazon S3 and Alibaba Cloud OSS. - For data files stored in Amazon S3 or GCS, `IMPORT INTO ... FROM FILE` supports running in the [TiDB Distributed eXecution Framework (DXF)](/tidb-distributed-execution-framework.md). @@ -189,6 +185,10 @@ For TiDB Self-Managed, `IMPORT INTO ... FROM FILE` supports importing data from ### Global Sort +> **Note:** +> +> Global Sort is not available on [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless) clusters. + `IMPORT INTO ... FROM FILE` splits the data import job of a source data file into multiple sub-jobs, each sub-job independently encoding and sorting data before importing. If the encoded KV ranges of these sub-jobs have significant overlap (to learn how TiDB encodes data to KV, see [TiDB computing](/tidb-computing.md)), TiKV needs to keep compaction during import, leading to a decrease in import performance and stability. In the following scenarios, there can be significant overlap in KV ranges: diff --git a/sql-statements/sql-statement-show-import-job.md b/sql-statements/sql-statement-show-import-job.md index 9100ea128cf34..396f60558a137 100644 --- a/sql-statements/sql-statement-show-import-job.md +++ b/sql-statements/sql-statement-show-import-job.md @@ -7,10 +7,6 @@ summary: An overview of the usage of SHOW IMPORT in TiDB. The `SHOW IMPORT` statement is used to show the IMPORT jobs created in TiDB. This statement can only show jobs created by the current user. -> **Note:** -> -> This feature is not available on [TiDB Cloud Serverless](https://docs.pingcap.com/tidbcloud/select-cluster-tier#tidb-cloud-serverless) clusters. - ## Required privileges - `SHOW IMPORT JOBS`: if a user has the `SUPER` privilege, this statement shows all import jobs in TiDB. Otherwise, this statement only shows jobs created by the current user. From ea026d3ac23f710f15c3f35c0bcda7b88d3b1387 Mon Sep 17 00:00:00 2001 From: Ben Meadowcroft Date: Fri, 25 Apr 2025 18:07:22 -0700 Subject: [PATCH 37/51] Add TiCDC related release notes Signed-off-by: Ben Meadowcroft --- releases/release-9.0.0.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 93b9bfa7b2cef..aefee1cc1c1f2 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -24,6 +24,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- + + Data Migration + TiCDC perforance, scalability, and stability improvements with new architecture (Preview) + TiCDC introduces a new architecture design that improves replication performance, scalability, and stability while reducing resource costs. This new architecture redesigns TiCDC core components and optimizes its data processing workflows. + Data Migration Support query argument redaction in DM logs @@ -180,6 +185,26 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Data migration +* TiCDC perforance, scalability, and stability improvements with new architecture (Preview) [#442](https://github.com/pingcap/ticdc/issues/442) @[CharlesCheung96](https://github.com/CharlesCheung96) **tw@Oreoxmt** + + TiCDC introduces a new architecture (in preview) that improves real-time data replication performance, scalability, and stability while reducing resource costs. This new architecture redesigns TiCDC core components and optimizes its data processing workflows. + + TiCDC can now scale the TiCDC cluster linearly and replicate millions of tables with improved resource utilization. Changefeed latency is reduced and performance is more stable in scenarios with high traffic, frequent DDL operations, and during cluster scaling events. + + For more information, see [documentation](/ticdc/ticdc-architecture.md). + +* TiCDC Adds DDL and Watermark Event Support to Debezium Protocol [#11566](https://github.com/pingcap/tiflow/issues/11566) @[wk989898](https://github.com/wk989898) **tw@Oreoxmt** + + TiCDC's support for Debezium Style events adds support for DDL and Watermark event types. After an upstream DDL is successfully executed, TiCDC now encodes the DDL event into a Kafka message with the key and message in a Debezium-style format. The Watermark event is a TiCDC extension (generated when [`enable-tidb-extension`](/ticdc/ticdc-sink-to-kafka.md#configure-sink-uri-for-kafka) is set on the Kafka sink) that represents a special time point indicating that the events received before this Watermark are complete. + + For more information, see [documentation](/ticdc/ticdc-debezium.md). + +* TiCDC Adds Guards Against Replicating to Itself [#12062](https://github.com/pingcap/tiflow/issues/12062) @[wlwilliamx](https://github.com/wlwilliamx) **tw@Oreoxmt** + + TiCDC supports replicating from a source TiDB system to multiple other downstream systems, including other TiDB instances. Prior to v9.0.0, If TiCDC was misconfigured to replicate from one TiDB to the same TiDB system as both source and target, the TiDB instance may experience unexpected data consistency issues due to the cyclical replication loop. With v9.0.0, TiCDC now checks that a downstream TiDB cluster is different from the source TiDB cluster, to guard against this misconfiguration causing issues. + + For more information, see [documentation](/ticdc/ticdc-manage-changefeed.md#security-mechanism). + * Support query argument redaction in Data Migration (DM) logs [#11489](https://github.com/pingcap/tiflow/issues/11489) @[db-will](https://github.com/db-will) **tw@Oreoxmt** Starting from v9.0.0, you can use the `redact-info-log` configuration item to enable the DM log redaction feature. When enabled, query arguments that contain sensitive data in DM logs are replaced with the `?` placeholder. To enable this feature, set `redact-info-log` to `true` in the DM-worker configuration file or pass `--redact-info-log=true` when starting DM. This feature only redacts query arguments, not the entire SQL statement, and requires a DM-worker restart to take effect. From 2a2219033f873878772d6837534c230320a8231f Mon Sep 17 00:00:00 2001 From: Ben Meadowcroft Date: Fri, 25 Apr 2025 19:13:37 -0700 Subject: [PATCH 38/51] Add BR/PITR related release notes Signed-off-by: Ben Meadowcroft --- releases/release-9.0.0.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index aefee1cc1c1f2..79a43d57faa44 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -24,6 +24,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- + + Scalability and Performance + Point-In-Time-Recovery (PITR) Now Supports Recovery from Compacted Log Backups for Faster Restores + Starting from v9.0.0, the log backup feature provides offline compaction capabilities, converting unstructured log backup data into structured SST files. These SST files can now recovered into the cluster much more quickly than reapplying the original logs, delivering improved recovery performance. + Data Migration TiCDC perforance, scalability, and stability improvements with new architecture (Preview) @@ -98,6 +103,16 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). +* Point-In-Time-Recovery (PITR) Now Supports Recovery from Compacted Log Backups for Faster Restores [#56522](https://github.com/pingcap/tidb/issues/56522) @[YuJuncen](https://github.com/YuJuncen) **tw@Oreoxmt** + + Starting from v9.0.0, the compact log backup feature provides offline compaction capabilities, converting unstructured log backup data into structured SST files. This results in the following improvements: + + - SST files can be quickly imported into the cluster, **improving recovery performance**. + - Redundant data is removed during compaction, **reducing storage space consumption**. + - You can set longer full backup intervals while ensuring the Recovery Time Objective (RTO), **reducing the impact on applications**. + + For more information, see [documentation](/br/br-compact-log-backup.md). + ### Availability * TiProxy officially supports the traffic replay feature (GA) [#642](https://github.com/pingcap/tiproxy/issues/642) @[djshow832](https://github.com/djshow832) tw@hfxsd @@ -132,6 +147,12 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- For more information, see [documentation](/index-advisor.md). +* Improved Log Backup Compatibility during Snapshot Restores [#58685](https://github.com/pingcap/tidb/issues/58685) @[BornChanger](https://github.com/BornChanger) **tw@Oreoxmt** + + Starting in v9.0.0, Log Backups can now continue to backup data during a snapshot restore in many conditions. This enables ongoing log backups to procede without having to stop them during the restore procedure. + + For more information, see [documentation](/br/br-pitr-manual.md#compatibility-between-ongoing-log-backup-and-snapshot-restore). + ### Observability * Add the TiDB Workload Repository feature to support persisting historical workload data into TiKV [#58247](https://github.com/pingcap/tidb/issues/58247) @[xhebox](https://github.com/xhebox) @[henrybw](https://github.com/henrybw) @[wddevries](https://github.com/wddevries) **tw@lilin90** From f863c166d89c373e6b5da5ea1f61a979e7b182f5 Mon Sep 17 00:00:00 2001 From: Ben Meadowcroft Date: Fri, 25 Apr 2025 19:34:14 -0700 Subject: [PATCH 39/51] Updated to add PD release notes, and fix typo Signed-off-by: Ben Meadowcroft --- releases/release-9.0.0.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 79a43d57faa44..2adeea8723517 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -24,6 +24,11 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- + + Scalability and Performance + Disaggregation of PD to improve scalability (General Availability) + The Placement Driver (PD) provides multiple critical modules to ensure the normal operation of TiDB clusters. Now Generally Available in v9.0.0, PD's Microservices mode supports deploying the TSO and scheduling modules as independent microservices. This can significantly reduce resource conflicts for these services as the cluster scales. With this architecture, much larger clusters with much larger workloads are now possible. + Scalability and Performance Point-In-Time-Recovery (PITR) Now Supports Recovery from Compacted Log Backups for Faster Restores @@ -31,7 +36,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- Data Migration - TiCDC perforance, scalability, and stability improvements with new architecture (Preview) + TiCDC performance, scalability, and stability improvements with new architecture (Preview) TiCDC introduces a new architecture design that improves replication performance, scalability, and stability while reducing resource costs. This new architecture redesigns TiCDC core components and optimizes its data processing workflows. @@ -56,7 +61,16 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with- ### Scalability +* PD supports the microservice mode (GA) [#5766](https://github.com/tikv/pd/issues/5766) @[binshi-bing](https://github.com/binshi-bing) + + Starting from v9.0.0, the PD microservice mode is now Generally Available. This mode splits the timestamp allocation and cluster scheduling functions of PD into separate microservices that can be deployed independently, thereby enhancing performance scalability for PD and addressing performance bottlenecks of PD in large-scale clusters. + + - `tso` microservice: provides monotonically increasing timestamp allocation for the entire cluster. + - `scheduling` microservice: provides scheduling functions for the entire cluster, including but not limited to load balancing, hot spot handling, replica repair, and replica placement. + + Each microservice is deployed as an independent process. If you configure more than one replica for a microservice, the microservice automatically implements a primary-secondary fault-tolerant mode to ensure high availability and reliability of the service. + For more information, see [documentation](/pd-microservices.md). ### Performance From 8852fa871e00fb939ee85c7b3c2ad363b3ccafec Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Sun, 27 Apr 2025 14:30:13 +0800 Subject: [PATCH 40/51] pd configuration: add dashboard.disable-custom-prom-addr (#20853) --- pd-configuration-file.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pd-configuration-file.md b/pd-configuration-file.md index 43babfbc503c5..ee0e792502906 100644 --- a/pd-configuration-file.md +++ b/pd-configuration-file.md @@ -467,6 +467,12 @@ Configuration items related to labels, which only support the `reject-leader` ty Configuration items related to the [TiDB Dashboard](/dashboard/dashboard-intro.md) built in PD. +### `disable-custom-prom-addr` + ++ Whether to disable configuring a custom Prometheus data source address in [TiDB Dashboard](/dashboard/dashboard-intro.md). ++ Default value: `false` ++ When it is set to `true`, if you configure a custom Prometheus data source address in TiDB Dashboard, TiDB Dashboard reports an error. + ### `tidb-cacert-path` + The path of the root CA certificate file. You can configure this path when you connect to TiDB's SQL services using TLS. From b44cf62709a4a11e6f7a28efc7a5d64b9125f48c Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Sun, 27 Apr 2025 15:43:31 +0800 Subject: [PATCH 41/51] toc: add TiDB release support policy (#19119) (#20860) --- TOC.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TOC.md b/TOC.md index 2efa39d5bf5b6..48d73a7920e25 100644 --- a/TOC.md +++ b/TOC.md @@ -1092,6 +1092,7 @@ - [All Releases](/releases/release-notes.md) - [Release Timeline](/releases/release-timeline.md) - [TiDB Versioning](/releases/versioning.md) + - [Release Support Policy](https://www.pingcap.com/tidb-release-support-policy/) - [TiDB Installation Packages](/binary-package.md) - v8.5 - [8.5.1](/releases/release-8.5.1.md) From af3e688226b477f2a9d44b076a4bcb7b9639b3ab Mon Sep 17 00:00:00 2001 From: BornChanger <97348524+BornChanger@users.noreply.github.com> Date: Sun, 27 Apr 2025 15:50:16 +0800 Subject: [PATCH 42/51] releases: add one br entry to v8.1.2 (#20861) --- releases/release-8.1.2.md | 1 + 1 file changed, 1 insertion(+) diff --git a/releases/release-8.1.2.md b/releases/release-8.1.2.md index 2b33a69370240..db5c947269cdc 100644 --- a/releases/release-8.1.2.md +++ b/releases/release-8.1.2.md @@ -39,6 +39,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.1/quick-start-with- + Backup & Restore (BR) - Reduce unnecessary log printing during backup [#55902](https://github.com/pingcap/tidb/issues/55902) @[Leavrth](https://github.com/Leavrth) + - Disable the table-level checksum calculation (`--checksum=false`) during full backups by default to improve backup performance [#56373](https://github.com/pingcap/tidb/issues/56373) @[Tristan1900](https://github.com/Tristan1900) + TiCDC From b89e89c204730501c6faa943b33ecbca1913e3ce Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Mon, 28 Apr 2025 14:03:46 +0800 Subject: [PATCH 43/51] add FAQs about collation for JDBC connections (#20848) --- .../dev-guide-sample-application-java-jdbc.md | 16 ++++- faq/sql-faq.md | 67 +++++++++++++++++++ faq/upgrade-faq.md | 6 ++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/develop/dev-guide-sample-application-java-jdbc.md b/develop/dev-guide-sample-application-java-jdbc.md index 7fd96eced87f3..8266e17bcc9ff 100644 --- a/develop/dev-guide-sample-application-java-jdbc.md +++ b/develop/dev-guide-sample-application-java-jdbc.md @@ -14,9 +14,23 @@ In this tutorial, you can learn how to use TiDB and JDBC to accomplish the follo - Connect to your TiDB cluster using JDBC. - Build and run your application. Optionally, you can find [sample code snippets](#sample-code-snippets) for basic CRUD operations. + + > **Note:** > -> This tutorial works with TiDB Cloud Serverless, TiDB Cloud Dedicated, and TiDB Self-Managed. +> - This tutorial works with TiDB Cloud Serverless, TiDB Cloud Dedicated, and TiDB Self-Managed. +> - Starting from TiDB v7.4, if `connectionCollation` is not configured, and `characterEncoding` is either not configured or set to `UTF-8` in the JDBC URL, the collation used in a JDBC connection depends on the JDBC driver version. For more information, see [Collation used in JDBC connections](/faq/sql-faq.md#collation-used-in-jdbc-connections). + + + + + +> **Note:** +> +> - This tutorial works with TiDB Cloud Serverless, TiDB Cloud Dedicated, and TiDB Self-Managed. +> - Starting from TiDB v7.4, if `connectionCollation` is not configured, and `characterEncoding` is either not configured or set to `UTF-8` in the JDBC URL, the collation used in a JDBC connection depends on the JDBC driver version. For more information, see [Collation used in JDBC connections](https://docs.pingcap.com/tidb/stable/sql-faq#collation-used-in-jdbc-connections). + + ## Prerequisites diff --git a/faq/sql-faq.md b/faq/sql-faq.md index 1d1351dfd67ab..334209b7dfd83 100644 --- a/faq/sql-faq.md +++ b/faq/sql-faq.md @@ -337,6 +337,73 @@ Whether your cluster is a new cluster or an upgraded cluster from an earlier ver - If the owner does not exist, try manually triggering owner election with: `curl -X POST http://{TiDBIP}:10080/ddl/owner/resign`. - If the owner exists, export the Goroutine stack and check for the possible stuck location. +## Collation used in JDBC connections + +This section lists questions related to collations used in JDBC connections. For information about character sets and collations supported by TiDB, see [Character Set and Collation](/character-set-and-collation.md). + +### What collation is used in a JDBC connection when `connectionCollation` is not configured in the JDBC URL? + +When `connectionCollation` is not configured in the JDBC URL, there are two scenarios: + +**Scenario 1**: Neither `connectionCollation` nor `characterEncoding` is configured in the JDBC URL + +- For Connector/J 8.0.25 and earlier versions, the JDBC driver attempts to use the server's default character set. Because the default character set of TiDB is `utf8mb4`, the driver uses `utf8mb4_bin` as the connection collation. +- For Connector/J 8.0.26 and later versions, the JDBC driver uses the `utf8mb4` character set and automatically selects the collation based on the return value of `SELECT VERSION()`. + + - When the return value is less than `8.0.1`, the driver uses `utf8mb4_general_ci` as the connection collation. TiDB follows the driver and uses `utf8mb4_general_ci` as the collation. + - When the return value is greater than or equal to `8.0.1`, the driver uses `utf8mb4_0900_ai_ci` as the connection collation. TiDB v7.4.0 and later versions follow the driver and use `utf8mb4_0900_ai_ci` as the collation, while TiDB versions earlier than v7.4.0 fall back to using the default collation `utf8mb4_bin` because the `utf8mb4_0900_ai_ci` collation is not supported in these versions. + +**Scenario 2**: `characterEncoding=utf8` is configured in the JDBC URL but `connectionCollation` is not configured. The JDBC driver uses the `utf8mb4` character set according to the mapping rules. The collation is determined according to the rules described in scenario 1. + +### How to handle collation changes after upgrading TiDB? + +In TiDB v7.4 and earlier versions, if `connectionCollation` is not configured, and `characterEncoding` is either not configured or set to `UTF-8` in the JDBC URL, the TiDB [`collation_connection`](/system-variables.md#collation_connection) variable defaults to the `utf8mb4_bin` collation. + +Starting from TiDB v7.4, if `connectionCollation` is not configured, and `characterEncoding` is either not configured or set to `UTF-8` in the JDBC URL, the value of the [`collation_connection`](/system-variables.md#collation_connection) variable depends on the JDBC driver version. For example, for Connector/J 8.0.26 and later versions, the JDBC driver defaults to the `utf8mb4` character set and uses `utf8mb4_general_ci` as the connection collation. TiDB follows the driver, and the [`collation_connection`](/system-variables.md#collation_connection) variable uses the `utf8mb4_0900_ai_ci` collation. For more information, see [Collation used in JDBC connections](#what-collation-is-used-in-a-jdbc-connection-when-connectioncollation-is-not-configured-in-the-jdbc-url). + +When upgrading from an earlier version to v7.4 or later (for example, from v6.5 to v7.5), if you need to maintain the `collation_connection` as `utf8mb4_bin` for JDBC connections, it is recommended to configure the `connectionCollation` parameter in the JDBC URL. + +The following is a common JDBC URL configuration in TiDB v6.5: + +``` +spring.datasource.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultfetchsize=-2147483648&allowMultiQueries=true +``` + +After upgrading to TiDB v7.5 or a later version, it is recommended to configure the `connectionCollation` parameter in the JDBC URL: + +``` +spring.datasource.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding=UTF-8&connectionCollation=utf8mb4_bin&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultFetchSize=-2147483648&allowMultiQueries=true +``` + +### What are the differences between the `utf8mb4_bin` and `utf8mb4_0900_ai_ci` collations? + +| Collation | Case-sensitive | Ignore trailing spaces | Accent-sensitive | Comparison method | +|----------------------|----------------|------------------|--------------|------------------------| +| `utf8mb4_bin` | Yes | Yes | Yes | Compare binary values | +| `utf8mb4_0900_ai_ci` | No | No | No | Use Unicode sorting algorithm | + +For example: + +```sql +-- utf8mb4_bin is case-sensitive +SELECT 'apple' = 'Apple' COLLATE utf8mb4_bin; -- Returns 0 (FALSE) + +-- utf8mb4_0900_ai_ci is case-insensitive +SELECT 'apple' = 'Apple' COLLATE utf8mb4_0900_ai_ci; -- Returns 1 (TRUE) + +-- utf8mb4_bin ignores trailing spaces +SELECT 'Apple ' = 'Apple' COLLATE utf8mb4_bin; -- Returns 1 (TRUE) + +-- utf8mb4_0900_ai_ci does not ignore trailing spaces +SELECT 'Apple ' = 'Apple' COLLATE utf8mb4_0900_ai_ci; -- Returns 0 (FALSE) + +-- utf8mb4_bin is accent-sensitive +SELECT 'café' = 'cafe' COLLATE utf8mb4_bin; -- Returns 0 (FALSE) + +-- utf8mb4_0900_ai_ci is accent-insensitive +SELECT 'café' = 'cafe' COLLATE utf8mb4_0900_ai_ci; -- Returns 1 (TRUE) +``` + ## SQL optimization ### TiDB execution plan description diff --git a/faq/upgrade-faq.md b/faq/upgrade-faq.md index d60feef4df6c0..d7fc3eeb3a560 100644 --- a/faq/upgrade-faq.md +++ b/faq/upgrade-faq.md @@ -36,6 +36,12 @@ It is not recommended to upgrade TiDB using the binary. Instead, it is recommend This section lists some FAQs and their solutions after you upgrade TiDB. +### The collation in JDBC connections changes after upgrading TiDB + +When upgrading from an earlier version to v7.4 or later, if the `connectionCollation` is not configured, and the `characterEncoding` is either not configured or configured as `UTF-8` in the JDBC URL, the default collation in your JDBC connections might change from `utf8mb4_bin` to `utf8mb4_0900_ai_ci` after upgrading. If you need to maintain the collation as `utf8mb4_bin`, configure `connectionCollation=utf8mb4_bin` in the JDBC URL. + +For more information, see [Collation used in JDBC connections](/faq/sql-faq.md#collation-used-in-jdbc-connections). + ### The character set (charset) errors when executing DDL operations In v2.1.0 and earlier versions (including all versions of v2.0), the character set of TiDB is UTF-8 by default. But starting from v2.1.1, the default character set has been changed into UTF8MB4. From 36dfd3bc598d992aa1cfe6f1781172eb847b85ea Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Tue, 29 Apr 2025 15:19:38 +0800 Subject: [PATCH 44/51] hardware-and-software-requirements: update Kylin Euler to Kylin (#20874) --- hardware-and-software-requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware-and-software-requirements.md b/hardware-and-software-requirements.md index 0219a230bfcbe..24ffe24fed7a6 100644 --- a/hardware-and-software-requirements.md +++ b/hardware-and-software-requirements.md @@ -43,7 +43,7 @@ This document describes the software and hardware requirements for deploying and
  • x86_64
  • ARM 64
- Kylin Euler V10 SP1/SP2/SP3 (SP3 is supported starting from v7.5.5) + Kylin V10 SP1/SP2/SP3 (SP3 is supported starting from v7.5.5)
  • x86_64
  • ARM 64
From 8c30d7f3094702c2bfca9e4d53f5ef4dad208968 Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 30 Apr 2025 10:03:59 +0800 Subject: [PATCH 45/51] JDBC URL: update the letter case for defaultFetchSize (#20884) --- faq/sql-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faq/sql-faq.md b/faq/sql-faq.md index 334209b7dfd83..e14da18f6fb14 100644 --- a/faq/sql-faq.md +++ b/faq/sql-faq.md @@ -366,7 +366,7 @@ When upgrading from an earlier version to v7.4 or later (for example, from v6.5 The following is a common JDBC URL configuration in TiDB v6.5: ``` -spring.datasource.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultfetchsize=-2147483648&allowMultiQueries=true +spring.datasource.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultFetchSize=-2147483648&allowMultiQueries=true ``` After upgrading to TiDB v7.5 or a later version, it is recommended to configure the `connectionCollation` parameter in the JDBC URL: From 6b8e13b2ae7f53435df588d6ca75eaaa1ab2019f Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 30 Apr 2025 16:22:04 +0800 Subject: [PATCH 46/51] planner: add doc for `tidb_ignore_inlist_plan_digest`. (#20870) --- releases/release-7.6.0.md | 1 + system-variables.md | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/releases/release-7.6.0.md b/releases/release-7.6.0.md index c48dad6da61a4..d9b83311ede0b 100644 --- a/releases/release-7.6.0.md +++ b/releases/release-7.6.0.md @@ -272,6 +272,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v7.6/quick-start-with- | [`tidb_ddl_version`](https://docs.pingcap.com/tidb/v7.6/system-variables#tidb_ddl_version-new-in-v760) | Newly added | Controls whether to enable [TiDB DDL V2](https://docs.pingcap.com/tidb/v7.6/ddl-v2). Set the value to `2` to enable it and `1` to disable it. The default value is `1`. When TiDB DDL V2 is enabled, DDL statements will be executed using TiDB DDL V2. The execution speed of DDL statements for creating tables is increased by 10 times compared with TiDB DDL V1. | | [`tidb_enable_global_index`](/system-variables.md#tidb_enable_global_index-new-in-v760) | Newly added | Controls whether to support creating `Global indexes` for partitioned tables. The default value is `OFF`. `Global index` is currently in the development stage. **It is not recommended to modify the value of this system variable**. | | [`tidb_idle_transaction_timeout`](/system-variables.md#tidb_idle_transaction_timeout-new-in-v760) | Newly added | Controls the idle timeout for transactions in a user session. When a user session is in a transactional state and remains idle for a duration exceeding the value of this variable, TiDB will terminate the session. The default value `0` means unlimited. | +| [`tidb_ignore_inlist_plan_digest`](/system-variables.md#tidb_ignore_inlist_plan_digest-new-in-v760) | New | Controls whether TiDB ignores the element differences in the `IN` list across different queries when generating Plan Digests. The default value `OFF` means differences are not ignored. | | [`tidb_opt_enable_fuzzy_binding`](/system-variables.md#tidb_opt_enable_fuzzy_binding-new-in-v760) | Newly added | Controls whether to enable the cross-database binding feature. The default value `OFF` means cross-database binding is disabled. | | [`tidb_txn_entry_size_limit`](/system-variables.md#tidb_txn_entry_size_limit-new-in-v760) | Newly added | Dynamically modifies the TiDB configuration item [`performance.txn-entry-size-limit`](/tidb-configuration-file.md#txn-entry-size-limit-new-in-v4010-and-v500). It limits the size of a single row of data in TiDB. The default value of this variable is `0`, which means that TiDB uses the value of the configuration item `txn-entry-size-limit` by default. When this variable is set to a non-zero value, `txn-entry-size-limit` is also set to the same value. | | [`pd_enable_follower_handle_region`](/system-variables.md#pd_enable_follower_handle_region-new-in-v760) | Newly added | Controls whether to enable the [Active PD Follower](/tune-region-performance.md#use-the-active-pd-follower-feature-to-enhance-the-scalability-of-pds-region-information-query-service) feature (experimental). When the value is `OFF`, TiDB only obtains Region information from the PD leader. When the value is `ON`, TiDB evenly distributes requests for Region information to all PD servers, and PD followers can also handle Region requests, thereby reducing the CPU pressure on the PD leader. | diff --git a/system-variables.md b/system-variables.md index c31bde4afb2b9..58c7bf3e3b014 100644 --- a/system-variables.md +++ b/system-variables.md @@ -3393,6 +3393,18 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - This variable is used to set whether to ignore the commands for closing prepared statement cache. - When this variable is set to `ON`, the `COM_STMT_CLOSE` command of the Binary protocol and the [`DEALLOCATE PREPARE`](/sql-statements/sql-statement-deallocate.md) statement of the text protocol are ignored. For details, see [Ignore the `COM_STMT_CLOSE` command and the `DEALLOCATE PREPARE` statement](/sql-prepared-plan-cache.md#ignore-the-com_stmt_close-command-and-the-deallocate-prepare-statement). +### tidb_ignore_inlist_plan_digest New in v7.6.0 + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Type: Boolean +- Default value: `OFF` +- This variable controls whether TiDB ignores the element differences in the `IN` list across different queries when generating Plan Digests. + + - When it is the default value `OFF`, TiDB does not ignore the element differences (including the difference in the number of elements) in the `IN` list when generating Plan Digests. The element differences in the `IN` list result in different Plan Digests. + - When it is set to `ON`, TiDB ignores the element differences (including the difference in the number of elements) in the `IN` list and uses `...` to replace elements in the `IN` list in Plan Digests. In this case, TiDB generates the same Plan Digests for `IN` queries of the same type. + ### tidb_index_join_batch_size - Scope: SESSION | GLOBAL From 3d67e5654745364fc8a41dd756a614e76e717d3c Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 30 Apr 2025 16:31:00 +0800 Subject: [PATCH 47/51] fix(pd): add missing configuration items for PD (#20883) --- pd-configuration-file.md | 28 +++++++++++++++++++++++++++- releases/release-8.0.0.md | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pd-configuration-file.md b/pd-configuration-file.md index ee0e792502906..0783e78d10ac4 100644 --- a/pd-configuration-file.md +++ b/pd-configuration-file.md @@ -97,6 +97,22 @@ This document only describes parameters that are not included in command-line pa + The time interval for automatic compaction of the meta-information database when `auto-compaction-retention` is `periodic`. When the compaction mode is set to `revision`, this parameter indicates the version number for the automatic compaction. + Default value: 1h +### `tick-interval` + ++ Equivalent to the `heartbeat-interval` configuration item of etcd. It controls the Raft heartbeat interval between embedded etcd instances in different PD nodes. A smaller value accelerates failure detection but increases network load. ++ Default value: `500ms` + +### `election-interval` + ++ Equivalent to the `election-timeout` configuration item of etcd. It controls the election timeout for embedded etcd instances in PD nodes. If an etcd instance does not receive a valid heartbeat from other etcd instances within this period, it initiates a Raft election. ++ Default value: `3000ms` ++ This value must be at least five times the [`tick-interval`](#tick-interval). For example, if `tick-interval` is `500ms`, `election-interval` must be greater than or equal to `2500ms`. + +### `enable-prevote` + ++ Equivalent to the `pre-vote` configuration item of etcd. It controls whether the embedded etcd in the PD node enables Raft pre-vote. When enabled, etcd performs an additional election phase to check whether enough votes can be obtained to win the election, minimizing service disruption. ++ Default value: `true` + ### `force-new-cluster` + Determines whether to force PD to start as a new cluster and modify the number of Raft members to `1` @@ -413,6 +429,16 @@ Configuration items related to scheduling + Specifies how many days the hot Region information is retained. + Default value: `7` +### `enable-heartbeat-breakdown-metrics` New in v8.0.0 + ++ Controls whether to enable breakdown metrics for Region heartbeats. These metrics measure the time consumed in each stage of Region heartbeat processing, facilitating analysis through monitoring. ++ Default value: `true` + +### `enable-heartbeat-concurrent-runner` New in v8.0.0 + ++ Controls whether to enable asynchronous concurrent processing for Region heartbeats. When enabled, an independent executor handles Region heartbeat requests asynchronously and concurrently, which can improve heartbeat processing throughput and reduce latency. ++ Default value: `true` + ## `replication` Configuration items related to replicas @@ -547,4 +573,4 @@ The following are the configuration items about the [Request Unit (RU)](/tidb-re + Basis factor for conversion from CPU to RU + Default value: 1/3 -+ 1 RU = 3 millisecond CPU time ++ 1 RU = 3 millisecond CPU time \ No newline at end of file diff --git a/releases/release-8.0.0.md b/releases/release-8.0.0.md index c84ad876b644a..477b09d4f1d4b 100644 --- a/releases/release-8.0.0.md +++ b/releases/release-8.0.0.md @@ -339,6 +339,8 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.0/quick-start-with- | TiKV | [`security.encryption.master-key.vendor`](/encryption-at-rest.md#specify-a-master-key-via-kms) | Modified | Adds `gcp` as an available type for the service provider. | | TiKV | [`rocksdb.defaultcf.titan.shared-blob-cache`](/tikv-configuration-file.md#shared-blob-cache-new-in-v800) | Newly added | Controls whether to enable the shared cache for Titan blob files and RocksDB block files. The default value is `true`. | | TiKV | [`security.encryption.master-key.gcp.credential-file-path`](/encryption-at-rest.md#specify-a-master-key-via-kms) | Newly added | Specifies the path to the Google Cloud authentication credentials file when `security.encryption.master-key.vendor` is `gcp`. | +| PD | [`schedule.enable-heartbeat-breakdown-metrics`](/pd-configuration-file.md#enable-heartbeat-breakdown-metrics-new-in-v800) | Newly added | Controls whether to enable breakdown metrics for Region heartbeats. These metrics measure the time consumed in each stage of Region heartbeat processing, facilitating analysis through monitoring. The default value is `true`. | +| PD | [`schedule.enable-heartbeat-concurrent-runner`](/pd-configuration-file.md#enable-heartbeat-concurrent-runner-new-in-v800) | Newly added | Controls whether to enable asynchronous concurrent processing for Region heartbeats. When enabled, an independent executor handles Region heartbeat requests asynchronously and concurrently, which can improve heartbeat processing throughput and reduce latency. The default value is `true`. | | TiDB Lightning | [`tikv-importer.duplicate-resolution`](/tidb-lightning/tidb-lightning-physical-import-mode-usage.md#the-old-version-of-conflict-detection-deprecated-in-v800) | Deprecated | Controls whether to detect and resolve unique key conflicts in physical import mode. Starting from v8.0.0, it is replaced by [`conflict.strategy`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task). | | TiDB Lightning | [`conflict.precheck-conflict-before-import`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) | Newly added | Controls whether to enable pre-import conflict detection, which checks conflicts in data before importing it to TiDB. The default value of this parameter is `false`, which means that TiDB Lightning only checks conflicts after the data import. This parameter can be used only in the physical import mode (`tikv-importer.backend = "local"`). | | TiDB Lightning | [`logical-import-batch-rows`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) | Newly added | Controls the maximum number of rows inserted per transaction in the logical import mode. The default value is `65536` rows. | From a5b3f19d33433bc2a6c451d8b49a34d2f6c3ffd8 Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 30 Apr 2025 16:37:38 +0800 Subject: [PATCH 48/51] tikv: recorrect the settings of some configs and supplement missing annotations for several configs. (#20871) --- releases/release-7.6.0.md | 3 +++ releases/release-8.0.0.md | 3 ++- releases/release-8.1.0.md | 1 + releases/release-8.1.2.md | 9 +++++++- tikv-configuration-file.md | 47 +++++++++++++++++++++++++++++++------- 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/releases/release-7.6.0.md b/releases/release-7.6.0.md index d9b83311ede0b..152b8f0c6fcc6 100644 --- a/releases/release-7.6.0.md +++ b/releases/release-7.6.0.md @@ -282,12 +282,15 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v7.6/quick-start-with- | Configuration file | Configuration parameter | Change type | Description | | -------- | -------- | -------- | -------- | | TiDB | [`tls-version`](/tidb-configuration-file.md#tls-version) | Modified | The default value is "". The default supported TLS versions of TiDB are changed from `TLS1.1` or higher to `TLS1.2` or higher. | +| TiKV | [`raftstore.report-min-resolved-ts-interval`](https://docs.pingcap.com/tidb/v7.5/tikv-configuration-file/#report-min-resolved-ts-interval-new-in-v600) | Renamed | To make the name more accurate, this configuration item is renamed to [`raftstore.pd-report-min-resolved-ts-interval`](/tikv-configuration-file.md#pd-report-min-resolved-ts-interval-new-in-v760). `raftstore.report-min-resolved-ts-interval` is no longer effective. | | TiKV | [`blob-file-compression`](/tikv-configuration-file.md#blob-file-compression) | Modified | The algorithm used for compressing values in Titan, which takes value as the unit. Starting from TiDB v7.6.0, the default compression algorithm is `zstd`. | | TiKV | [`rocksdb.defaultcf.titan.min-blob-size`](/tikv-configuration-file.md#min-blob-size) | Modified | Starting from TiDB v7.6.0, the default value for new clusters is `32KB`. For existing clusters upgrading to v7.6.0, the default value `1KB` remains unchanged. | | TiKV | [`rocksdb.titan.enabled`](/tikv-configuration-file.md#enabled) | Modified | Enables or disables Titan. For v7.5.0 and earlier versions, the default value is `false`. Starting from v7.6.0, the default value is `true` for only new clusters. Existing clusters upgraded to v7.6.0 or later versions will retain the original configuration. | +| TiKV | [`cdc.incremental-scan-concurrency-limit`](/tikv-configuration-file.md#incremental-scan-concurrency-limit-new-in-v760) | Newly added | Sets the maximum queue length for the tasks of incrementally scanning historical data waiting to be executed. The default value is `10000`, which means that at most 10000 tasks can be queued for execution. | | TiKV | [`gc.num-threads`](/tikv-configuration-file.md#num-threads-new-in-v658-v714-v751-and-v760) | Newly added | When `enable-compaction-filter` is set to `false`, this parameter controls the number of GC threads. The default value is `1`. | | TiKV | [`raftstore.periodic-full-compact-start-times`](/tikv-configuration-file.md#periodic-full-compact-start-times-new-in-v760) | Newly added | Sets the specific times that TiKV initiates periodic full compaction. The default value `[]` means periodic full compaction is disabled. | | TiKV | [`raftstore.periodic-full-compact-start-max-cpu`](/tikv-configuration-file.md#periodic-full-compact-start-max-cpu-new-in-v760) | Newly added | Limits the maximum CPU usage rate for TiKV periodic full compaction. The default value is `0.1`. | +| TiKV | [`raftstore.pd-report-min-resolved-ts-interval`](/tikv-configuration-file.md#pd-report-min-resolved-ts-interval-new-in-v760) | Newly added | Renamed from [`raftstore.report-min-resolved-ts-interval`](https://docs.pingcap.com/tidb/v7.5/tikv-configuration-file#report-min-resolved-ts-interval-new-in-v600). It specifies the minimum interval for TiKV to report Resolved TS to the PD leader. The default value is `"1s"`. | | TiKV | [`zstd-dict-size`](/tikv-configuration-file.md#zstd-dict-size) | Newly added | Specifies the `zstd` dictionary compression size. The default value is `"0KB"`, which means to disable the `zstd` dictionary compression. | | TiFlash | [`logger.level`](/tiflash/tiflash-configuration.md#configure-the-tiflashtoml-file) | Modified | Changes the default value from `"debug"` to `"INFO"` to reduce the cost of logging. | | TiDB Lightning| [`tidb.pd-addr`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) | Modified | Configures the addresses of the PD Servers. Starting from v7.6.0, TiDB supports setting multiple PD addresses. | diff --git a/releases/release-8.0.0.md b/releases/release-8.0.0.md index 477b09d4f1d4b..c82bd5d0bef41 100644 --- a/releases/release-8.0.0.md +++ b/releases/release-8.0.0.md @@ -336,7 +336,9 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.0/quick-start-with- | TiKV | [`log-backup.initial-scan-rate-limit`](/tikv-configuration-file.md#initial-scan-rate-limit-new-in-v620) | Modified | Adds a limit of `1MiB` as the minimum value. | | TiKV | [`raftstore.store-io-pool-size`](/tikv-configuration-file.md#store-io-pool-size-new-in-v530) | Modified | Changes the default value from `0` to `1` to improve TiKV performance, meaning that the size of the StoreWriter thread pool now defaults to `1`. | | TiKV | [`rocksdb.defaultcf.titan.blob-cache-size`](/tikv-configuration-file.md#blob-cache-size) | Modified | Starting from v8.0.0, TiKV introduces the `shared-blob-cache` configuration item and enables it by default, so there is no need to set `blob-cache-size` separately. The configuration of `blob-cache-size` only takes effect when `shared-blob-cache` is set to `false`. | +| TiKV | [`rocksdb.titan.max-background-gc`](/tikv-configuration-file.md#max-background-gc) | Modified | Changes the default value from `4` to `1` to reduce the occupation of thread resources by the Titan GC process. | | TiKV | [`security.encryption.master-key.vendor`](/encryption-at-rest.md#specify-a-master-key-via-kms) | Modified | Adds `gcp` as an available type for the service provider. | +| TiKV | [`storage.block-cache.low-pri-pool-ratio`](/tikv-configuration-file.md#low-pri-pool-ratio-new-in-v800) | Newly added | Specifies the proportion of the entire block cache that the Titan component can use. The default value is `0.2`. | | TiKV | [`rocksdb.defaultcf.titan.shared-blob-cache`](/tikv-configuration-file.md#shared-blob-cache-new-in-v800) | Newly added | Controls whether to enable the shared cache for Titan blob files and RocksDB block files. The default value is `true`. | | TiKV | [`security.encryption.master-key.gcp.credential-file-path`](/encryption-at-rest.md#specify-a-master-key-via-kms) | Newly added | Specifies the path to the Google Cloud authentication credentials file when `security.encryption.master-key.vendor` is `gcp`. | | PD | [`schedule.enable-heartbeat-breakdown-metrics`](/pd-configuration-file.md#enable-heartbeat-breakdown-metrics-new-in-v800) | Newly added | Controls whether to enable breakdown metrics for Region heartbeats. These metrics measure the time consumed in each stage of Region heartbeat processing, facilitating analysis through monitoring. The default value is `true`. | @@ -347,7 +349,6 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.0/quick-start-with- | TiDB Lightning | [`logical-import-batch-size`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) | Newly added | Controls the maximum size of each SQL query executed on the downstream TiDB server in the logical import mode. The default value is `"96KiB"`. The unit can be KB, KiB, MB, or MiB. | | Data Migration | [`secret-key-path`](/dm/dm-master-configuration-file.md) | Newly added | Specifies the file path of the secret key, which is used to encrypt and decrypt upstream and downstream passwords. The file must contain a 64-character hexadecimal AES-256 secret key. | | TiCDC | [`debezium-disable-schema`](/ticdc/ticdc-changefeed-config.md) | Newly added | Controls whether to disable the output of schema information. This parameter only takes effect when the sink type is MQ and the output protocol is Debezium. | - | TiCDC | [`tls-certificate-file`](/ticdc/ticdc-sink-to-pulsar.md) | Newly added | Specifies the path to the encrypted certificate file on the client, which is required when Pulsar enables TLS encrypted transmission. | | TiCDC | [`tls-key-file-path`](/ticdc/ticdc-sink-to-pulsar.md) | Newly added | Specifies the path to the encrypted private key on the client, which is required when Pulsar enables TLS encrypted transmission. | diff --git a/releases/release-8.1.0.md b/releases/release-8.1.0.md index 6947bb6709839..69c4ee72b0a8b 100644 --- a/releases/release-8.1.0.md +++ b/releases/release-8.1.0.md @@ -187,6 +187,7 @@ Compared with the previous LTS 7.5.0, 8.1.0 includes new features, improvements, | PD | [`enable-telemetry`](/pd-configuration-file.md#enable-telemetry) | Deprecated | Starting from v8.1.0, the telemetry feature in TiDB Dashboard is removed, and this configuration item is no longer functional. It is retained solely for compatibility with earlier versions. | | TiDB Lightning | [`conflict.max-record-rows`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-configuration) | Modified | Starting from v8.1.0, there is no need to configure `conflict.max-record-rows` manually, because TiDB Lightning automatically assigns the value of `conflict.max-record-rows` with the value of `conflict.threshold`, regardless of the user input. `conflict.max-record-rows` will be deprecated in a future release. | | TiDB Lightning | [`conflict.threshold`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) | Modified | Changes the default value from `9223372036854775807` to `10000` to quickly interrupt abnormal tasks so that you can make corresponding adjustments as soon as possible. This saves time and computational resources by avoiding the scenario where a large amount of conflicting data is discovered after the import, caused by abnormal data sources or incorrect table schema definitions. | +| TiKV | [`memory.enable-thread-exclusive-arena`](/tikv-configuration-file.md#enable-thread-exclusive-arena-new-in-v810) | Newly added | Controls whether to display the memory allocation status at the TiKV thread level to track the memory usage of each TiKV thread. The default value is `true`. | | TiCDC | [`security.client-allowed-user`](/ticdc/ticdc-server-config.md#cdc-server-configuration-file-parameters) | Newly added | Lists the usernames that are allowed for client authentication. Authentication requests with usernames not in this list will be rejected. The default value is null. | | TiCDC | [`security.client-user-required`](/ticdc/ticdc-server-config.md#cdc-server-configuration-file-parameters) | Newly added | Controls whether to use username and password for client authentication. The default value is `false`. | | TiCDC | [`security.mtls`](/ticdc/ticdc-server-config.md#cdc-server-configuration-file-parameters) | Newly added | Controls whether to enable the TLS client authentication. The default value is `false`. | diff --git a/releases/release-8.1.2.md b/releases/release-8.1.2.md index db5c947269cdc..e7f993e297844 100644 --- a/releases/release-8.1.2.md +++ b/releases/release-8.1.2.md @@ -1,6 +1,6 @@ --- title: TiDB 8.1.2 Release Notes -summary: Learn about the improvements and bug fixes in TiDB 8.1.2. +summary: Learn about the compatibility changes, improvements, and bug fixes in TiDB 8.1.2. --- # TiDB 8.1.2 Release Notes @@ -11,6 +11,13 @@ TiDB version: 8.1.2 Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.1/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v8.1/production-deployment-using-tiup) +## Compatibility changes + +- Add the TiKV configuration item [`server.snap-min-ingest-size`](/tikv-configuration-file.md#snap-min-ingest-size-new-in-v812), which specifies the minimum threshold for whether TiKV adopts the ingest method when processing snapshots. The default value is `2MiB`. + + - When the snapshot size exceeds this threshold, TiKV adopts the ingest method, which imports SST files from the snapshot into RocksDB. This method is faster for large files. + - When the snapshot size does not exceed this threshold, TiKV adopts the direct write method, which writes each piece of data into RocksDB individually. This method is more efficient for small files. + ## Improvements + TiDB diff --git a/tikv-configuration-file.md b/tikv-configuration-file.md index 9c132d69eff77..feb459b579806 100644 --- a/tikv-configuration-file.md +++ b/tikv-configuration-file.md @@ -229,6 +229,17 @@ This document only describes the parameters that are not included in command-lin + Unit: KiB|MiB|GiB + Minimum value: `"1KiB"` +### `snap-min-ingest-size` New in v8.1.2 + ++ Specifies the minimum threshold for whether TiKV adopts the ingest method when processing snapshots. + + + When the snapshot size exceeds this threshold, TiKV adopts the ingest method, which imports SST files from the snapshot into RocksDB. This method is faster for large files. + + When the snapshot size does not exceed this threshold, TiKV adopts the direct write method, which writes each piece of data into RocksDB individually. This method is more efficient for small files. + ++ Default value: `"2MiB"` ++ Unit: KiB|MiB|GiB ++ Minimum value: `0` + ### `enable-request-batch` + Determines whether to process requests in batches @@ -526,6 +537,11 @@ Configuration items related to the sharing of block cache among multiple RocksDB + Unit: KiB|MiB|GiB +### `low-pri-pool-ratio` New in v8.0.0 + ++ Controls the proportion of the entire block cache that the Titan component can use. ++ Default value: `0.2` + ## storage.flow-control Configuration items related to the flow control mechanism in TiKV. This mechanism replaces the write stall mechanism in RocksDB and controls flow at the scheduler layer, which avoids secondary disasters caused by the stuck Raftstore or Apply threads. @@ -856,6 +872,17 @@ Configuration items related to Raftstore. + Default value: `"10s"` + Minimum value: `0` +### `pd-report-min-resolved-ts-interval` New in v7.6.0 + +> **Note:** +> +> This configuration item is renamed from [`report-min-resolved-ts-interval`](https://docs.pingcap.com/tidb/v7.5/tikv-configuration-file/#report-min-resolved-ts-interval-new-in-v600). Starting from v7.6.0, `report-min-resolved-ts-interval` is no longer effective. + ++ Specifies the minimum interval for TiKV to report Resolved TS to the PD leader. Setting it to `0` disables the reporting. ++ Default value: `"1s"`, which is the minimum positive value. Before v6.3.0, the default value is `"0s"`. ++ Minimum value: `0` ++ Unit: second + ### `snap-mgr-gc-tick-interval` + The time interval at which the recycle of expired snapshot files is triggered. `0` means that this feature is disabled. @@ -1056,13 +1083,6 @@ Configuration items related to Raftstore. + Default value: `1MiB` + Minimum value: `0` -### `report-min-resolved-ts-interval` New in v6.0.0 - -+ Determines the interval at which the minimum resolved timestamp is reported to the PD leader. If this value is set to `0`, it means that the reporting is disabled. -+ Default value: Before v6.3.0, the default value is `"0s"`. Starting from v6.3.0, the default value is `"1s"`, which is the smallest positive value. -+ Minimum value: `0` -+ Unit: second - ### `evict-cache-on-memory-ratio` New in v7.5.0 + When the memory usage of TiKV exceeds 90% of the system available memory, and the memory occupied by Raft entry cache exceeds the used memory * `evict-cache-on-memory-ratio`, TiKV evicts the Raft entry cache. @@ -1458,7 +1478,7 @@ Configuration items related to Titan. ### `max-background-gc` + The maximum number of GC threads in Titan. From the **TiKV Details** > **Thread CPU** > **RocksDB CPU** panel, if you observe that the Titan GC threads are at full capacity for a long time, consider increasing the size of the Titan GC thread pool. -+ Default value: `4` ++ Default value: `1`. Before v8.0.0, the default value is `4`. + Minimum value: `1` ## rocksdb.defaultcf | rocksdb.writecf | rocksdb.lockcf | rocksdb.raftcf @@ -2361,6 +2381,12 @@ Configuration items related to TiCDC. + Default value: `6`, which means 6 tasks can be concurrent executed at most. + Note: The value of `incremental-scan-concurrency` must be greater than or equal to that of `incremental-scan-threads`; otherwise, TiKV will report an error at startup. +### `incremental-scan-concurrency-limit` New in v7.6.0 + ++ The maximum queue length for the tasks of incrementally scanning historical data waiting to be executed. When the number of tasks waiting to be executed exceeds this limit, new tasks will be rejected. ++ Default value: `10000`, which means that at most 10000 tasks can be queued for execution. ++ Note: `incremental-scan-concurrency-limit` must be greater than or equal to [`incremental-scan-concurrency`](#incremental-scan-concurrency); otherwise, TiKV uses `incremental-scan-concurrency` to override this configuration. + ## resolved-ts Configuration items related to maintaining the Resolved TS to serve Stale Read requests. @@ -2591,6 +2617,11 @@ Configuration items related to [Load Base Split](/configure-load-base-split.md). + Specifies the amount of data sampled by Heap Profiling each time, rounding up to the nearest power of 2. + Default value: `512KiB` +### `enable-thread-exclusive-arena` New in v8.1.0 + ++ Controls whether to display the memory allocation status at the TiKV thread level to track the memory usage of each TiKV thread. ++ Default value: `true` + ## in-memory-engine New in v8.5.0 TiKV MVCC in-memory engine (IME) configuration items related to the storage layer. From 4f1847430d89c47f8eb13c8a7ec6de7d8ccf7e06 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 30 Apr 2025 18:37:25 +0800 Subject: [PATCH 49/51] planner: add doc for `tidb_ignore_inlist_plan_digest`. (#20870) (#20890) (#20900) --- releases/release-7.6.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-7.6.0.md b/releases/release-7.6.0.md index 152b8f0c6fcc6..d0d55e549768e 100644 --- a/releases/release-7.6.0.md +++ b/releases/release-7.6.0.md @@ -272,7 +272,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v7.6/quick-start-with- | [`tidb_ddl_version`](https://docs.pingcap.com/tidb/v7.6/system-variables#tidb_ddl_version-new-in-v760) | Newly added | Controls whether to enable [TiDB DDL V2](https://docs.pingcap.com/tidb/v7.6/ddl-v2). Set the value to `2` to enable it and `1` to disable it. The default value is `1`. When TiDB DDL V2 is enabled, DDL statements will be executed using TiDB DDL V2. The execution speed of DDL statements for creating tables is increased by 10 times compared with TiDB DDL V1. | | [`tidb_enable_global_index`](/system-variables.md#tidb_enable_global_index-new-in-v760) | Newly added | Controls whether to support creating `Global indexes` for partitioned tables. The default value is `OFF`. `Global index` is currently in the development stage. **It is not recommended to modify the value of this system variable**. | | [`tidb_idle_transaction_timeout`](/system-variables.md#tidb_idle_transaction_timeout-new-in-v760) | Newly added | Controls the idle timeout for transactions in a user session. When a user session is in a transactional state and remains idle for a duration exceeding the value of this variable, TiDB will terminate the session. The default value `0` means unlimited. | -| [`tidb_ignore_inlist_plan_digest`](/system-variables.md#tidb_ignore_inlist_plan_digest-new-in-v760) | New | Controls whether TiDB ignores the element differences in the `IN` list across different queries when generating Plan Digests. The default value `OFF` means differences are not ignored. | +| [`tidb_ignore_inlist_plan_digest`](/system-variables.md#tidb_ignore_inlist_plan_digest-new-in-v760) | Newly added | Controls whether TiDB ignores the element differences in the `IN` list across different queries when generating Plan Digests. The default value `OFF` means differences are not ignored. | | [`tidb_opt_enable_fuzzy_binding`](/system-variables.md#tidb_opt_enable_fuzzy_binding-new-in-v760) | Newly added | Controls whether to enable the cross-database binding feature. The default value `OFF` means cross-database binding is disabled. | | [`tidb_txn_entry_size_limit`](/system-variables.md#tidb_txn_entry_size_limit-new-in-v760) | Newly added | Dynamically modifies the TiDB configuration item [`performance.txn-entry-size-limit`](/tidb-configuration-file.md#txn-entry-size-limit-new-in-v4010-and-v500). It limits the size of a single row of data in TiDB. The default value of this variable is `0`, which means that TiDB uses the value of the configuration item `txn-entry-size-limit` by default. When this variable is set to a non-zero value, `txn-entry-size-limit` is also set to the same value. | | [`pd_enable_follower_handle_region`](/system-variables.md#pd_enable_follower_handle_region-new-in-v760) | Newly added | Controls whether to enable the [Active PD Follower](/tune-region-performance.md#use-the-active-pd-follower-feature-to-enhance-the-scalability-of-pds-region-information-query-service) feature (experimental). When the value is `OFF`, TiDB only obtains Region information from the PD leader. When the value is `ON`, TiDB evenly distributes requests for Region information to all PD servers, and PD followers can also handle Region requests, thereby reducing the CPU pressure on the PD leader. | From ea60a95b8c13e5d2d4053cda89bfe2bbc2bf938a Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Tue, 6 May 2025 15:28:28 +0800 Subject: [PATCH 50/51] Update releases/release-9.0.0.md --- releases/release-9.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 2adeea8723517..18ddb1727f1f4 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -11,7 +11,7 @@ Release date: xx xx, 2025 TiDB version: 9.0.0 -Quick access: [Quick start](https://docs.pingcap.com/tidb/v8.5/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v8.5/production-deployment-using-tiup) +Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with-tidb) | [Production deployment](https://docs.pingcap.com/tidb/v9.0/production-deployment-using-tiup) 9.0.0 introduces the following key features and improvements: From 80a20ff79a2636602050415eb5dd3a7ef1a02016 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Tue, 6 May 2025 15:43:03 +0800 Subject: [PATCH 51/51] assign Ben's notes to tw --- releases/release-9.0.0.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/releases/release-9.0.0.md b/releases/release-9.0.0.md index 18ddb1727f1f4..96378b96e5ca2 100644 --- a/releases/release-9.0.0.md +++ b/releases/release-9.0.0.md @@ -61,7 +61,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- ### Scalability -* PD supports the microservice mode (GA) [#5766](https://github.com/tikv/pd/issues/5766) @[binshi-bing](https://github.com/binshi-bing) +* PD supports the microservice mode (GA) [#5766](https://github.com/tikv/pd/issues/5766) @[binshi-bing](https://github.com/binshi-bing) tw@hfxsd Starting from v9.0.0, the PD microservice mode is now Generally Available. This mode splits the timestamp allocation and cluster scheduling functions of PD into separate microservices that can be deployed independently, thereby enhancing performance scalability for PD and addressing performance bottlenecks of PD in large-scale clusters. @@ -74,7 +74,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- ### Performance -* In scenarios with hundreds of thousands to millions of users, the performance of creating and modifying users has improved by 77 times [#55563](https://github.com/pingcap/tidb/issues/55563) @[tiancaiamao](https://github.com/tiancaiamao) tw@hfxsd +* In scenarios with hundreds of thousands to millions of users, the performance of creating and modifying users has improved by 77 times [#55563](https://github.com/pingcap/tidb/issues/55563) @[tiancaiamao](https://github.com/tiancaiamao) tw@hfxsd In previous versions, when the number of users in a cluster exceeded 200,000, the QPS for creating and modifying users drops to 1. In certain SaaS environments, if there is a need to create millions of users and periodically update user passwords in bulk, it can take up to 2 days or more, which is unacceptable for some SaaS businesses. @@ -117,7 +117,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- For more information, see [user documentation](/tiflash/tiflash-configuration.md#format_version). -* Point-In-Time-Recovery (PITR) Now Supports Recovery from Compacted Log Backups for Faster Restores [#56522](https://github.com/pingcap/tidb/issues/56522) @[YuJuncen](https://github.com/YuJuncen) **tw@Oreoxmt** +* Point-In-Time-Recovery (PITR) Now Supports Recovery from Compacted Log Backups for Faster Restores [#56522](https://github.com/pingcap/tidb/issues/56522) @[YuJuncen](https://github.com/YuJuncen) **tw@lilin90** Starting from v9.0.0, the compact log backup feature provides offline compaction capabilities, converting unstructured log backup data into structured SST files. This results in the following improvements: @@ -161,7 +161,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- For more information, see [documentation](/index-advisor.md). -* Improved Log Backup Compatibility during Snapshot Restores [#58685](https://github.com/pingcap/tidb/issues/58685) @[BornChanger](https://github.com/BornChanger) **tw@Oreoxmt** +* Improved Log Backup Compatibility during Snapshot Restores [#58685](https://github.com/pingcap/tidb/issues/58685) @[BornChanger](https://github.com/BornChanger) **tw@lilin90** Starting in v9.0.0, Log Backups can now continue to backup data during a snapshot restore in many conditions. This enables ongoing log backups to procede without having to stop them during the restore procedure. @@ -220,7 +220,7 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- ### Data migration -* TiCDC perforance, scalability, and stability improvements with new architecture (Preview) [#442](https://github.com/pingcap/ticdc/issues/442) @[CharlesCheung96](https://github.com/CharlesCheung96) **tw@Oreoxmt** +* TiCDC perforance, scalability, and stability improvements with new architecture (Preview) [#442](https://github.com/pingcap/ticdc/issues/442) @[CharlesCheung96](https://github.com/CharlesCheung96) **tw@qiancai** TiCDC introduces a new architecture (in preview) that improves real-time data replication performance, scalability, and stability while reducing resource costs. This new architecture redesigns TiCDC core components and optimizes its data processing workflows. @@ -228,13 +228,13 @@ Quick access: [Quick start](https://docs.pingcap.com/tidb/v9.0/quick-start-with- For more information, see [documentation](/ticdc/ticdc-architecture.md). -* TiCDC Adds DDL and Watermark Event Support to Debezium Protocol [#11566](https://github.com/pingcap/tiflow/issues/11566) @[wk989898](https://github.com/wk989898) **tw@Oreoxmt** +* TiCDC Adds DDL and Watermark Event Support to Debezium Protocol [#11566](https://github.com/pingcap/tiflow/issues/11566) @[wk989898](https://github.com/wk989898) **tw@lilin90** TiCDC's support for Debezium Style events adds support for DDL and Watermark event types. After an upstream DDL is successfully executed, TiCDC now encodes the DDL event into a Kafka message with the key and message in a Debezium-style format. The Watermark event is a TiCDC extension (generated when [`enable-tidb-extension`](/ticdc/ticdc-sink-to-kafka.md#configure-sink-uri-for-kafka) is set on the Kafka sink) that represents a special time point indicating that the events received before this Watermark are complete. For more information, see [documentation](/ticdc/ticdc-debezium.md). -* TiCDC Adds Guards Against Replicating to Itself [#12062](https://github.com/pingcap/tiflow/issues/12062) @[wlwilliamx](https://github.com/wlwilliamx) **tw@Oreoxmt** +* TiCDC Adds Guards Against Replicating to Itself [#12062](https://github.com/pingcap/tiflow/issues/12062) @[wlwilliamx](https://github.com/wlwilliamx) **tw@qiancai** TiCDC supports replicating from a source TiDB system to multiple other downstream systems, including other TiDB instances. Prior to v9.0.0, If TiCDC was misconfigured to replicate from one TiDB to the same TiDB system as both source and target, the TiDB instance may experience unexpected data consistency issues due to the cyclical replication loop. With v9.0.0, TiCDC now checks that a downstream TiDB cluster is different from the source TiDB cluster, to guard against this misconfiguration causing issues. @@ -331,7 +331,6 @@ Before upgrading TiDB, ensure that your operating system version meets the [OS a * The following feature has been removed: - * The following features are planned for removal in future versions: * Starting from v8.0.0, TiDB Lightning deprecates the [old version of conflict detection](/tidb-lightning/tidb-lightning-physical-import-mode-usage.md#the-old-version-of-conflict-detection-deprecated-in-v800) strategy for the physical import mode, and enables you to control the conflict detection strategy for both logical and physical import modes via the [`conflict.strategy`](/tidb-lightning/tidb-lightning-configuration.md#tidb-lightning-task) parameter. The [`duplicate-resolution`](/tidb-lightning/tidb-lightning-configuration.md) parameter for the old version of conflict detection will be removed in a future release.