DBAtlas · 데이터베이스 운영 아틀라스

메모리 압박 / OOM

증상

OOM killer가 프로세스를 종료하고, 'out of memory', 낮은 cache hit ratio, 과도한 swap, Redis 'OOM command not allowed'가 발생한다.

1. 누가 메모리를 소비하는가

DB에 할당된 메모리(buffer pool/SGA)인가, 세션별 메모리(PGA/sort/work_mem)인가, OS 전체인가? OS 수준에서는 free/vmstat으로, DB 내부에서는 메모리 뷰로 확인한다.

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을 초과하는가(over-commit)? shared_buffers + (work_mem * 동시성)을 계산한다. 아니면 일시적인 부하(거대한 sort/hash, 많은 연결)인가?

3. Redis 특유: eviction과 단편화

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에서 열기 →