执行内存占用高问题经常在不同环境中遇到, 在内存较大的租户场景下, 问题可能暴露不明显, 但小规格场景下, 如果执行内存占用非常高, 往往有上 G 甚至几十G 的情况, 可能导致整个租户无内存使用。本文汇总执行内存占用高问题。
获取内存高的 mod 的代码 backtrace 方式
对于执行内存占用高的问题,可以使用常态化 memory leak 诊断工具 获取代码 backtrace。一般通过以下步骤可以获取到占用内存高的代码堆栈,具体方法如下。
执行内存占用高的问题
SqlExecContext 模块
问题描述
repeat
,space
等表达式向量化场景 SqlExecContext
模块内存膨胀到 10+g。
问题原因
repeat
,space
的结果内存大小不可控,且结果长度很大时仍使用的 varchar 类型存储,在向量化场景会进一步放大内存使用,导致内存很高。
问题诊断
解决方法
OceanBase 数据库 V4.2 版本缓解,V4.3 版本彻底解决。
multi table replace 算子模块
问题描述
SQL_EXEC_CTX_ID
内存膨胀至 190G,租户内存爆。
问题原因
OceanBase 数据库 V3.x 版本的 multi_part_xxx 计划因为未作多批次写入流程,所有的数据都会被 load 在本地,所以当数据量很大的时候,会发生严重的内存膨胀。
问题诊断
解决方法
OceanBase 数据库 V3.2.3 版本之前存在但不是很明显,V3.2.3 及之后版本, 开向量化时该场景内存使用会明显增加,注意 V3.2.3 版本尚未解决。
聚合函数的参数含 distinct 模块
问题描述
distinct aggration + 向量化场景下内存占用高问题。
问题原因
向量化中会维护 256 组聚合,每组都会用 sort 做去重,导致这里用内存太多。
问题诊断
解决方法
OceanBase 数据库 V4.2 版本缓解,V4.3 版本彻底解决。
SqlExecutor 模块
问题描述
batch insert 场景内存使用高。
问题原因
insert values 类型 SQL 后跟多行数据时,硬解析时,内存膨胀,另外行数不固定,可能导致不能命中 plan_cache,出现并发硬解析时,同时占用内存就很大。
问题诊断
执行语句为 batch insert,比如 insert into ... values(...), (...), (...) ... ...
。
解决方法
OceanBase 数据库 V4.0 版本已进行优化,默认关闭,还存在 bad case,而在 V4.3 版本会默认打开优化。优化打开命令。
ALTER SYSTEM SET ob_enable_batched_multi_statement = true;
SqlExecutor/CostBasedRewrite 模块
问题描述
in 个数或 or 很多时, query range 抽取内存占用高。
问题原因
抽取 query range 时,反复深拷导致内存占用高。
问题诊断
解决方法
OceanBase 数据库 V4.2 版本解决。
SqlWindoRowStor 模块
问题描述
window function 中,存在某个组数据很多情况场景, 内存占用高。
问题原因
window function 未接入自动内存管理,当前落盘阈值太高。
问题诊断
解决方法
OceanBase 数据库 V4.2 版本解决。
SqlAggrFunGroCo 模块
问题描述
groupconcat aggregate + 向量化场景, 内存占用高问题。
问题原因
groupconcat aggregate 没接自动内存管理。
问题诊断
解决方法
OceanBase 数据库 V4.2 缓解,V4.3 彻底解决。
SqlCteRow 模块
问题描述
cte 场景, 可能存在内存占用高问题。
问题原因
数据量大、递归层次过高、无限递归场景,判环占用内存高。
问题诊断
解决方法
OceanBase 数据库 V3.2.3 版本之前存在但不是很明显,V3.2.3 及之后版本,开向量化时该场景内存使用会明显增加。
ConnectByPump 模块
问题描述
connect by 场景, 可能存在内存占用高问题。
问题原因
递归层次过高时保留 pump node 用于判环, 导致内存占用高。
问题诊断
解决方法
OceanBase 数据库所有活跃版本均存在该问题。
MysqlRequesReco 模块
问题描述
sql audit queue
内存小规格占用 80M 问题。
问题原因
因为当前 sql audit
内部使用的循环 buffer,默认使用的 1000w 个槽位, 不支持动态调整,固定占用 80+M。
问题诊断
这个 mod 名称 ·MysqlRequesReco·, 表示 sql audit
消耗内存, 可以先通过 SQL 语句 select svr_ip, svr_port, count(*) from gv$ob_sql_audit group by svr_ip, svr_port
查看 sql audit
中的执行记录信息。
解决方法
OceanBase 数据库 V4.3 版本解决。
DtlIntermRes 模块
问题描述
执行分布式计划时内存占用高。
问题原因
停流量后,内存占用仍然很大:中间结果泄漏;停流量后,内存占用降到很低(执行一些分布式 inner sql ):流量大导致写入大量中间结果。
解决方法
OceanBase 数据库 V4.2 版本已修复,V4.3 版本解决,实施中间结果的自动内存管理。
ObSQLSessionInf 模块
问题描述
大量 session 建连场景,内存占用过高,长时间未释放。
问题原因
session_pool hold
住内存,当前设计不存在释放相应内存。
解决方法
在 OceanBase 数据库 V4.x 版本中添加开关,关闭 session pool。
WindowAggProc 模块
问题描述
WindowAggProc
内存膨胀 5G+;400k 的查询首次执行爆内存,再次执行成功。
问题原因
WM_CONCAT
内存使用过于粗放,数据全部缓存在 arena 中,引发内存膨胀。
解决方法
OceanBase 数据库 V4.3 版本解决。
适用版本
OceanBase 数据库所有版本。




