
Wanneer een Linux-database server onverwacht stopt, moet je de oorzaak vinden. Er kunnen verschillende redenen zijn. Bijvoorbeeld, SIGSEGV — een fout door een bug in de backend-server. Maar dat is zeldzaam. Meestal is de beschikbare schijfruimte of het geheugen gewoon op. Als de schijfruimte op is, is er maar één oplossing: ruimte vrijmaken en de database opnieuw opstarten.
Out-Of-Memory Killer
Wanneer de de server of een proces geen geheugen meer heeft, biedt Linux 2 oplossingsrichtingen: ofwel het hele systeem laten crashen of de applicatie beëindigen die te veel geheugen gebruikt. Het is natuurlijk beter om het proces te beëindigen en het besturingssysteem te redden van een noodstop. In het kort, de Out-Of-Memory Killer is een proces dat een applicatie beëindigt om de kernel te beschermen tegen een crash. Het offert de applicatie op om de werking van het besturingssysteem te waarborgen. Laten we eerst bespreken hoe OOM werkt en hoe je het kunt beheersen, en daarna bekijken we hoe OOM Killer beslist welke applicatie beëindigd moet worden.
Een van de hoofdtaken van Linux is om geheugen toe te wijzen aan processen wanneer ze daarom vragen. Gewoonlijk vraagt een proces of applicatie om geheugen van het besturingssysteem, maar gebruikt het dit niet volledig. Als het besturingssysteem geheugen toekent aan iedereen die erom vraagt, maar het niet van plan is te gebruiken, zal het geheugen snel op zijn en de systeemdiensten falen. Om dit te voorkomen, reserveert het besturingssysteem geheugen voor het proces, maar geeft dit niet daadwerkelijk uit. Het geheugen wordt pas toegewezen wanneer het proces het echt nodig heeft. Het kan gebeuren dat er geen vrij geheugen beschikbaar is, maar het besturingssysteem het al heeft gereserveerd voor een proces, en wanneer dat proces het nodig heeft, wordt het geheugen toegewezen, indien mogelijk. Het nadeel is dat het besturingssysteem soms geheugen reserveert, maar op dat moment geen vrij geheugen heeft en er een systeemcrash optreedt. OOM speelt een belangrijke rol in dit scenario en beëindigt processen om de kernel te beschermen tegen paniek. Wanneer een PostgreSQL-proces geforceerd wordt beëindigd, verschijnt de volgende boodschap in de log:
Out of Memory: Killed process 12345 (postgres).Als er weinig geheugen in het systeem beschikbaar is en het niet mogelijk is om het vrij te maken, wordt de functie out_of_memoryOp dit moment blijft er nog maar één ding over — één of meerdere processen beëindigen. Moet de OOM-killer het proces onmiddellijk beëindigen of kan er gewacht worden? Het is duidelijk dat wanneer out_of_memory wordt aangeroepen, dit verband houdt met het wachten op een invoer- of uitvoerfunctie of het inwisselen van een pagina naar de schijf. Daarom moet de OOM-killer eerst controles uitvoeren en op basis daarvan beslissen welke processen moeten worden beëindigd. Als alle onderstaande controles positief zijn, zal OOM het proces beëindigen.
Proces selecteren
Wanneer het geheugen opraakt, wordt de functie aangeroepen out_of_memory(). Deze functie bevat select_bad_process(), die een beoordeling ontvangt van de functie badness(). Het slechtste proces wordt geselecteerd. De functie badness() selecteert een proces op basis van bepaalde regels.
- De kernel heeft een minimum aan geheugen nodig voor zichzelf.
- Er moet veel geheugen worden vrijgemaakt.
- Processen die weinig geheugen gebruiken, hoeven niet te worden beëindigd.
- Er moeten minimaal enkele processen worden beëindigd.
- Complexe algoritmen die de kans vergroten dat de processen worden beëindigd die de gebruiker zelf wil beëindigen.
Na het uitvoeren van al deze controles bestudeert OOM de score (oom_score). OOM wijst oom_score aan elk proces toe, en vermenigvuldigt deze waarde vervolgens met de hoeveelheid geheugen. Processen met hogere waarden hebben een grotere kans om slachtoffer te worden van de OOM-killer. Processen gerelateerd aan een geprivilegieerde gebruiker hebben een lagere score en minder kans om geforceerd te worden beëindigd.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)De proces-ID van Postgres is 3813, zodat je in een andere shell de score kunt ophalen met dit kernparameter oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Als je absoluut niet wilt dat de OOM-Killer het proces beëindigt, is er nog een kernparameter: oom_score_adj. Voeg een grote negatieve waarde toe om de kans op beëindiging van een belangrijk proces te verkleinen.
sudo echo -100 > /proc/3813/oom_score_adjOm een waarde in te stellen oom_score_adj, stel OOMScoreAdjust in het serviceblok in:
[Service]
OOMScoreAdjust=-1000Of gebruik oomprotect in het commando rcctl.
rcctl set servicenaam oomprotect -1000Geforceerd beëindigen van een proces
Wanneer een of meerdere processen al zijn geselecteerd, roept de OOM-Killer de functie aan oom_kill_task(). Deze functie stuurt een beëindigingssignaal naar het proces. In geval van geheugenstekort oom_kill() roept deze functie aan om het proces het SIGKILL-signaal te sturen. Een bericht wordt in de kernel-log opgeslagen.
Out of Memory: Proces [pid] [name] beëindigd.Hoe OOM-Killer te controleren
In Linux kan OOM-Killer in- en uitgeschakeld worden (hoewel het laatste niet wordt aanbevolen). Gebruik de parameter vm.oom-kill. Om OOM-Killer tijdens runtime in te schakelen, voert u de volgende opdracht uit , beschikbaar zijn voor.
sudo -s sysctl -w vm.oom-kill = 1Om OOM-Killer uit te schakelen, stelt u de waarde 0 in deze opdracht in:
sudo -s sysctl -w vm.oom-kill = 0De uitkomst van deze opdracht blijft niet permanent, maar slechts tot de eerstvolgende herstart. Voor meer permanentheid voegt u deze regel toe aan het bestand /etc/sysctl.conf:
echo vm.oom-kill = 1 >> /etc/sysctl.confEen andere manier om het in en uit te schakelen is door de variabele panic_on_oom. De waarde kan altijd gecontroleerd worden in /proc.
$ cat /proc/sys/vm/panic_on_oom
0Als u de waarde 0 instelt, zal er geen kernel panic optreden als het geheugen op is.
$ echo 0 > /proc/sys/vm/panic_on_oomAls u de waarde 1 instelt, zal er een kernel panic optreden als het geheugen op is.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer kan niet alleen in- en uitgeschakeld worden. We hebben al besproken dat Linux voor processen meer geheugen kan reserveren dan beschikbaar is, maar dit niet daadwerkelijk kan toekennen, en dit gedrag wordt beheerd door een kernelparameter. Dit wordt geregeld door variabele vm.overcommit_memory.
Hier kunnen de volgende waarden worden ingesteld:
0: de kernel beslist zelf of er teveel geheugen gereserveerd moet worden. Dit is de standaardinstelling in de meeste versies van Linux.
1: de kernel zal altijd extra geheugen reserveren. Dit is riskant, omdat het geheugen op kan raken, omdat processen waarschijnlijk ooit de toegewezen hoeveelheid zullen vragen.
2: de kernel zal niet meer geheugen reserveren dan is aangegeven in de parameter overcommit_ratio.
In deze parameter geef je het percentage geheugen aan waarvoor overmatige reservering is toegestaan. Als er geen ruimte voor is, wordt het geheugen niet toegewezen en wordt de reservering geweigerd. Dit is de veiligste optie, aanbevolen voor PostgreSQL. Een ander element dat invloed heeft op OOM-Killer is de swap mogelijkheid, die wordt beheerd door variabele cat /proc/sys/vm/swappiness. Deze waarden geven de kernel instructies over hoe om te gaan met paginauitwisseling. Hoe hoger de waarde, hoe kleiner de kans dat OOM het proces beëindigt, maar het heeft een negatieve invloed op de database vanwege invoer-/uitvoeractiviteiten. En omgekeerd: hoe lager de waarde, hoe groter de kans op inmenging van OOM-Killer, maar ook de databaseprestaties zijn hoger. De standaardwaarde is 60, maar als de hele database in het geheugen past, is het beter om de waarde in te stellen op 1.
Conclusies
Laat je niet afschrikken door de "killer" in OOM-Killer. In dit geval is de killer de redder van je systeem. Hij "vermoordt" de slechtste processen en redt het systeem van een crash. Om te voorkomen dat OOM-Killer PostgreSQL moet beëindigen, stel je vm.overcommit_memory de waarde in op 2. Dit garandeert niet dat OOM-Killer niet hoeft in te grijpen, maar vermindert de kans op gedwongen beëindiging van het PostgreSQL-proces.
Bron: habr.com
