diff --git a/identify-slow-queries.md b/identify-slow-queries.md
index 66928ec623fd..48ca86196cf8 100644
--- a/identify-slow-queries.md
+++ b/identify-slow-queries.md
@@ -59,7 +59,7 @@ Slow Query 基础信息:
* `Compile_time`:表示这个语句在查询优化阶段花费的时间。
* `Optimize_time`:表示这个语句在优化查询计划阶段花费的时间。
* `Wait_TS`:表示这个语句在等待获取事务 TS 阶段花费的时间。
-* `Query`:表示 SQL 语句。慢日志里面不会打印 `Query`,但映射到内存表后,对应的字段叫 `Query`。
+* `Query`:表示 SQL 语句。慢查询日志里面不会打印 `Query`,但映射到内存表后,对应的字段叫 `Query`。
* `Digest`:表示 SQL 语句的指纹。
* `Txn_start_ts`:表示事务的开始时间戳,也是事务的唯一 ID,可以用这个值在 TiDB 日志中查找事务相关的其他日志。
* `Is_internal`:表示是否为 TiDB 内部的 SQL 语句。`true` 表示 TiDB 系统内部执行的 SQL 语句,`false` 表示用户执行的 SQL 语句。
@@ -173,29 +173,109 @@ Slow Query 基础信息:
- `Storage_from_kv`:从 v9.0.0 开始引入,表示该语句是否从 TiKV 读取数据。
- `Storage_from_mpp`:从 v9.0.0 开始引入,表示该语句是否从 TiFlash 读取数据。
-## 相关系统变量
+## 相关 Hint
+
+从 v9.0.0 开始,你可以使用 `WRITE_SLOW_LOG` Hint。该 Hint 用于强制 TiDB 将特定 SQL 的执行信息输出至慢查询日志,无论其执行时长是否达到阈值。这有助于捕获 SQL 执行过程中的详细元数据,如执行计划和资源消耗。例如,在出现偶发性能抖动问题时,某些 SQL 仅在特定条件下(如数据量突增或索引失效)才会变慢,而平时执行速度很快,因此难以通过默认的慢查询阈值捕获。这种情况下,可以预先在业务 SQL 中添加 `WRITE_SLOW_LOG` Hint,确保在问题复现的瞬间,系统能完整记录下该次 SQL 执行的详细信息。
-* [tidb_slow_log_threshold](/system-variables.md#tidb_slow_log_threshold):设置慢日志的阈值,执行时间超过阈值的 SQL 语句将被记录到慢日志中。默认值是 300 ms。
-* [tidb_query_log_max_len](/system-variables.md#tidb_query_log_max_len):设置慢日志记录 SQL 语句的最大长度。默认值是 4096 byte。
-* [tidb_redact_log](/system-variables.md#tidb_redact_log):设置慢日志记录 SQL 时是否将用户数据脱敏用 `?` 代替。默认值是 `0`,即关闭该功能。
-* [tidb_enable_collect_execution_info](/system-variables.md#tidb_enable_collect_execution_info):设置是否记录执行计划中各个算子的物理执行信息,默认值是 `1`。该功能对性能的影响约为 3%。开启该项后查看 `Plan` 的示例如下:
+- 该 Hint 不受任何阈值或触发规则限制,即无论该 SQL 查询是否达到慢查询日志打印阈值,都会打印慢查询日志。
+- 目前只支持强制开启打印慢查询日志,暂不支持通过 `WRITE_SLOW_LOG(FALSE)` 强制关闭打印慢查询日志。
+
+使用示例:
```sql
-> select tidb_decode_plan('jAOIMAk1XzE3CTAJMQlmdW5jczpjb3VudChDb2x1bW4jNyktPkMJC/BMNQkxCXRpbWU6MTAuOTMxNTA1bXMsIGxvb3BzOjIJMzcyIEJ5dGVzCU4vQQoxCTMyXzE4CTAJMQlpbmRleDpTdHJlYW1BZ2dfOQkxCXQRSAwyNzY4LkgALCwgcnBjIG51bTogMQkMEXMQODg0MzUFK0hwcm9jIGtleXM6MjUwMDcJMjA2HXsIMgk1BWM2zwAAMRnIADcVyAAxHcEQNQlOL0EBBPBbCjMJMTNfMTYJMQkzMTI4MS44NTc4MTk5MDUyMTcJdGFibGU6dCwgaW5kZXg6aWR4KGEpLCByYW5nZTpbLWluZiw1MDAwMCksIGtlZXAgb3JkZXI6ZmFsc2UJMjUBrgnQVnsA');
-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| tidb_decode_plan('jAOIMAk1XzE3CTAJMQlmdW5jczpjb3VudChDb2x1bW4jNyktPkMJC/BMNQkxCXRpbWU6MTAuOTMxNTA1bXMsIGxvb3BzOjIJMzcyIEJ5dGVzCU4vQQoxCTMyXzE4CTAJMQlpbmRleDpTdHJlYW1BZ2dfOQkxCXQRSAwyNzY4LkgALCwgcnBjIG51bTogMQkMEXMQODg0MzUFK0hwcm9jIGtleXM6MjUwMDcJMjA2HXsIMg |
-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| id task estRows operator info actRows execution info memory disk |
-| StreamAgg_17 root 1 funcs:count(Column#7)->Column#5 1 time:10.931505ms, loops:2 372 Bytes N/A |
-| └─IndexReader_18 root 1 index:StreamAgg_9 1 time:10.927685ms, loops:2, rpc num: 1, rpc time:10.884355ms, proc keys:25007 206 Bytes N/A |
-| └─StreamAgg_9 cop 1 funcs:count(1)->Column#7 1 time:11ms, loops:25 N/A N/A |
-| └─IndexScan_16 cop 31281.857819905217 table:t, index:idx(a), range:[-inf,50000), keep order:false 25007 time:11ms, loops:25 N/A N/A |
-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+SELECT /*+ WRITE_SLOW_LOG */ count(*) FROM t t1, t t2 WHERE t1.a = t2.b;
```
-在性能测试中可以关闭自动收集算子的执行信息:
+## 相关系统变量
-{{< copyable "sql" >}}
+* [`tidb_slow_log_threshold`](/system-variables.md#tidb_slow_log_threshold):用于设置慢查询日志的阈值,执行时间超过阈值的 SQL 语句将被记录到慢查询日志中。默认值是 300 ms。
+* [`tidb_slow_log_rules`](/system-variables.md#tidb_slow_log_rules-从-v900-版本开始引入):用于定义慢查询日志的触发规则,支持多维度指标组合条件,以实现更加灵活和精细化的日志记录控制。该变量在 v9.0.0 版本中引入,逐步替代传统的单一阈值控制方式,即替代 `tidb_slow_log_threshold` 的使用。该变量支持将以下字段作为筛选条件,设置输出慢查询日志的条件。详情请参考[字段含义说明](#字段含义说明)。
+ - 支持的筛选字段:
+ * Slow Query 基础信息:
+ * `Query_time`、`Parse_time`、`Compile_time`、`Optimize_time`、`Wait_TS`、`Rewrite_time`
+ * `Digest`、`Plan_digest`、`Is_internal`、`Succ`
+ * `Exec_retry_count`、`Backoff_time`、`Write_sql_response_total`
+ * 事务执行相关的字段:
+ * `Prewrite_time`、`Commit_time`、`Write_keys`、`Write_size`、`Prewrite_region`
+ * SQL 执行的用户相关的字段:
+ * `Conn_ID`、`DB`、`Session_alias`
+ * TiKV Coprocessor Task 相关的字段:
+ * `Process_time`、`Total_keys`、`Process_keys`、`Num_cop_tasks`
+ * 内存使用相关的字段:
+ * `Mem_max`
+ * 硬盘使用相关的字段:
+ * `Disk_max`
+ * 资源管控相关的字段:
+ * `Resource_group`
+ * 网络传输相关的字段:
+ * `KV_total`、`PD_total`
+ * `Unpacked_bytes_sent_tikv_total`、`Unpacked_bytes_received_tikv_total`
+ * `Unpacked_bytes_sent_tikv_cross_zone`、`Unpacked_bytes_received_tikv_cross_zone`
+ * `Unpacked_bytes_sent_tiflash_total`、`Unpacked_bytes_received_tiflash_total`
+ * `Unpacked_bytes_sent_tiflash_cross_zone`、`Unpacked_bytes_received_tiflash_cross_zone`
+ * 如果未设置 `tidb_slow_log_rules`:
+ * 慢查询日志触发仍依赖 `tidb_slow_log_threshold`。注:`query_time` 阈值的含义同该变量,均表示 SQL 执行时长阈值,以保持向后兼容。
+ * 如果已设置 `tidb_slow_log_rules`:
+ * 配置的规则优先生效,`tidb_slow_log_threshold` 将被忽略。
+ * 若希望规则中仍使用 SQL 执行时间作为输出慢日志的条件之一,可在设置规则时使用`query_time` 并设置阈值。
+ * 规则匹配逻辑(多条规则之间采用 OR 关系):
+ * SESSION 作用域规则:优先匹配,如果匹配成功,则打印慢查询日志。
+ * GLOBAL 作用域规则:仅在 SESSION 作用域规则未匹配时考虑:
+ * 若规则指定了 `ConnID` 并与当前会话的 `ConnID` 匹配,则使用该规则。
+ * 若规则未指定 `ConnID`(全局通用规则),则使用该规则。
+ * 使用 `SHOW VARIABLES`、`SELECT @@GLOBAL.tidb_slow_log_rules`、`SELECT @@SESSION.tidb_slow_log_rules` 显示该变量的行为与其他系统变量一致。
+ * 使用示例:
+ * 标准格式(SESSION 作用域):
+
+ ```sql
+ SET SESSION tidb_slow_log_rules = 'Query_time: 500, Is_internal: false';
+ ```
+
+ * 错误格式(SESSION 作用域不支持 `ConnID`):
+
+ ```sql
+ SET SESSION tidb_slow_log_rules = 'ConnID: 12, Query_time: 500, Is_internal: false';
+ ```
+
+ * 全局规则(适用于所有连接):
+
+ ```sql
+ SET GLOBAL tidb_slow_log_rules = 'Query_time: 500, Is_internal: false';
+ ```
+
+ * 指定特定连接的全局规则(分别适用于 `ConnID:11` 和 `ConnID:11` 的两个连接):
+
+ ```sql
+ SET GLOBAL tidb_slow_log_rules = 'ConnID: 11, Query_time: 500, Is_internal: false; ConnID: 12, Query_time: 600, Process_time: 300, DB: db1';
+ ```
+
+ > **Tip:**
+ >
+ > - `tidb_slow_log_rules` 用于替换单一阈值的方式,实现更灵活和精细化的慢查询日志控制,支持多维度指标组合条件。
+ > - 在资源充足的测试环境(1 个 TiDB 节点,16 核 CPU、48 GiB 内存;3 个 TiKV 节点,每个 16 核 CPU、48 GiB 内存)中,多次 sysbench 测试结果表明:当多维慢查询日志规则在 30 分钟内生成数百万条慢查询日志时,对性能影响较小;但当日志量达到千万级时,TPS 会明显下降,延迟也会显著增加。在业务负载较高或 CPU、内存资源接近瓶颈的情况下,应谨慎配置 `tidb_slow_log_rules`,避免因规则过宽导致日志洪泛。建议结合使用 `tidb_slow_log_max_per_sec` 来限制日志打印速率,以降低对业务性能的影响。
+
+* [`tidb_slow_log_max_per_sec`](/system-variables.md#tidb_slow_log_max_per_sec-从-v900-版本开始引入):用于设置每秒打印慢查询日志数量的上限,默认值为 `0`。
+ * 当值为 `0` 时,表示不限制每秒打印的慢查询日志数量。
+ * 当值大于 `0` 时,TiDB 每秒最多打印指定数量的慢查询日志,超过部分将被丢弃,不会写入慢查询日志文件。
+ * 建议在启用了 `tidb_slow_log_rules` 后配置该变量,以防止基于规则的慢查询日志触发过于频繁。
+* [`tidb_query_log_max_len`](/system-variables.md#tidb_query_log_max_len):设置慢查询日志记录 SQL 语句的最大长度。默认值是 4096 byte。
+* [`tidb_redact_log`](/system-variables.md#tidb_redact_log):设置慢查询日志记录 SQL 时,是否将用户数据脱敏用 `?` 代替。默认值是 `0`,即关闭该功能。
+* [`tidb_enable_collect_execution_info`](/system-variables.md#tidb_enable_collect_execution_info):设置是否记录执行计划中各个算子的物理执行信息,默认值是 `1`。开启该功能会导致性能降低约 3%。开启后查看 `Plan` 的示例如下:
+
+ ```sql
+ > select tidb_decode_plan('jAOIMAk1XzE3CTAJMQlmdW5jczpjb3VudChDb2x1bW4jNyktPkMJC/BMNQkxCXRpbWU6MTAuOTMxNTA1bXMsIGxvb3BzOjIJMzcyIEJ5dGVzCU4vQQoxCTMyXzE4CTAJMQlpbmRleDpTdHJlYW1BZ2dfOQkxCXQRSAwyNzY4LkgALCwgcnBjIG51bTogMQkMEXMQODg0MzUFK0hwcm9jIGtleXM6MjUwMDcJMjA2HXsIMgk1BWM2zwAAMRnIADcVyAAxHcEQNQlOL0EBBPBbCjMJMTNfMTYJMQkzMTI4MS44NTc4MTk5MDUyMTcJdGFibGU6dCwgaW5kZXg6aWR4KGEpLCByYW5nZTpbLWluZiw1MDAwMCksIGtlZXAgb3JkZXI6ZmFsc2UJMjUBrgnQVnsA');
+ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | tidb_decode_plan('jAOIMAk1XzE3CTAJMQlmdW5jczpjb3VudChDb2x1bW4jNyktPkMJC/BMNQkxCXRpbWU6MTAuOTMxNTA1bXMsIGxvb3BzOjIJMzcyIEJ5dGVzCU4vQQoxCTMyXzE4CTAJMQlpbmRleDpTdHJlYW1BZ2dfOQkxCXQRSAwyNzY4LkgALCwgcnBjIG51bTogMQkMEXMQODg0MzUFK0hwcm9jIGtleXM6MjUwMDcJMjA2HXsIMg |
+ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | id task estRows operator info actRows execution info memory disk |
+ | StreamAgg_17 root 1 funcs:count(Column#7)->Column#5 1 time:10.931505ms, loops:2 372 Bytes N/A |
+ | └─IndexReader_18 root 1 index:StreamAgg_9 1 time:10.927685ms, loops:2, rpc num: 1, rpc time:10.884355ms, proc keys:25007 206 Bytes N/A |
+ | └─StreamAgg_9 cop 1 funcs:count(1)->Column#7 1 time:11ms, loops:25 N/A N/A |
+ | └─IndexScan_16 cop 31281.857819905217 table:t, index:idx(a), range:[-inf,50000), keep order:false 25007 time:11ms, loops:25 N/A N/A |
+ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ ```
+
+在性能测试中可以关闭自动收集算子的执行信息:
```sql
set @@tidb_enable_collect_execution_info=0;
@@ -205,17 +285,17 @@ set @@tidb_enable_collect_execution_info=0;
更多详细信息,可以参见 [TiDB 专用系统变量和语法](/system-variables.md)。
-## 慢日志内存映射表
+## 慢查询日志内存映射表
-用户可通过查询 `INFORMATION_SCHEMA.SLOW_QUERY` 表来查询慢查询日志中的内容,表中列名和慢日志中字段名一一对应,表结构可查看 [`SLOW_QUERY` 表](/information-schema/information-schema-slow-query.md)中的介绍。
+用户可通过查询 `INFORMATION_SCHEMA.SLOW_QUERY` 表来查询慢查询日志中的内容,表中列名和慢查询日志中字段名一一对应,表结构可查看 [`SLOW_QUERY` 表](/information-schema/information-schema-slow-query.md)中的介绍。
> **注意:**
>
> 每次查询 `SLOW_QUERY` 表时,TiDB 都会去读取和解析一次当前的慢查询日志。
-TiDB 4.0 中,`SLOW_QUERY` 已经支持查询任意时间段的慢日志,即支持查询已经被 rotate 的慢日志文件的数据。用户查询时只需要指定 `TIME` 时间范围即可定位需要解析的慢日志文件。如果查询不指定时间范围,则仍然只解析当前的慢日志文件,示例如下:
+TiDB 4.0 中,`SLOW_QUERY` 已经支持查询任意时间段的慢查询日志,即支持查询已经被 rotate 的慢查询日志文件的数据。用户查询时只需要指定 `TIME` 时间范围即可定位需要解析的慢查询日志文件。如果查询不指定时间范围,则仍然只解析当前的慢查询日志文件,示例如下:
-不指定时间范围时,只会解析当前 TiDB 正在写入的慢日志文件的慢查询数据:
+不指定时间范围时,只会解析当前 TiDB 正在写入的慢查询日志文件的慢查询数据:
{{< copyable "sql" >}}
@@ -234,7 +314,7 @@ from slow_query;
+----------+----------------------------+----------------------------+
```
-指定查询 `2020-03-10 00:00:00` 到 `2020-03-11 00:00:00` 时间范围后,会定位指定时间范围内的慢日志文件后解析慢查询数据:
+指定查询 `2020-03-10 00:00:00` 到 `2020-03-11 00:00:00` 时间范围后,会定位指定时间范围内的慢查询日志文件后解析慢查询数据:
{{< copyable "sql" >}}
@@ -257,7 +337,7 @@ where time > '2020-03-10 00:00:00'
> **注意:**
>
-> 如果指定时间范围内的慢日志文件被删除,或者并没有慢查询,则查询结果会返回空。
+> 如果指定时间范围内的慢查询日志文件被删除,或者并没有慢查询,则查询结果会返回空。
TiDB 4.0 中新增了 [`CLUSTER_SLOW_QUERY`](/information-schema/information-schema-slow-query.md#cluster_slow_query-table) 系统表,用来查询所有 TiDB 节点的慢查询信息,表结构在 `SLOW_QUERY` 的基础上多增加了 `INSTANCE` 列,表示该行慢查询信息来自的 TiDB 节点地址。使用方式和 [`SLOW_QUERY`](/information-schema/information-schema-slow-query.md) 系统表一样。
@@ -468,9 +548,9 @@ select instance, count(*) from information_schema.cluster_slow_query where time
+---------------+----------+
```
-### 查询仅出现在异常时间段的慢日志
+### 查询仅出现在异常时间段的慢查询日志
-假如发现 `2020-03-10 13:24:00` ~ `2020-03-10 13:27:00` 的 QPS 降低或者延迟上升等问题,可能是由于突然出现大查询导致的,可以用下面 SQL 查询仅出现在异常时间段的慢日志,其中 `2020-03-10 13:20:00` ~ `2020-03-10 13:23:00` 为正常时间段。
+假如发现 `2020-03-10 13:24:00` ~ `2020-03-10 13:27:00` 的 QPS 降低或者延迟上升等问题,可能是由于突然出现大查询导致的,可以用下面 SQL 查询仅出现在异常时间段的慢查询日志,其中 `2020-03-10 13:20:00` ~ `2020-03-10 13:23:00` 为正常时间段。
{{< copyable "sql" >}}
@@ -521,7 +601,7 @@ min(prev_stmt) |
digest | 24bd6d8a9b238086c9b8c3d240ad4ef32f79ce94cf5a468c0b8fe1eb5f8d03df
```
-## 解析其他的 TiDB 慢日志文件
+## 解析其他的 TiDB 慢查询日志文件
TiDB 通过 session 变量 `tidb_slow_query_file` 控制查询 `INFORMATION_SCHEMA.SLOW_QUERY` 时要读取和解析的文件,可通过修改改 session 变量的值来查询其他慢查询日志文件的内容:
@@ -531,9 +611,9 @@ TiDB 通过 session 变量 `tidb_slow_query_file` 控制查询 `INFORMATION_SCHE
set tidb_slow_query_file = "/path-to-log/tidb-slow.log"
```
-## 用 `pt-query-digest` 工具分析 TiDB 慢日志
+## 用 `pt-query-digest` 工具分析 TiDB 慢查询日志
-可以用 `pt-query-digest` 工具分析 TiDB 慢日志。
+可以用 `pt-query-digest` 工具分析 TiDB 慢查询日志。
> **注意:**
>
diff --git a/system-variables.md b/system-variables.md
index 93952c7a0e45..cf5a8301c5de 100644
--- a/system-variables.md
+++ b/system-variables.md
@@ -5061,6 +5061,32 @@ Query OK, 0 rows affected, 1 warning (0.00 sec)
>
> 跳过字符检查可能会使 TiDB 检测不到应用写入的非法 UTF-8 字符,进一步导致执行 `ANALYZE` 时解码错误,以及引入其他未知的编码问题。如果应用不能保证写入字符串的合法性,不建议跳过该检查。
+### `tidb_slow_log_max_per_sec` 从 v9.0.0 版本开始引入
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否
+- 默认值:`0`
+- 类型:整数型
+- 范围:`[0, 1000000]`
+- 控制每个 TiDB 节点每秒打印的慢查询日志的数量上限。
+ - 当值为 `0` (默认值)时,表示不限制每秒打印的慢查询日志数量。
+ - 当值大于 `0` 时,TiDB 每秒最多打印指定数量的慢查询日志,超过部分将被丢弃,不会写入慢查询日志文件。
+- 该变量常与 [`tidb_slow_log_rules`](#tidb_slow_log_rules-从-v900-版本开始引入) 结合使用,以防止在高负载情况下产生过多的慢查询日志。
+
+### `tidb_slow_log_rules` 从 v9.0.0 版本开始引入
+
+- 作用域:SESSION | GLOBAL
+- 是否持久化到集群:是
+- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否
+- 默认值:""
+- 类型:字符串
+- 用于定义慢查询日志的触发规则,支持基于多维度指标的组合条件,实现更加灵活和精细化的日志记录控制。
+
+> **Tip:**
+>
+> 建议在启用 `tidb_slow_log_rules` 后,同时配置 [`tidb_slow_log_max_per_sec`](#tidb_slow_log_max_per_sec-从-v900-版本开始引入),以限制慢查询日志打印频率,防止基于规则的慢查询日志触发过于频繁。
+
### `tidb_slow_log_threshold`
- 作用域:GLOBAL