---
title: "资源限流最佳实践 - OceanBase 最佳实践 | OceanBase 文档中心"
description: 资源限流最佳实践 在数据库运行过程中，一个常见的性能问题是系统资源异常占用，这会导致每秒查询率（QPS）下降明显，严重时甚至会跌至 0。这个问题可能由多种因素引起，比如非预期的 SQL 语句消耗了过多资源、业务流量突然增长、或业务负载模式发生变化（如大规模请求的增加），这些情况都会导致对 CPU、内存以及 I/O 等…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

# 资源限流最佳实践

更新时间：2026-07-28

[编辑](https://github.com/oceanbase/best-practices-doc/edit/master/zh-CN/700.management/100.bset-practices-for-resource-flow-limiting.md) 适用产品： OceanBase 数据库 适用场景： 运维管理  

在数据库运行过程中，一个常见的性能问题是系统资源异常占用，这会导致每秒查询率（QPS）下降明显，严重时甚至会跌至 0。这个问题可能由多种因素引起，比如非预期的 SQL 语句消耗了过多资源、业务流量突然增长、或业务负载模式发生变化（如大规模请求的增加），这些情况都会导致对 CPU、内存以及 I/O 等关键资源的需求激增，直至耗尽可用资源。为应对这一挑战，OceanBase 数据库提供了产品化的限流能力，旨在通过调整不同场景下的资源分配策略，有效缓解因资源竞争而导致的服务性能下降问题。这种方法不仅有助于提高系统的稳定性和响应速度，还能够在高负载情况下提供更加可靠的服务体验。

## 场景一：OLTP 场景下，数据库中存在少量性能异常的 SQL 请求

### 场景说明

对于 OLTP 场景，高并发的交易类小请求居多，偶尔会出现少量因计划不优、访问数据量大等导致的异常 SQL 请求，这些请求长时间占用集群资源，导致正常的交易请求受阻，需要应急方案控制或者释放异常 SQL 的资源。

### 解决方案

针对此类场景，OceanBase 数据库提供了两种解决方案。

**方案一**：在集群级别设置大查询判定策略，限制大查询的 CPU 占用，优先将 CPU 提供给小请求，解决突发的异常 SQL 阻塞正常请求的问题。

具体方案如下：

- **限流策略**

  通过以下配置项，分别设置大查询的判定策略以及大查询的 CPU 占用：

     - 集群级配置项 `large_query_threshold`：用于配置查询执行时间的阈值，超过该时间的请求被认为是大查询，默认为 5s。

      需要使用 sys 租户设置该配置项，示例如下：

      ```shell
      obclient> ALTER SYSTEM SET large_query_threshold = '5s';

      ```
     - 集群级配置项 `large_query_worker_percentage`：用于设置预留给处理大查询的工作线程百分比，默认为 30。

      ```shell
      obclient> ALTER SYSTEM SET large_query_worker_percentage = 30;

      ```
 - **大查询处理策略**

  当一个线程执行的 SQL 被判定为大查询, 执行大查询的线程会被标记为大查询线程，此时，系统仅允许一定数量的线程继续执行大查询（默认是 30%），剩下的线程就会被挂起。由于租户活跃线程数为固定值（cpu_count * cpu_quota_concurrency），在大查询线程挂起自身的同时，系统会分配一个新的线程来处理队列中的新请求，这样就为其它的小查询让出 CPU ，待小查询执行一段时间后，大查询继续执行，保证小查询高时效性的同时也不会影响大查询的最终完成，从而提高整体的用户体验和系统的响应性能。
 - **提前识别大查询**

  如果集群中有大量的大查询，且都是在执行中才被判定为大查询，则有可能会耗光租户工作线程，导致小查询无法执行。因此，OceanBase 数据库在 SQL 编译期也增加了大查询预定。在 SQL 开始执行之前从 Plan Cache 中获取 SQL 的执行计划, 通过平均执行时间是否超过大查询阈值来判定其是否为大查询。如果某个 SQL 被预判为大查询，那么该 SQL 就会被放入一个特殊的大查询队列重试，其线程会被释放，系统就能接着执行后面的请求了。
 - **查询限流记录**

  通过视图 `gv$ob_plan_cache_plan_stat` 可以查看大查询的限制记录。重点关注 `LARGE_QUERYS` 列（被判断为大查询的次数）和 `DELAYED_LARGE_QUERYS` 列（被判断为大查询且被丢入大查询队列的次数）。

**方案二**：对临时发起或消耗较多资源的复杂 SQL 请求，增加 SQL 级并发度限制（outline）。

具体方案如下：

  使用 Outline 绑定, 添加 `/*+max_concurrent(N)*/` 这个 Hint。其中，`N` 表示某类 Query 可同时执行的请求数，实际内部限制的是某个 Plan 可同时执行的请求数。

  当被限流的 SQL 达到最大并发个数后，再有新的限流 SQL 执行时，系统会出现 `SQL reach max concurrent num` 的报错。
 - **限流绑定方式**

  支持使用文本限流、SQL_ID 限流以及模糊限流三种方式来绑定 Outline。

  #### 注意

     - 当同一条 SQL 可以匹配多个限流规则时，会选择并发度最小的进行限流。
     - 所有的 Outline 相关功能都只能针对本租户，不能通过系统租户对其他租户进行 Outline 相关操作。  
     - 使用文本限流

      语句如下：

      ```sql
      CREATE [OR REPLACE] OUTLINE outline_name ON stmt [ TO target_stmt ];

      ```

      部分参数说明如下：

           - `outline_name`：指定 Outline 的名称。
           - `stmt`：指定需要绑定 Outline 的 SQL 语句。一般为一个带有 Hint 和原始参数的 DML 语句。
           - `TO target_stmt`：如果不指定 `TO target_stmt`，则表示如果数据库接受的 SQL 参数化后与 `stmt` 去掉 Hint 参数化的文本相同，则将该 SQL 绑定 `stmt` 中的 Hint 生成执行计划；如果期望对含有 Hint 的语句进行固定计划，则需要使用 `TO target_stmt` 来指明原始的 SQL。

      以 SQL 文本的形式创建 Outline，并在 Hint 中指定限流的示例如下：

      ```shell
      obclient> CREATE OUTLINE ol_1 ON SELECT /*+max_concurrent(0)*/ * FROM t1 WHERE c1 = 1 AND c2 = ?;

      ```

      本示例中，实际生效的 SQL 如下：

      ```sql
      SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;

      ```

      和

      ```sql
      SELECT * FROM t1 WHERE c1 = 1 AND c2 = 2;

      ```

      有关 `CREATE OUTLINE` 语句的详细说明及示例，参见 [CREATE OUTLINE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000511012)。
     - 使用 SQL_ID 限流

      语句如下：

      ```sql
      CREATE [OR REPLACE] OUTLINE outline_name ON sql_id USING HINT hint;

      ```

      部分参数说明如下：

           - `outline_name`：指定 Outline 的名称。
           - `sql_id`：指定需要绑定 Outline 的 SQL 的 ID。可通过查询视图 `V$OB_PLAN_CACHE_PLAN_STAT` 或 `GV$OB_SQL_AUDIT` 获取或者通过参数化的原始 SQL，使用 MD5 生成 SQL_ID。获取 `sql_id` 的详细操作及说明可参见 [计划绑定](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001036351)。
           - `hint`：指定需要绑定 Outline 的 SQL 的 Hint。格式为 `/*+ xxx */`。

      假设获取的 SQL_ID 为 `A1887AEC05DF723958F85E2AA89C8085`，则使用 SQL_ID 绑定 Outline 的示例如下：

      ```shell
      obclient> CREATE OUTLINE otl ON "A1887AEC05DF723958F85E2AA89C8085" USING HINT /*+max_concurrent(0)*/;

      ```

      有关 `CREATE OUTLINE` 语句的详细说明及示例，参见 [CREATE OUTLINE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000511012)。
     - 模糊限流

      #### 注意

      对于 V4.2.x 版本，当前仅 V4.2.2 及以上版本支持模糊绑定方式；对于 V4.3.x 版本，暂不支持模糊绑定方式。

      语句如下：

      ```sql
      CREATE [OR REPLACE] FORMAT OUTLINE outline_name ON format_stmt [ TO format_target_stmt ]

      ```

      或者

      ```sql
      CREATE [OR REPLACE] FORMAT OUTLINE outline_name ON format_sql_id USING HINT hint;

      ```

      部分参数说明如下：

           - `outline_name`：指定 Outline 的名称。
           - `format_stmt`：通过归一化规则改写后的 SQL。通常，这种 `stmt` 可以通过一些表达式或 DBMS 包获取。

            归一化规则如下：

                   - 归一化常量参数。
                   - 归一化为大写。
                   - 忽略空格、换行符等非语法定义符号的差异。
                   - 对于 IN 表达式，将会做归一化。
           - `format_target_stmt`：与 `format_stmt` 获取方式相同，但需要注意，如果期望对含有 Hint 的语句进行固定计划，则应使用 `format_target_stmt` 指明原始 SQL。在使用 `TO format_target_stmt` 子句时，要求原始 SQL `format_stmt` 与 `format_target_stmt` 在去掉 HINT 后完全匹配。
           - `format_sql_id`：通过归一化规则改写后得到 `format_stmt`，然后根据 `format_stmt` 计算 MD5 值得到 `format_sql_id`。

      有关 `CREATE FORMAT OUTLINE` 语句的详细说明及示例，参见 [CREATE FORMAT OUTLINE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000511036)。
 - **查看、修改和删除限流规则**

  绑定限流策略后，可以通过以下方式，查看、修改或删除限流规则：

     - 通过视图 `DBA_OB_CONCURRENT_LIMIT_SQL` 查看 Outline 的限流记录。有关视图 `DBA_OB_CONCURRENT_LIMIT_SQL` 的详细说明，参见 [DBA_OB_CONCURRENT_LIMIT_SQL](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000509569)。
     - 使用 `ALTER OUTLINE` 语句修改限流规则。有关 `ALTER OUTLINE` 语句的详细说明及示例，参见 [ALTER OUTLINE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000511000)。
     - 使用 `DROP OUTLINE` 语句删除 outline_name 对应的所有限流规则。有关 `DROP OUTLINE` 语句的详细说明及示例，参见 [DROP OUTLINE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000511035)。

## 场景二：数据库中存在不同类型的请求混合负载

### 场景说明

该场景又可以细分为典型的 OLTP 和 OLAP 混合负载场景以及生产业务请求和临时任务混合负载场景。

对于典型的 OLTP 和 OLAP 混合负载场景，其业务场景分为联机交易（OLTP）和报表分析（OLAP）两大类，其中交易系统中运行的 SQL 大多是简单SQL的高并发，且对实时性要求高，这类 SQL 的大量并发对服务器不构成持续压力，短时间内可执行完成，不会造成业务堆积。报表系统中运行的 SQL 以复杂 SQL 居多，整体业务逻辑相对复杂，非常耗费资源，但优先级相对较低。数据库整体层面需要分别对交易和报表系统进行合理的资源管控，以保障数据库系统正常运行。

对于生产业务请求和临时任务混合负载场景，其业务场景中除了有常规的生产 SQL 请求，同时还持续存在一些系统监控、临时运维任务等，需要数据库将系统资源分别隔离，让生产 SQL 不受临时和异常任务影响，保证业务稳定运行。

### 解决方案

针对此类场景，可以为不同的业务类型创建不同的资源组，将负载分别放入各自的资源组，通过 Resource Manager 统一控制 CPU、IO 的使用，从而做到数据库资源的隔离与分配。

具体方案如下：

  通过以下几种方式来实现资源的限流：

     - User 级限制资源：指定用户与资源组的映射关系，使该用户只能使用指定的 Group 资源。
     - SQL 级限制资源：通过绑定资源组，使特定 SQL 使用指定的 Group 资源。
     - Function 级限制资源：指定后台任务与资源组的映射关系，隔离各任务使用的资源。
 - **限流方式**

  有关限流的详细操作，参见 [资源隔离](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000819168)。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
