内存压力 / 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)。需要处理淘汰策略和碎片问题。
根本原因:非数据库的内存消耗
内存不是被数据库消耗的,而是被整个操作系统或相邻进程消耗:其他应用、文件系统缓存压力或存在内存泄漏的辅助进程。