DBAtlas · 数据库运维图谱

内存压力 / OOM

症状

OOM killer 终止进程,出现 'out of memory'、缓存命中率低、过度 swap,Redis 报 'OOM command not allowed'。

1. 谁在消耗内存

是数据库分配的内存(buffer pool/SGA)、每个会话的内存(PGA/sort/work_mem),还是整个操作系统?在操作系统层面检查 free/vmstat,并在数据库内查看内存相关视图。

Oracle

SELECT component, current_size/1048576 mb FROM v$memory_dynamic_components WHERE current_size>0;

PostgreSQL

SHOW shared_buffers; SHOW work_mem; -- work_mem * connections * number of sorts can blow up in total

MySQL

SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW STATUS LIKE 'Innodb_buffer_pool%';

Redis

INFO memory  # used_memory, maxmemory, mem_fragmentation_ratio

2. 区分配置问题与负载问题

内存设置的总和是否超过物理 RAM(过度分配)?计算 shared_buffers + (work_mem * 并发数)。还是只是瞬时负载(巨大的排序/哈希、大量连接)?

3. Redis 特有:淘汰与碎片

若 used_memory 已达到 maxmemory,检查 maxmemory-policy(使用 noeviction 时写入会被拒绝)。若 mem_fragmentation_ratio 很高,使用 MEMORY PURGE / activedefrag。用 --bigkeys 找出大键。

Redis

CONFIG GET maxmemory-policy
MEMORY DOCTOR
redis-cli --bigkeys

4. 立即缓解

终止吞噬内存的失控查询/会话,临时调低 work_mem 等会话内存,断开不必要的连接。若系统正在 swap,首要任务是摆脱 swap。

5. 正确规划容量

使用 Tools > Memory/Buffer Pool 计算器合理分配 RAM。一般规则:在专用服务器上,buffer pool/SGA 约为 RAM 的 70-80%;会话内存总量乘以并发数,不得超过 RAM。必要时增加 RAM。

在 DBAtlas 中打开 →