内存压力 / 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 totalMySQL
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW STATUS LIKE 'Innodb_buffer_pool%';Redis
INFO memory # used_memory, maxmemory, mem_fragmentation_ratio2. 区分配置问题与负载问题
内存设置的总和是否超过物理 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 --bigkeys4. 立即缓解
终止吞噬内存的失控查询/会话,临时调低 work_mem 等会话内存,断开不必要的连接。若系统正在 swap,首要任务是摆脱 swap。
5. 正确规划容量
使用 Tools > Memory/Buffer Pool 计算器合理分配 RAM。一般规则:在专用服务器上,buffer pool/SGA 约为 RAM 的 70-80%;会话内存总量乘以并发数,不得超过 RAM。必要时增加 RAM。