DBAtlas · 数据库运维图谱

内存压力 / OOM

服务器内存即将耗尽、系统正在 swap,或 OOM killer 已触发。先确定是谁在消耗内存:已分配内存(buffer pool/SGA)、会话内存(work_mem/PGA)、整个操作系统,还是 Redis 特有的情况?

是谁在消耗内存?

按层次区分内存压力的来源。是已分配(固定)内存过大、每会话内存暴涨、非数据库进程在占用,还是 Redis 自身的内存管理在起作用?

SELECT component, ROUND(current_size/1024/1024) AS mb FROM v$memory_dynamic_components WHERE current_size>0 ORDER BY current_size DESC;
  • 已分配内存(buffer pool / SGA)占主导
  • 会话内存(work_mem / PGA)暴涨
  • 非数据库进程/整个操作系统
  • Redis 特有(maxmemory / 淘汰 / 碎片)

配置的内存总量是否超过物理内存?

若固定分配的内存很大,有两种可能:要么配置总量(buffer pool + 会话 + 操作系统)超过物理内存(过量分配),要么大小合理但缓存命中率仍然很低。把各项设置加起来与物理内存比较。

SHOW PARAMETER sga_target;  SHOW PARAMETER pga_aggregate_target;
SELECT ROUND(value/1024/1024/1024,1) AS host_ram_gb FROM v$osstat WHERE stat_name='PHYSICAL_MEMORY_BYTES';
  • 是的,配置总量超过了物理内存(过量分配)
  • 没有,大小合理但缓存命中率低

根本原因:内存过量分配

buffer pool/SGA + 会话内存 + 操作系统需求之和超过了物理内存。系统正在 swap,或 OOM killer 正在终止进程。

根本原因:缓存不足(缓存命中率低)

已分配内存未超过物理内存,但相对于工作集偏小;buffer cache 命中率低,数据库不断从磁盘读取。

根本原因:会话内存暴涨

work_mem/PGA 等每会话内存乘以高并发,耗尽了物理内存。每个排序/哈希操作都可能单独分配这部分内存。

根本原因:Redis 内存管理

在 Redis 中,used_memory 已达到 maxmemory、淘汰正在进行,或碎片率过高(used_memory_rss >> used_memory)。需要处理淘汰策略和碎片问题。

根本原因:非数据库的内存消耗

内存不是被数据库消耗的,而是被整个操作系统或相邻进程消耗:其他应用、文件系统缓存压力或存在内存泄漏的辅助进程。

在 DBAtlas 中打开 →