---
title: Plan Cache 内存用满-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 Plan Cache 内存用满相关的常见问题和使用技巧，帮助您快速解决 Plan Cache 内存用满的难题。
---
切换语言

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

划线反馈

# Plan Cache 内存用满

更新时间：2026-05-08 08:11

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x 内容类型：Troubleshoot  

## 适用版本

OceanBase 数据库 V2.x、V3.x 版本。

## 问题描述

OCP 监控平台告警，OBServer 日志出现 `plan cache memory used reach limit` 的报错。

```shell
2023-02-14T06:56:01+08:00 [OceanBase] ob_cluster=lg_ob_cluster_01:host=3.xx.xx.xx:server_type=observer:ob_error_code=5226 OCP告警通知-多条告警 - 名称：ob_log_alarm:OB日志告警 - 级别：严重 - 告警数量：1 - 聚合分组：ob_log_alarm:5226:lg_ob_cluster_01 - 告警对象：ob_cluster=lg_ob_cluster_01:host=3.xx.xx.xx:server_type=observer:ob_error_code=5226 生成时间：2023-02-14T06:56:01+08:00 概述：[OB日志告警] ob_cluster=lg_ob_cluster_01:host=3.xx.xx.xx:server_type=observer:ob_error_code=5226 详情：集群：lg_ob_cluster_01 主机：3.xx.xx.xx 日志类型：observer 错误码：5226 TraceId：YB42030E5A0C-0005F3BADFD974E4-0-0 日志名称：OB_REACH_MEMORY_LIMIT 日志级别：error 日志详情：[2023-02-14 13:37:57.260504] ERROR [SQL.PC] add_plan (ob_plan_cache.cpp:793) [7777][0][YB42030E5A0C-0005F3BADFD974E4-0-0] [lt=11] [dc=0] plan cache memory used reach limit(tenant_id=1002, get_mem_hold()=859832320, get_mem_limit()=858993455, ret=-5226) BACKTRACE:0xf729d8f 0x53a274f 0x54fa56e 0x53d0eaf 0x54fa2dc 0x5510fde 0xc10fb90 0xc10f771 0xe4ca42b 0x

```

## 问题原因

当前系统中大量执行无法重用 Plan 的 SQL，导致同一条 SQL_ID 下存在很多不同的 PLAN_ID。如果 SQL 的执行计划占用的内存较多，比如 30M，一个 SQL_ID 可能会使用的 Plan Cache 内存接近 600M。

当前的设计是，一个 SQL_ID 下最多可以有 200 个 Plan。如果一个 SQL 无法重用执行计划，每次执行都要生成新的 Plan，那么当 SQL_ID 下有 200个 Plan 后，新的 Plan 无法加入到 Plan Cache 中，Plan Cache 也无法进行淘汰，此后每次 SQL 执行都是硬解析。

目前，我们发现有两类 SQL 会导致该问题。

- 使用 `SELECT FROM DUAL` 的 UNION：可能会在不同位置执行，因而不能共用 plan。

  ```shell
  obclient> insert into tab_lh (c1,c2,c3) select 1,'a','b' from dual  union all select 1,'c','d' from dual;

  ```

  ```shell
  obclient> insert into tab_lh (c1,c2,c3) select 1,'a','' from dual  union all select 1,'a','b' from dual;

  ```

  ```shell
  obclient> insert into tab_lh (c1,c2,c3) select 1,'a','b' from dual  union all select 1,'','d' from dual;

  ```

  ```shell
  obclient> insert into tab_lh (c1,c2,c3) select 1,'a','b' from dual  union all select 1,'','' from dual;

  ```
 - 使用 IFNULL 的 SQL：当 `IFNULL(?, ?)` 出现在不同的列时不能共用 plan， `IFNULL(0, 0)` 和 `IFNULL(null, 0)` 也不能共用 plan。

  ```shell
  obclient> select 1, IFNULL(0, 0) from dual;

  ```

  ```shell
  obclient> select 1, IFNULL(null, 0) from dual;

  ```

## 解决方法

目前，遇到此类问题的应急处理流程如下。

1. 增加租户内存或者调整参数 `ob_plan_cache_percentage`。

   ```shell
   obclient> set global ob_plan_cache_percentage=xx;

   ```
 2. 手工淘汰指定租户的 sql_id。

   ```shell
   obclient> alter system flush plan cache sql_id='xxx' tenant='xxx' global;

   ```
 3. 给这些 SQL 使用如下 HINT。

   ```
   /*+USE_PLAN_CACHE(NONE)*/`

   ```

上一篇

[如何确定 Plan Cache 的淘汰机制是否正常](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000366643)

下一篇

[add_plan 报错： -5226 plan cache memory used reach limit](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000209936) ![有帮助](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) 咨询热线
