基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
租户内存不足导致 allocate memory fail
更新时间:2026-08-25 02:41
问题现象
在 1+1+1 架构的 OceanBase 集群(版本 3.2.4.7-107000012023113010)中,一个规格为 16C120G 的租户持续告警 allocate memory fail。
OCP 监控显示该租户的内存使用率已接近 100%。
告警信息中,SQL 执行报错 ret=-4013,错误信息为 ALLOCATE MEMORY FAILED。
问题原因
SQL Work Area 可用内存不足,导致排序(Sort)算子无法分配足够的排序缓冲区,从而引发 -4013 错误。
关键信息
内存分配失败日志
日志显示内存分配失败的直接原因是 WORK_AREA 上下文内存已打满。
[2026-03-10 08:20:49.647990] WDIAG ob_tenant_ctx_allocator.h:154 [28161][0][YB420AFC0121-00060D26856D1D93-0-0] [lt=8] [dc=0][errcode=-4013]
[OOPS] alloc failed reason: ctx memory has reached the upper limit
(ctx_name: WORK_AREA, ctx_hold: 6440353792, ctx_limit: 6442450940, alloc_size: 2097152)
[2026-03-10 08:20:49.648022] WDIAG ob_tenant_ctx_allocator.h:159 [28161][0][YB420AFC0121-00060D26856D1D93-0-0] [lt=28] [dc=0][errcode=-4013]
oops, alloc failed, tenant_id=1007, ctx_id=24, ctx_name=WORK_AREA,
ctx_hold=6440353792, ctx_limit=6442450940,
tenant_hold=121305563136, tenant_limit=128849018880
日志关键字段说明:
ctx_name: WORK_AREA:SQL 工作区内存上下文。ctx_hold: 6,440,353,792 ≈ 6.0 GB:当前已持有的 WORK_AREA 内存。ctx_limit: 6,442,450,940 ≈ 6.0 GB:WORK_AREA 内存上限。alloc_size: 2,097,152 = 2 MB:本次申请的内存大小。tenant_hold: 121,305,563,136 ≈ 113 GB:租户当前持有的总内存。tenant_limit: 128,849,018,880 = 120 GB:租户的总内存上限。
经确认,该租户的 sql_work_area_percentage 参数为默认值 5%。
ctx_id 对应值
| ctx_id | ctx_name | 对应模块 | 内存比例/说明 |
|---|---|---|---|
| 0 | DEFAULT_CTX_ID |
默认/通用内存 | 无特定限制,共享剩余空间。系统租户(500)为 2GB,其余租户为 50MB。 |
| 1 | DO_NOT_USE_ME |
保留位 | 占位,不实际使用。 |
| 2 | MEMSTORE_CTX_ID |
MemStore 写缓存 | 受 memstore_limit_percentage 控制(默认小租户 40%,大租户 50%)。 |
| 3 | EXECUTE_CTX_ID |
SQL 执行上下文 | SQL 执行器(ExecContext、DML、DAS、PX 交互结果等)。 |
| 4 | TRANS_CTX_MGR_ID |
事务上下文管理器 | 事务管理相关内存。 |
| 5 | PLAN_CACHE_CTX_ID |
Plan Cache 执行计划缓存 | 并行度。 |
| 6 | WORK_AREA |
SQL 工作区 | 受 ob_sql_work_area_percentage 控制(默认 5%),用于 Sort/Hash/Aggregate 算子内存。 |
| 7 | GLIBC |
GLIBC 内存 | C 标准库 malloc 分配,不受租户内存限制。 |
| 8 | CO_STACK |
协程栈 | 用户态协程执行栈内存。 |
| 9 | LIBEASY |
RPC 网络框架 | 并行度设为 32,启用 dirty list。 |
| 10 | LOGGER_CTX_ID |
日志模块 | 并行度设为 4,启用 dirty list + no log。 |
| 11 | KVSTORE_CACHE_ID |
KV Cache 存储 | Block Cache、Row Cache、Schema Cache 等,是最大内存消费者,可被 Wash。 |
| 12 | META_OBJ_CTX_ID |
元数据对象池 | Tablet Pool 等元数据对象,受 _storage_meta_memory_limit_percentage 控制。 |
| 13 | TX_CALLBACK_CTX_ID |
事务回调 | MemTable 写回调(trans callback)。 |
| 14 | LOB_CTX_ID |
LOB 大对象 | LOB 持久化适配器。 |
| 15 | PS_CACHE_CTX_ID |
Prepare Statement Cache | PS 缓存。 |
| 16 | RPC_CTX_ID |
RPC 通信 | RPC 请求/响应内存。 |
| 17 | PKT_NIO |
SQL NIO 网络 | MySQL 协议包网络 IO。 |
| 18 | TX_DATA_TABLE |
事务数据表 | Tx Data MemTable,受 _tx_data_memory_limit_percentage 控制。 |
| 19 | STORAGE_LONG_TERM_META_CTX_ID |
存储长期元数据 | 长期驻留的存储元数据。 |
| 20 | MDS_DATA_ID |
MDS 数据 | Multi-Data-Source 数据(MDS Table、TX OP),受 _mds_memory_limit_percentage 控制。 |
| 21 | MDS_CTX_ID |
MDS 上下文 | MDS Buffer Context。 |
| 22 | SCHEMA_SERVICE |
Schema 服务 | 权限管理、Schema 缓存等,使用 500 租户内存。 |
| 23 | UNEXPECTED_IN_500 |
500 租户异常 | 预留给系统租户的异常内存。 |
| 24 | MERGE_RESERVE_CTX_ID |
Mini Merge 预留 | Mini Compaction 专用,禁止同步 Wash,保证合并不被内存回收打断。 |
| 25 | MERGE_NORMAL_CTX_ID |
普通 Merge | 非 Mini 的合并操作。 |
| 26 | VECTOR_CTX_ID |
向量索引 | 向量索引(Vector Index)内存,受 vector_mem_limit_percentage 控制。 |
Cache Wash 日志
在 08:17:46 至 08:23:38 期间,系统在 6 分钟内对租户 1007 执行了 642 次 Wash memory 操作,但每次仅能释放极少量内存。
[2026-03-10 08:17:46.321184] INFO [COMMON] ob_kvcache_store.cpp:321
Wash memory, (tenant_id=1007, cache_size=92651220288,
lower_mem_limit=128849018880, upper_mem_limit=128849018880,
min_wash_size=4688847, max_wash_size=4688847,
mem_usage=121188122624, reserve_mem=12884901888, wash_size=4688847)
[2026-03-10 08:17:50.339112] INFO [COMMON] ob_kvcache_store.cpp:321
Wash memory, (tenant_id=1007, cache_size=92569434816,
lower_mem_limit=128849018880, upper_mem_limit=128849018880,
min_wash_size=4688847, max_wash_size=4688847,
mem_usage=121188122624, reserve_mem=12884901888, wash_size=4688847)
日志关键字段解读:
cache_size ≈ 86.0 GB:Cache 占用量。lower_mem_limit= 120 GB:租户规格下限。upper_mem_limit= 120 GB:租户规格上限。mem_usage= 112.8GB:当前总内存持有量。reserve_mem = 12 GB:预留内存。wash_size ≈ 4~13 MB:每次 Wash 仅释放几 MB,效果甚微。
在以下两种情况下会触发 Cache Wash:
- 定时任务(每 200ms 一次)。
- SQL 算子申请内存失败时,会同步触发 Wash 尝试回收内存。
问题分析
- SQL 报 allocate memory fail 的原因是什么?
Sort 算子申请内存失败(ret=-4013)。 - Sort 算子为何申请不到内存?
WORK_AREA 内存上下文已达到上限(ctx_hold: 6,440,353,792 ≈ ctx_limit: 6,442,450,940)。
问题的风险及影响
无。
适用版本
OceanBase 数据库 3.x 版本。
解决方法
临时增大 SQL Work Area 比例
通过调整 sql_work_area_percentage 参数,临时增加 SQL 工作区的内存占比(默认 5%)。
ALTER SYSTEM SET sql_work_area_percentage = 10 TENANT = 1007;
扩容租户
通过修改资源单元(Resource Unit)配置,增加租户的 CPU 和内存规格。
ALTER RESOURCE UNIT config_ob_ora_pay_zone3_U16C120G_dnn
MAX_CPU = 24, MIN_CPU = 24,
MAX_MEMORY = '180G', MIN_MEMORY = '180G';
规避方式
无。