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

- 简体中文
- English

划线反馈

# 4013 内存爆问题的排查

更新时间：2025-05-07 10:07

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

本文介绍 4013 内存爆问题的排查。

## 内存爆的类型

内存爆主要分为五类，可以通过关键词 `OOPS` 确定内存爆的类型。

| 内存爆的类型 | 日志信息（关键字为 [OOPS]） |
| --- | --- |
| SINGLE_ALLOC_SIZE_OVERFLOW | single alloc size large than 4G is not allowed(alloc_size: %ld) |
| CTX_HOLD_REACH_LIMIT | ctx memory has reached the upper limit(ctx_name: %s, ctx_hold: %ld, ctx_limit: %ld, alloc_size: %ld) |
| TENANT_HOLD_REACH_LIMIT | tenant memory has reached the upper limit(tenant_id: %lu, tenant_hold: %ld, tenant_limit: %ld, alloc_size: %ld) |
| SERVER_HOLD_REACH_LIMIT | server memory has reached the upper limit(server_hold: %ld, server_limit: %ld, alloc_size: %ld) |
| PHYSICAL_MEMORY_EXHAUST | physical memory exhausted(os_total: %ld, os_available: %ld, server_hold: %ld, errno: %d, alloc_size: %ld) |

可以在内存爆的时间点（比如 `20230730142424792`），搜索 `OOPS` 日志，确定属于哪个类型的内存爆。

```shell
grep '\[OOPS\]' observer.log.20230730142424792

```

## 租户内存爆

检查是否存在 `msg` 信息，表示特定租户的内存爆。

![yu688-68uty67y-7gy7768-hu8ut9](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory001.png)

此处 `msg` 表示 1008 租户的内存爆了，需要进一步查看该租户下哪个 `CTX_ID` 的占用偏高。

### 1.1 分析租户的内存元信息，确定高内存占用的 `CTX_ID`

1. 分析租户的内存元信息，确定高内存占用的 `CTX_ID`。

   通过关键词 `malloc_allocator.*tenant: 1008` 可以获取租户的内存元信息（`limit`、`hold`、`cache_hold`），-A 可以显示更多的内存元信息的细节，包括该租户下各 CTX 的内存占用，以及租户线程的 PM 信息。

   ![78yh60-ju6967uy-78yh5oi8-79u6o89](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory002.png)

   上述内存元信息显示 `DEFAULT_CTX_ID`、`DEFAULT_CTX_ID`、`RPC_CTX_ID` 占用比较高，需要进一步分析这些 `CTX_ID` 下占用最高的几个内存模块。
 2. CTX 的内存元信息分析

   查找和分析 `DEFAULT_CTX_ID`、`DEFAULT_CTX_ID`、`RPC_CTX_ID` 的内存元信息。

   以 `DEFAULT_CTX_ID` 举例 。

   ![68u560-dre65tuy-67r9oi8-68y589](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory003.png)

   通过关键词 `1008 ctx_id= DEFAULT_CTX_ID` 可以获取 1008 租户的 `DEFAULT_CTX_ID` 的内存元信息（`hold`、`used`、`limit`、内存碎片清理信息），-A 可以显示该 `CTX_ID` 的各内存模块的内存占用。发现疑似导致内存爆的模块后，找模块 `owner` 进行最后的确定。

   `CTX_ID` 的内存元信息中 `used`与 `hold` 相差很大。

   ![686hty-uiy73tuy-ju32i8-cw7989](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013memory008.png)

   存在二种可能（内存碎片、MEMORY 日志统计延时），可以通过查看内存爆所在的多个时刻的 `CTX_ID` 的内存元信息确定。

   ![68hr0-78hg5uy-jky99oi8-6y8ho89](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory004.png)

      - 内存碎片。

       内存爆触发内存碎片清理机制，`washed_size` 会显著变大，`hold` 会减小到与 `used` 差不多大。
      - MEMORY 日志统计延时。

            - `washed_size` 变化幅度很小，可能会出现 `used` 大于 `hold` 的现象。一般是由内存快速膨胀导致的，需要找到内存膨胀模块。
            - 在内存爆所在时间段，搜索 `CTX_ID` 的 `used` 明显比较大的 MEMORY 日志，跟前后时刻的 MEMORY 日志进行比对，内存占用增幅最大的模块很可能就是内存膨胀模块。

             ![0ry40-f25ds9iuy-546g9oi8-byr43t89](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory005.png)
            - 如果找不到 `used` 较大的 MEMROY 日志，需要等待复现（用脚本定时打印该 `CTX_ID` 中占用最高的几个内存模块，并且输出 `alloc_bytes` 最大的堆栈。

   当无明显占用较大的内存模块的情况

      - 确定占用最高的几个内存模块是否有已知内存问题未修复。
      - 占用最高的几个内存模块，是否有陌生的模块。

   有明显占用较大的内存模块。

   直接锁定占用最高的内存模块。
 3. kvcache 内存异常。

未发现占用较大的 `CTX_ID`，并且租户的大部分内存都是 kvcache，说明租户内存不足时挤占 kvcache 的内存失败了，需要确定失败的原因。

1. 搜索关键词 `T1008.*tenant sync wash failed, cache memblock info`，其中 `ref_count` 不为 2 表示这块内存被应用层 hold 住了，`status` 不为 2 表示这块内存正在被 cache 使用。如果存在 `ref_count` 和 `status` 都为 2 的内存，则说明存在 bug，需要存储方面的分析。

   ![57fq30-ug56asy-t6ewi8-g68s9](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory006.png)
 2. 搜索关键词 `tenant_id.*1008 cache memory info`，发现 `cache_size` 占用最大的模块，找 owner 分析占用是否符合预期。

   ![gr5a8u0-gh789iuy-hu6sei8-5h0549](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/202402224013Memory007.png)

## OBServer 内存爆

- 一般是500租户超卖导致的，可以先获取 500 租户的内存元信息，按照 **租户内存爆** 这一节的步骤来确定导致 OBServer 内存爆的模块。
 - 搜索关键词 `CHUNK_MGR`，确定 OBServer 是否存在大量缓存，若存在大量缓存则可能是 OBServer 缓存未设上限，导致 OBServer hold 的内存接近 `memory_limit`，此时申请大于 4M 的内存会失败。可以通过设置配置项 `memory_chunk_cache_size` 释放缓存。
 - 500 租户的内存占用符合预期，查看全部业务租户的内存元信息。

     - 全部业务租户的总 `limit` 超过了 `memory_limit - system_memory`，很可能是租户扩缩容时存在 BUG，或者其他问题。
     - 全部业务租户的总 `limit` 符合预期，可能是业务租户的规格设置过大，可以适当调小快速恢复业务。

## CTX_ID 内存爆

按照 **CTX 的内存元信息分析** 这一节的步骤来确定导致 OBServer 内存爆的模块。

## 物理内存耗尽

常见原因是超卖机器的物理内存，一台机器上部署多个 OBServer，或者 OBServer 的 `memory_limit` 接近机器的物理内存。可以结合 `tsar --mem` 在内存爆时刻的日志进行验证。

## 无 OOPS 日志

- 通过 `CHUNK_MGR` 日志确定是否是 OBServer 内存爆，若是 OBServer 内存爆则按照 **OBServer 内存爆** 这一节来排查问题。
 - 通过全部租户的内存元信息确定是否是租户内存爆，若是，则按照 **租户内存爆** 这一节来排查问题。

## 适用版本

OceanBase 数据库所有版本。

Previous

[CTE temp table 数据量超过 90W 时发生 500 租户 ObSEArray 内存泄漏问题](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003098734)

Next

[机器可用内存不足导致 SQL 一直卡住重试 retry_info 显示 -4121](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002398326) ![有帮助](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) 咨询热线
