본문으로 건너뛰기

3.3 OOM과 cgroup memory

OOM은 host 전체 memory가 부족한 global OOM과 cgroup limit을 넘은 memcg OOM으로 나눠 봅니다. Kubernetes Pod가 OOMKilled여도 node 전체에는 여유 memory가 있을 수 있습니다.

journalctl -k --since '-30 min' | grep -Ei 'oom|out of memory|killed process'
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.events
cat /sys/fs/cgroup/memory.pressure

memory.eventshigh, max, oom, oom_kill 증분을 봅니다. memory.high는 throttling과 reclaim을 유도하고 memory.max는 hard limit입니다.

PostgreSQL process가 선택됐을 때

Postmaster 또는 backend가 종료됐는지, database가 crash recovery를 수행했는지 확인합니다.

systemctl status postgresql
journalctl -u postgresql --since '-30 min'

OOM 이후 자동 재시작만 확인하고 끝내면 같은 workload가 재발시킵니다. 당시 query, connection 수, autovacuum과 backup, container limit 변경과 배포를 시간순으로 복원합니다.

예방 기준

  1. 정상 peak의 working set과 page cache를 측정합니다.
  2. PostgreSQL shared memory와 backend private memory를 분리합니다.
  3. memory.high 경고와 PSI alert로 kill 이전을 관측합니다.
  4. oom_score_adj 변경은 다른 핵심 process로 피해를 옮길 수 있으므로 신중히 사용합니다.

Huge page와 overcommit 설정은 allocation 실패의 형태를 바꿀 수 있습니다. 변경 전 kernel과 PostgreSQL version, workload를 재현하는 실험이 필요합니다.