본문으로 건너뛰기

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.events의 high, 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를 재현하는 실험이 필요합니다.