From 53c42e2ae9e6b9efd62dc40eed5c4a559cd32f09 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Wed, 9 Sep 2026 19:20:31 +0800 Subject: [PATCH 1/8] docs: document TTL index scan --- system-variable-reference.md | 7 +++++++ system-variables.md | 13 +++++++++++++ time-to-live.md | 26 +++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/system-variable-reference.md b/system-variable-reference.md index 3590ce3e5c8fd..9c33bb17889d9 100644 --- a/system-variable-reference.md +++ b/system-variable-reference.md @@ -4136,6 +4136,13 @@ Referenced in: - [TiDB 7.1.6 Release Notes](/releases/release-7.1.6.md) - [TiDB 6.5.0 Release Notes](/releases/release-6.5.0.md) +### tidb_ttl_enable_index_scan + +Referenced in: + +- [Periodically Delete Expired Data Using TTL (Time to Live)](/time-to-live.md) +- [System Variables](/system-variables.md#tidb_ttl_enable_index_scan) + ### tidb_ttl_job_enable Referenced in: diff --git a/system-variables.md b/system-variables.md index ce7bf4e26cb5e..582cac865c3bf 100644 --- a/system-variables.md +++ b/system-variables.md @@ -6725,6 +6725,19 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Range: `[1, 256]` - This variable is used to set the maximum concurrency of TTL jobs on each TiDB node. For more information, refer to [Time to Live](/time-to-live.md). +### tidb_ttl_enable_index_scan + +> **Note:** +> +> This variable is read-only for [{{{ .starter }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#starter) and [{{{ .essential }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#essential) instances. + +- Scope: GLOBAL +- Persists to cluster: Yes +- Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No +- Default value: `ON` +- Type: Boolean +- This variable controls whether newly created TTL jobs can use an eligible secondary index or nonclustered primary index that starts with the TTL column. When this variable is set to `OFF`, new TTL jobs scan in table-key order. Changing this variable does not change the scan path of running TTL tasks. For index eligibility and rolling-upgrade behavior, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). + ### tidb_ttl_job_enable New in v6.5.0 > **Note:** diff --git a/time-to-live.md b/time-to-live.md index 05c60079086eb..d202c4b0ef3d9 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -140,6 +140,30 @@ When executing a TTL job, TiDB splits the table into tasks, with the Region as t TiDB also limits the number of concurrent TTL tasks at the cluster level. You can adjust this concurrency by setting the system variable [`tidb_ttl_running_tasks`](/system-variables.md#tidb_ttl_running_tasks-new-in-v700). +### Scan expired rows using an index + +By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. Compared with scanning in table-key order, scanning in TTL-column order avoids repeatedly scanning unexpired index entries. TiDB splits the job according to the TiKV Regions of the selected index, and Regions that are entirely after the expiration-time boundary do not participate in the job. + +This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variables.md#tidb_ttl_enable_index_scan) global variable, which is enabled by default. When this variable is disabled or no eligible index is available, TiDB falls back to scanning in table-key order and prevents the optimizer from selecting a secondary index for that scan. + +An index must meet all of the following requirements to be used by a TTL job: + +- It is a public, visible, local secondary index or nonclustered primary index. Clustered primary indexes, global indexes, multi-valued indexes, columnar indexes, and conditional indexes are not eligible. +- Its first column is the TTL column, and every indexed column stores the full value of a visible table column. Prefix indexes and indexes on hidden expression columns are not eligible. +- It provides a stable, unique pagination order. For a unique composite index, every indexed column other than the TTL column must be `NOT NULL`. For a non-unique index, the declared index columns must contain either the entire table key or none of it. If they contain none of the table key, TiDB appends the implicit table key to the pagination order when that physical order is supported. +- The final pagination columns do not contain `SET`, `FLOAT`, or `DOUBLE` columns. + +Here, the table key is the clustered primary key, or `_tidb_rowid` for a table without a clustered primary key. A non-unique index that contains only part of a composite table key is not eligible. An unsigned integer clustered primary key and a common handle with a prefix primary-key column cannot be used as an implicit suffix, but the index can still be eligible if it explicitly contains the complete table key. + +If multiple indexes are eligible, TiDB prefers a single-column index on the TTL column, then an index that explicitly contains the complete table key, and then the index with the shortest pagination tuple. If pagination tuples have the same length, TiDB prefers the index that requires reading fewer columns. + +> **Note:** +> +> - During a rolling upgrade, if a table would use an index scan but the TiDB server builds in the cluster do not match, TiDB does not create a new TTL job for that table. The scheduler retries after the TiDB server builds become consistent. To keep creating jobs using table-key scans during the upgrade, temporarily disable `tidb_ttl_enable_index_scan`. +> - If TiDB cannot obtain or compare server information, it creates the job using a table-key scan instead. +> - If the selected index is dropped after a TTL job is created, the affected task reports an error. A later TTL job can select another eligible index or fall back to a table-key scan. +> - Each scan page is a separate SQL statement. If an indexed value changes during a scan, the current job might skip the row or observe it again. Before deletion, TiDB checks the expiration condition again, so a row that is no longer expired is not deleted. An expired row skipped by the current job remains eligible for a later TTL job. + To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: ```sql @@ -207,7 +231,7 @@ In addition, TiDB provides three tables to obtain more information about TTL job The columns `{last, current}_job_{start_time, finish_time, ttl_expire}` describe respectively the start time, finish time, and expiration time used by the TTL job of the last or current execution. The `last_job_summary` column describes the execution status of the last TTL task, including the total number of rows, the number of successful rows, and the number of failed rows. -+ The `mysql.tidb_ttl_task` table contains information about the ongoing TTL subtasks. A TTL job is split into many subtasks, and this table records the subtasks that are currently being executed. ++ The `mysql.tidb_ttl_task` table contains information about the ongoing TTL subtasks. A TTL job is split into many subtasks, and this table records the subtasks that are currently being executed. The `scan_index_id` column indicates the scan path selected when the job was created. A non-`NULL` value is the ID of the selected index, and `NULL` means that the task scans in table-key order. + The `mysql.tidb_ttl_job_history` table contains information about the TTL jobs that have been executed. The record of TTL job history is kept for 90 days. ```sql From c7bdb08585f1e5f26f2bc5e7831cf8af68d67819 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Wed, 9 Sep 2026 19:48:11 +0800 Subject: [PATCH 2/8] docs: simplify TTL index scan requirements --- system-variables.md | 2 +- time-to-live.md | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/system-variables.md b/system-variables.md index 582cac865c3bf..d0d493fa55a54 100644 --- a/system-variables.md +++ b/system-variables.md @@ -6736,7 +6736,7 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Default value: `ON` - Type: Boolean -- This variable controls whether newly created TTL jobs can use an eligible secondary index or nonclustered primary index that starts with the TTL column. When this variable is set to `OFF`, new TTL jobs scan in table-key order. Changing this variable does not change the scan path of running TTL tasks. For index eligibility and rolling-upgrade behavior, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). +- This variable controls whether TTL jobs can use an eligible secondary index or nonclustered primary index that starts with the TTL column. When this variable is set to `OFF`, TTL jobs scan in table-key order. For index eligibility, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). ### tidb_ttl_job_enable New in v6.5.0 diff --git a/time-to-live.md b/time-to-live.md index d202c4b0ef3d9..69bf7957a80cc 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -142,27 +142,19 @@ TiDB also limits the number of concurrent TTL tasks at the cluster level. You ca ### Scan expired rows using an index -By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. Compared with scanning in table-key order, scanning in TTL-column order avoids repeatedly scanning unexpired index entries. TiDB splits the job according to the TiKV Regions of the selected index, and Regions that are entirely after the expiration-time boundary do not participate in the job. +By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. This avoids scanning unexpired index entries. TiDB splits the job by the Regions of the selected index and does not create tasks for Regions entirely after the expiration-time boundary. This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variables.md#tidb_ttl_enable_index_scan) global variable, which is enabled by default. When this variable is disabled or no eligible index is available, TiDB falls back to scanning in table-key order and prevents the optimizer from selecting a secondary index for that scan. -An index must meet all of the following requirements to be used by a TTL job: +An eligible index must meet the following requirements: -- It is a public, visible, local secondary index or nonclustered primary index. Clustered primary indexes, global indexes, multi-valued indexes, columnar indexes, and conditional indexes are not eligible. -- Its first column is the TTL column, and every indexed column stores the full value of a visible table column. Prefix indexes and indexes on hidden expression columns are not eligible. -- It provides a stable, unique pagination order. For a unique composite index, every indexed column other than the TTL column must be `NOT NULL`. For a non-unique index, the declared index columns must contain either the entire table key or none of it. If they contain none of the table key, TiDB appends the implicit table key to the pagination order when that physical order is supported. -- The final pagination columns do not contain `SET`, `FLOAT`, or `DOUBLE` columns. +- It is a visible secondary index or nonclustered primary index, and its first column is the TTL column. +- Each index column indexes the full column value. Prefix indexes and expression indexes are not supported. +- In a unique composite index, all columns except the TTL column are `NOT NULL`. +- For a non-unique index, TiDB must be able to append the table row identifier to the scan order. Including all primary key columns in the index ensures this requirement; including only some columns of a composite primary key is not supported. +- The columns used to identify a row do not use the `SET`, `FLOAT`, or `DOUBLE` data type. -Here, the table key is the clustered primary key, or `_tidb_rowid` for a table without a clustered primary key. A non-unique index that contains only part of a composite table key is not eligible. An unsigned integer clustered primary key and a common handle with a prefix primary-key column cannot be used as an implicit suffix, but the index can still be eligible if it explicitly contains the complete table key. - -If multiple indexes are eligible, TiDB prefers a single-column index on the TTL column, then an index that explicitly contains the complete table key, and then the index with the shortest pagination tuple. If pagination tuples have the same length, TiDB prefers the index that requires reading fewer columns. - -> **Note:** -> -> - During a rolling upgrade, if a table would use an index scan but the TiDB server builds in the cluster do not match, TiDB does not create a new TTL job for that table. The scheduler retries after the TiDB server builds become consistent. To keep creating jobs using table-key scans during the upgrade, temporarily disable `tidb_ttl_enable_index_scan`. -> - If TiDB cannot obtain or compare server information, it creates the job using a table-key scan instead. -> - If the selected index is dropped after a TTL job is created, the affected task reports an error. A later TTL job can select another eligible index or fall back to a table-key scan. -> - Each scan page is a separate SQL statement. If an indexed value changes during a scan, the current job might skip the row or observe it again. Before deletion, TiDB checks the expiration condition again, so a row that is no longer expired is not deleted. An expired row skipped by the current job remains eligible for a later TTL job. +TTL jobs do not use clustered primary indexes, partial indexes, global indexes, multi-valued indexes, columnar indexes, or invisible indexes. To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: From afeda1a51acfa3d52fa8f45a9b04c6fc8dbcd0a8 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Wed, 9 Sep 2026 19:54:04 +0800 Subject: [PATCH 3/8] docs: clarify eligible TTL indexes --- time-to-live.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/time-to-live.md b/time-to-live.md index 69bf7957a80cc..33ea8beeea7d1 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -142,20 +142,18 @@ TiDB also limits the number of concurrent TTL tasks at the cluster level. You ca ### Scan expired rows using an index -By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. This avoids scanning unexpired index entries. TiDB splits the job by the Regions of the selected index and does not create tasks for Regions entirely after the expiration-time boundary. +By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. This avoids scanning unexpired index entries. This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variables.md#tidb_ttl_enable_index_scan) global variable, which is enabled by default. When this variable is disabled or no eligible index is available, TiDB falls back to scanning in table-key order and prevents the optimizer from selecting a secondary index for that scan. An eligible index must meet the following requirements: -- It is a visible secondary index or nonclustered primary index, and its first column is the TTL column. -- Each index column indexes the full column value. Prefix indexes and expression indexes are not supported. +- It is a visible secondary index or nonclustered primary index, rather than a partial, global, multi-valued, or columnar index. +- Its first column is the TTL column, and each index column indexes the full column value. Prefix indexes and expression indexes are not supported. - In a unique composite index, all columns except the TTL column are `NOT NULL`. -- For a non-unique index, TiDB must be able to append the table row identifier to the scan order. Including all primary key columns in the index ensures this requirement; including only some columns of a composite primary key is not supported. +- A non-unique index includes either all primary key columns or none of them. - The columns used to identify a row do not use the `SET`, `FLOAT`, or `DOUBLE` data type. -TTL jobs do not use clustered primary indexes, partial indexes, global indexes, multi-valued indexes, columnar indexes, or invisible indexes. - To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: ```sql From afc66a55982760c617c9d2261ad198216ce42550 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Thu, 10 Sep 2026 13:16:56 +0800 Subject: [PATCH 4/8] docs: clarify TTL index column type limits --- time-to-live.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/time-to-live.md b/time-to-live.md index 33ea8beeea7d1..c60c6d6f3057e 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -152,7 +152,7 @@ An eligible index must meet the following requirements: - Its first column is the TTL column, and each index column indexes the full column value. Prefix indexes and expression indexes are not supported. - In a unique composite index, all columns except the TTL column are `NOT NULL`. - A non-unique index includes either all primary key columns or none of them. -- The columns used to identify a row do not use the `SET`, `FLOAT`, or `DOUBLE` data type. +- Index columns cannot use the `SET`, `FLOAT`, or `DOUBLE` data type. For a non-unique index that does not include primary key columns, the primary key columns cannot use these data types either. To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: From a0d2d91c9fd26c2f9bd958cf85e5680c072b6e5d Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Thu, 10 Sep 2026 14:27:54 +0800 Subject: [PATCH 5/8] docs: document additional TTL index restrictions --- system-variables.md | 2 +- time-to-live.md | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/system-variables.md b/system-variables.md index d0d493fa55a54..6773c2c3b1a49 100644 --- a/system-variables.md +++ b/system-variables.md @@ -6736,7 +6736,7 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Default value: `ON` - Type: Boolean -- This variable controls whether TTL jobs can use an eligible secondary index or nonclustered primary index that starts with the TTL column. When this variable is set to `OFF`, TTL jobs scan in table-key order. For index eligibility, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). +- This variable controls whether TTL jobs can use an eligible secondary index or non-clustered primary key that starts with the TTL column. When this variable is set to `OFF`, TTL jobs scan in table-key order. For index eligibility, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). ### tidb_ttl_job_enable New in v6.5.0 diff --git a/time-to-live.md b/time-to-live.md index c60c6d6f3057e..3bc042e79498f 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -148,10 +148,14 @@ This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variab An eligible index must meet the following requirements: -- It is a visible secondary index or nonclustered primary index, rather than a partial, global, multi-valued, or columnar index. +- It is a secondary index or a non-clustered primary key. TiDB does not use a clustered primary key, partial index, global index, multi-valued index, vector search index, full-text index, or invisible index for this scan. - Its first column is the TTL column, and each index column indexes the full column value. Prefix indexes and expression indexes are not supported. -- In a unique composite index, all columns except the TTL column are `NOT NULL`. -- A non-unique index includes either all primary key columns or none of them. +- For a unique index that contains multiple columns, all columns except the TTL column are `NOT NULL`. +- A non-unique index meets the following requirements: + - It includes either all primary key columns or none of them. It cannot include only some columns of a composite primary key. + - If the table has a clustered primary key consisting of a single unsigned integer column, the index includes that primary key column. + - If any column of the clustered primary key is defined with a prefix length, the index includes all primary key columns. + - If the [new collation framework](/character-set-and-collation.md#new-framework-for-collations) is enabled, for a table created by an earlier TiDB version whose clustered primary key contains non-binary string columns, include all primary key columns to avoid compatibility restrictions. - Index columns cannot use the `SET`, `FLOAT`, or `DOUBLE` data type. For a non-unique index that does not include primary key columns, the primary key columns cannot use these data types either. To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: From e52bd55e0b7906e09e800521517e9fd93e2c2605 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Thu, 10 Sep 2026 14:36:12 +0800 Subject: [PATCH 6/8] docs: simplify TTL index compatibility requirement --- time-to-live.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/time-to-live.md b/time-to-live.md index 3bc042e79498f..3b72a46056a8f 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -155,7 +155,7 @@ An eligible index must meet the following requirements: - It includes either all primary key columns or none of them. It cannot include only some columns of a composite primary key. - If the table has a clustered primary key consisting of a single unsigned integer column, the index includes that primary key column. - If any column of the clustered primary key is defined with a prefix length, the index includes all primary key columns. - - If the [new collation framework](/character-set-and-collation.md#new-framework-for-collations) is enabled, for a table created by an earlier TiDB version whose clustered primary key contains non-binary string columns, include all primary key columns to avoid compatibility restrictions. + - For a table created by an earlier TiDB version whose clustered primary key contains non-binary string columns, the index includes all primary key columns. - Index columns cannot use the `SET`, `FLOAT`, or `DOUBLE` data type. For a non-unique index that does not include primary key columns, the primary key columns cannot use these data types either. To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: From a1709331783e200910b1fa9aad7d3ac0e76a4e80 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Thu, 10 Sep 2026 14:50:31 +0800 Subject: [PATCH 7/8] docs: remove unsupported legacy TTL restriction --- time-to-live.md | 1 - 1 file changed, 1 deletion(-) diff --git a/time-to-live.md b/time-to-live.md index 3b72a46056a8f..e2e52439d7ffb 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -155,7 +155,6 @@ An eligible index must meet the following requirements: - It includes either all primary key columns or none of them. It cannot include only some columns of a composite primary key. - If the table has a clustered primary key consisting of a single unsigned integer column, the index includes that primary key column. - If any column of the clustered primary key is defined with a prefix length, the index includes all primary key columns. - - For a table created by an earlier TiDB version whose clustered primary key contains non-binary string columns, the index includes all primary key columns. - Index columns cannot use the `SET`, `FLOAT`, or `DOUBLE` data type. For a non-unique index that does not include primary key columns, the primary key columns cannot use these data types either. To disable the execution of TTL jobs, in addition to setting the `TTL_ENABLE='OFF'` table option, you can also disable the execution of TTL jobs in the entire cluster by setting the [`tidb_ttl_job_enable`](/system-variables.md#tidb_ttl_job_enable-new-in-v650) global variable: From f693e18139b8f66b9b8c99d5f77f1e2c446e1a41 Mon Sep 17 00:00:00 2001 From: Yang Keao Date: Thu, 10 Sep 2026 16:31:33 +0800 Subject: [PATCH 8/8] clarify TTL index scan requirements --- system-variables.md | 2 +- time-to-live.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/system-variables.md b/system-variables.md index 6773c2c3b1a49..e4f31fe0b72f7 100644 --- a/system-variables.md +++ b/system-variables.md @@ -6736,7 +6736,7 @@ For details, see [Identify Slow Queries](/identify-slow-queries.md). - Applies to hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value): No - Default value: `ON` - Type: Boolean -- This variable controls whether TTL jobs can use an eligible secondary index or non-clustered primary key that starts with the TTL column. When this variable is set to `OFF`, TTL jobs scan in table-key order. For index eligibility, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). +- This variable controls whether TTL jobs can use an eligible secondary index or non-clustered primary key index that starts with the TTL column. When this variable is set to `OFF`, TTL jobs scan in table-key order. For index eligibility, see [Scan expired rows using an index](/time-to-live.md#scan-expired-rows-using-an-index). ### tidb_ttl_job_enable New in v6.5.0 diff --git a/time-to-live.md b/time-to-live.md index e2e52439d7ffb..80e19f2781322 100644 --- a/time-to-live.md +++ b/time-to-live.md @@ -142,14 +142,14 @@ TiDB also limits the number of concurrent TTL tasks at the cluster level. You ca ### Scan expired rows using an index -By default, TiDB uses an eligible index that starts with the TTL column to scan expired rows. This avoids scanning unexpired index entries. +To use an index scan, the TTL column must be the first column of the index. This allows TiDB to scan the index range that can contain expired rows without scanning unexpired index entries. -This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variables.md#tidb_ttl_enable_index_scan) global variable, which is enabled by default. When this variable is disabled or no eligible index is available, TiDB falls back to scanning in table-key order and prevents the optimizer from selecting a secondary index for that scan. +By default, TiDB automatically selects an eligible index for this scan. This behavior is controlled by the [`tidb_ttl_enable_index_scan`](/system-variables.md#tidb_ttl_enable_index_scan) global variable, which is enabled by default. When this variable is disabled or no eligible index is available, TiDB falls back to scanning in table-key order and prevents the optimizer from selecting a secondary index for that scan. For a table with a clustered primary key, the table-key scan uses that primary key. -An eligible index must meet the following requirements: +In addition to starting with the TTL column, an eligible index must meet the following requirements: -- It is a secondary index or a non-clustered primary key. TiDB does not use a clustered primary key, partial index, global index, multi-valued index, vector search index, full-text index, or invisible index for this scan. -- Its first column is the TTL column, and each index column indexes the full column value. Prefix indexes and expression indexes are not supported. +- It is a visible secondary index or a non-clustered primary key index. It is not a partial index, global index, multi-valued index, vector search index, or full-text index. +- Each index column indexes the full column value. Prefix indexes and expression indexes are not supported. - For a unique index that contains multiple columns, all columns except the TTL column are `NOT NULL`. - A non-unique index meets the following requirements: - It includes either all primary key columns or none of them. It cannot include only some columns of a composite primary key. @@ -224,7 +224,7 @@ In addition, TiDB provides three tables to obtain more information about TTL job The columns `{last, current}_job_{start_time, finish_time, ttl_expire}` describe respectively the start time, finish time, and expiration time used by the TTL job of the last or current execution. The `last_job_summary` column describes the execution status of the last TTL task, including the total number of rows, the number of successful rows, and the number of failed rows. -+ The `mysql.tidb_ttl_task` table contains information about the ongoing TTL subtasks. A TTL job is split into many subtasks, and this table records the subtasks that are currently being executed. The `scan_index_id` column indicates the scan path selected when the job was created. A non-`NULL` value is the ID of the selected index, and `NULL` means that the task scans in table-key order. ++ The `mysql.tidb_ttl_task` table contains information about the ongoing TTL subtasks. A TTL job is split into subtasks, and this table records the subtasks that are currently being executed. The `scan_index_id` column indicates the scan path selected when the job was created. A non-`NULL` value is the ID of the selected index, and `NULL` means that the task scans in table-key order. + The `mysql.tidb_ttl_job_history` table contains information about the TTL jobs that have been executed. The record of TTL job history is kept for 90 days. ```sql