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 변경과 배포를 시간순으로 복원합니다.
예방 기준
- 정상 peak의 working set과 page cache를 측정합니다.
- PostgreSQL shared memory와 backend private memory를 분리합니다.
memory.high경고와 PSI alert로 kill 이전을 관측합니다.oom_score_adj변경은 다른 핵심 process로 피해를 옮길 수 있으므로 신중히 사용합니다.
Huge page와 overcommit 설정은 allocation 실패의 형태를 바꿀 수 있습니다. 변경 전 kernel과 PostgreSQL version, workload를 재현하는 실험이 필요합니다.