En tjeneste som hadde gått lenge, med aktive sesjoner, forsvant plutselig midt i drift. Applikasjonen hadde ikke krasjet, det lå ingen feil i mine egne logger. Prosessen var rett og slett borte. Sånt lukter minnepress og kjernens OOM-håndtering lang vei, så det var der jeg begynte å lete.
Bekreft årsaken i loggen

Ikke gjett. Sjekk om det faktisk var systemd-oomd som tok prosessen. Under minnepress går oomd gjennom cgroupene og dreper der presset er høyest, helt uavhengig av om kjernens gamle OOM-killer har rukket å slå til.
journalctl -k --grep "Out of memory|oom-kill"
journalctl -u systemd-oomd --since "-1h"
systemctl status systemd-oomd
Ser du meldinger fra systemd-oomd om at en cgroup ble drept, eller Killed process i kjerneloggen, så har du svaret. Da kan du gjøre noe presist, i stedet for å skru på grenser i blinde og håpe.
Feil fiks: bare heve grenser
Det fristende er å doble MemoryMax eller skru av swap-oppførselen. Men det flytter bare problemet et hakk lenger frem. Under ekte press må noe fortsatt vike, og uten instruksjon plukker oomd selv. Poenget er ikke å kaste mer minne på det. Poenget er å fortelle systemet hvilke prosesser som kan ofres, og hvilke som absolutt ikke kan det.
Riktig fiks: marker hva som må overleve

systemd lar deg sette en preferanse per unit. ManagedOOMPreference=avoid ber oomd om å nedprioritere akkurat denne cgroupen når et offer skal velges. Sett den på unit-en som holder de langvarige sesjonene, den du helst vil ha i fred.
[Service]
ManagedOOMPreference=avoid
Legg det i en drop-in, så overlever det når pakken oppgraderes.
systemctl edit min-tjeneste.service
# i editoren:
[Service]
ManagedOOMPreference=avoid
systemctl daemon-reload
systemctl restart min-tjeneste.service
Sjekk så at preferansen faktisk ble lest inn.
systemctl show min-tjeneste.service -p ManagedOOMPreference
Motsatt vei kan du sette ManagedOOMPreference=omit på batch-jobber og annet som gjerne kan ryke først. Da gir du kjernen og oomd nok å gå på til å velge et fornuftig offer, i stedet for å ta det på slump.
Par det med auto-resume
En preferanse er ingen garanti. Blir alt minnet spist opp, ryker det noe uansett. Derfor må du sørge for at tjenesten kommer tilbake på egen hånd.
[Service]
Restart=always
RestartSec=5
[Unit]
StartLimitIntervalSec=0
Har tjenesten sesjonstilstand som må hentes tilbake, la den lese tilstanden fra disk ved oppstart, slik at aktive sesjoner plukkes opp igjen etter en restart.
Oppsummert
- Bekreft i
journalctlat det virkelig var oomd, og ikke applikasjonen selv. - Marker eksplisitt hva som må overleve, med
ManagedOOMPreference=avoid. - Merk de ofrbare prosessene med
omit, så oomd har et bedre offer for hånden. - Par det med
Restart=alwaysog gjenoppretting av tilstand.
Å skille det som kan ofres fra det som ikke kan det, er hele poenget her. Grenser alene løser det ikke.



