systemd-oomd drepte langvarige sesjoner: ManagedOOMPreference=avoid og automatisk omstart

En langvarig tjeneste med aktive sesjoner forsvant midt i drift. Applikasjonen hadde ikke krasjet, og mine egne logger viste ingen feil. Prosessen var borte. Det tyder på minnepress og OOM-håndtering, så det var der jeg begynte å lete.

Bekreft årsaken i loggen

Skjematisk diagram: systemd-oomd overvåker flere cgroups under minnepress og velger den med høyest press som drapsoffer

Sjekk først om det var systemd-oomd som drepte prosessen. Under minnepress går oomd gjennom cgroupene og dreper der presset er høyest, uavhengig av om kjernens OOM-killer har slått til.

journalctl -k --grep "Out of memory|oom-kill"
journalctl -u systemd-oomd --since "-1h"
systemctl status systemd-oomd
Meldinger fra systemd-oomd om at en cgroup ble drept, eller Killed process i kjerneloggen, bekrefter årsaken. Da kan du rette det presist i stedet for å endre grenser i blinde.

Høyere grenser flytter bare problemet

Å doble MemoryMax eller skru av swap-oppførselen utsetter problemet. Under ekte minnepress må noe fortsatt drepes, og uten instruksjon velger oomd selv. Det som løser det, er å fortelle systemd hvilke prosesser som kan ofres og hvilke som ikke kan det.

Marker hva som må overleve

Skjematisk flytdiagram: ManagedOOMPreference avoid, omit og standard styrer hvilken cgroup oomd velger som offer

systemd har en OOM-preferanse per unit. ManagedOOMPreference=avoid ber oomd nedprioritere denne cgroupen når et offer skal velges. Sett den på unit-en som holder de langvarige sesjonene.

[Service]
ManagedOOMPreference=avoid
Legg det i en drop-in, så overlever innstillingen pakkeoppgraderinger.

systemctl edit min-tjeneste.service
# i editoren:
[Service]
ManagedOOMPreference=avoid

systemctl daemon-reload
systemctl restart min-tjeneste.service
Sjekk at preferansen ble lest inn:

systemctl show min-tjeneste.service -p ManagedOOMPreferenceMotsatt kan du sette ManagedOOMPreference=omit på batch-jobber og annet som kan ryke først. Da har oomd et bedre offer å velge enn et tilfeldig.

Kombiner med automatisk omstart

Preferansen er ingen garanti. Går minnet helt tomt, drepes noe uansett, så tjenesten må starte igjen av seg selv.

[Service]
Restart=always
RestartSec=5

[Unit]
StartLimitIntervalSec=0
Har tjenesten sesjonstilstand, la den lese tilstanden fra disk ved oppstart, så aktive sesjoner tas opp igjen etter omstarten.