
Wenn der Datenbankserver unter Linux unerwartet abgestürzt ist, ist es wichtig, die Ursache zu ermitteln. Es könnte mehrere Gründe dafür geben. Zum Beispiel, SIGSEGV — ein Fehler aufgrund eines Bugs im Backend-Server. Das ist jedoch selten. Häufiger passiert es, dass der Speicherplatz auf der Festplatte oder der RAM ausgeht. Wenn der Speicherplatz auf der Festplatte aufgebraucht ist, gibt es nur einen Ausweg – Platz schaffen und die Datenbank neu starten.
Out-Of-Memory Killer
Wenn bei Server oder einem Prozess der Speicher zur Neige geht, bietet Linux zwei Lösungsansätze: das gesamte System abzustürzen oder den Prozess (das Programm), das zu viel Speicher benötigt, zu beenden. Es ist besser, den Prozess zu stoppen und das Betriebssystem vor einem Absturz zu bewahren. Kurz gesagt, der Out-Of-Memory Killer ist ein Prozess, der ein Programm beendet, um den Kernel vor einem Ausfall zu schützen. Er opfert ein Programm, um die Funktionalität des Betriebssystems zu erhalten. Lassen Sie uns zuerst besprechen, wie OOM funktioniert und wie man es steuern kann, und anschließend sehen wir uns an, wie der OOM Killer entscheidet, welches Programm beendet werden soll.
Eine der Hauptaufgaben von Linux ist es, Prozessen Speicher zuzuweisen, wenn sie diesen anfordern. Typischerweise fragt ein Prozess oder eine Anwendung beim Betriebssystem nach Speicher, nutzt ihn jedoch oft nicht vollständig. Wenn das Betriebssystem allen, die nach Speicher fragen, diesen zuteilt, ohne dass sie ihn tatsächlich verwenden wollen, wird der Speicher schnell erschöpft sein, und das System wird versagen. Um dies zu vermeiden, reserviert das Betriebssystem Speicher für einen Prozess, gibt ihn jedoch nicht sofort frei. Der Speicher wird nur zugeteilt, wenn der Prozess tatsächlich beabsichtigt, ihn zu nutzen. Es kann vorkommen, dass es für das Betriebssystem keinen freien Speicher gibt, es jedoch dennoch Speicher für einen Prozess reserviert hat. Wenn der Prozess diesen Speicher benötigt, wird er zugeteilt, sofern dies möglich ist. Ein Nachteil dabei ist, dass das Betriebssystem manchmal Speicher reserviert, es jedoch zum benötigten Zeitpunkt keinen freien Speicher gibt, was zu einem Systemausfall führt. OOM spielt in diesem Szenario eine wichtige Rolle und beendet Prozesse, um den Kernel vor einem Panic-Zustand zu schützen. Wenn der Prozess PostgreSQL zwangsweise beendet wird, erscheint folgende Nachricht im Log:
Out of Memory: Killed process 12345 (postgres).Wenn im System wenig Speicher verfügbar ist und dieser nicht freigegeben werden kann, wird die Funktion out_of_memory. In diesem Schritt bleibt nur noch eines zu tun – einen oder mehrere Prozesse zu beenden. Sollte der OOM-Killer den Prozess sofort beenden oder kann gewartet werden? Offensichtlich ist der Aufruf von out_of_memory mit einer wartenden Ein-/Ausgabeoperation oder dem Auslagern von Seiten auf die Festplatte verbunden. Daher sollte der OOM-Killer zunächst Prüfungen durchführen und auf deren Grundlage entscheiden, welcher Prozess beendet werden muss. Wenn alle unten aufgeführten Prüfungen positiv ausfallen, wird OOM den Prozess beenden.
Prozessauswahl
Wenn der Speicher zu Ende geht, wird die Funktion out_of_memory(). Diese umfasst die Funktion select_bad_process(), die eine Bewertung von der Funktion badness()erhält. Das am schlechtesten bewertete Prozess wird ausgewählt. Die Funktion badness() wählt den Prozess nach bestimmten Regeln aus.
- Der Kernel benötigt ein gewisses Minimum an Speicher für sich selbst.
- Es muss viel Speicher freigegeben werden.
- Es sollten keine Prozesse beendet werden, die wenig Speicher verwenden.
- Es müssen mindestens Prozesse beendet werden.
- Komplexe Algorithmen, die die Chancen erhöhen, Prozesse zu beenden, die der Benutzer selbst beenden möchte.
Nachdem all diese Prüfungen durchgeführt wurden, analysiert OOM die Bewertung (oom_score). OOM weist zu oom_score Jeder Prozess erhält eine Bewertung, die dann mit dem Speicherbedarf multipliziert wird. Prozesse mit höheren Werten haben eine größere Wahrscheinlichkeit, Opfer des OOM-Killers zu werden. Prozesse, die mit privilegierten Benutzern verbunden sind, erhalten eine niedrigere Bewertung und haben somit weniger Chancen auf eine erzwungene Beendigung.
postgres=# SELECT pg_backend_pid();
gpg_backend_pid
----------------
3813
(1 Zeile)Die Prozess-ID von Postgres ist 3813, daher kann in einer anderen Shell der Wert mithilfe dieser Kernel-Parameter abgerufen werden. oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Wenn Sie verhindern möchten, dass der OOM-Killer den Prozess beendet, gibt es noch einen weiteren Kernel-Parameter: oom_score_adj. Fügen Sie einen großen negativen Wert hinzu, um die Wahrscheinlichkeit zu verringern, dass Ihr wichtiger Prozess beendet wird.
sudo echo -100 > /proc/3813/oom_score_adjUm den Wert festzulegen oom_score_adj, setzen Sie OOMScoreAdjust im Dienstblock:
[Service]
OOMScoreAdjust=-1000Oder verwenden Sie oomprotect im Befehl rcctl.
rcctl set servicename oomprotect -1000Erzwinge das Beenden des Prozesses
Wenn ein oder mehrere Prozesse ausgewählt wurden, ruft der OOM-Killer die Funktion oom_kill_task(). Diese Funktion sendet ein Beendigungsignal an den Prozess. Im Falle eines Speicherengpasses oom_kill() ruft diese Funktion auf, um dem Prozess das Signal SIGKILL zu senden. Eine Nachricht wird im Kernel-Log aufgezeichnet.
Speicherengpass: Prozess [pid] [name] wurde beendet.Wie man den OOM-Killer kontrolliert
In Linux kann der OOM-Killer aktiviert oder deaktiviert werden (obwohl Letzteres nicht empfohlen wird). Verwenden Sie den Parameter vm.oom-kill, um den OOM-Killer zu aktivieren oder zu deaktivieren. Um den OOM-Killer zur Laufzeit zu aktivieren, führen Sie den Befehl aus sysctl.
sudo -s sysctl -w vm.oom-kill=1Um den OOM-Killer zu deaktivieren, geben Sie den Wert 0 im selben Befehl an:
sudo -s sysctl -w vm.oom-kill=0Das Ergebnis dieses Befehls wird nicht dauerhaft gespeichert, sondern nur bis zum nächsten Neustart. Wenn mehr Beständigkeit erforderlich ist, fügen Sie diese Zeile in die Datei ein /etc/sysctl.conf:
echo vm.oom-kill=1 >> /etc/sysctl.confEine weitere Möglichkeit, ihn ein- und auszuschalten, besteht darin, die Variable panic_on_oomzu schreiben. Der Wert kann jederzeit überprüft werden mit /proc.
$ cat /proc/sys/vm/panic_on_oom
0Wenn der Wert auf 0 gesetzt ist, wird beim Speichermangel kein Kernel-Panic ausgelöst.
$ echo 0 > /proc/sys/vm/panic_on_oomWenn der Wert auf 1 gesetzt ist, wird beim Speichermangel ein Kernel-Panic ausgelöst.
echo 1 > /proc/sys/vm/panic_on_oomDer OOM-Killer lässt sich nicht nur aktivieren und deaktivieren. Wir haben bereits erwähnt, dass Linux für Prozesse mehr Speicher reservieren kann, als tatsächlich verfügbar ist, ohne diesen tatsächlich zuzuweisen, und dieses Verhalten wird durch eine Kernel-Parameter gesteuert. Dafür ist die Variable zuständig vm.overcommit_memory.
Es können folgende Werte angegeben werden:
0: Der Kernel entscheidet selbst, ob zu viel Speicher reserviert werden soll. Dies ist der Standardwert in den meisten Linux-Versionen.
1: Der Kernel wird immer zusätzlichen Speicher reservieren. Dies ist riskant, da der Speicher möglicherweise erschöpft ist, weil Prozesse irgendwann wahrscheinlich den verfügbaren Speicher anfordern werden.
2: Der Kernel wird nicht mehr Speicher reservieren, als in dem Parameter overcommit_ratio.
angegeben ist. In diesem Parameter geben Sie den Prozentsatz des Speichers an, für den eine Überreservierung zulässig ist. Wenn kein Platz dafür vorhanden ist, wird der Speicher nicht zugewiesen, und die Reservierung wird verweigert. Dies ist die sicherste Option, die für PostgreSQL empfohlen wird. Ein weiterer Faktor, der den OOM-Killer beeinflusst, ist die Swapping-Möglichkeit, die durch die Variable gesteuert wird cat /proc/sys/vm/swappiness. Diese Werte geben dem Kernel an, wie die Auslagerung von Seiten behandelt werden soll. Je höher der Wert, desto geringer die Wahrscheinlichkeit, dass OOM den Prozess beendet, aber aufgrund der Ein- und Ausgabeoperationen hat dies negative Auswirkungen auf die Datenbank. Umgekehrt gilt: Je niedriger der Wert, desto höher die Wahrscheinlichkeit, dass der OOM-Killer eingreift, aber auch die Leistung der Datenbank ist höher. Der Standardwert ist 60, aber wenn die gesamte Datenbank im RAM Platz findet, sollten Sie den Wert auf 1 setzen.
Ergebnisse
Lassen Sie sich von dem Begriff „Killer“ im OOM-Killer nicht einschüchtern. In diesem Fall wird der Killer zum Retter Ihres Systems. Er "tötet" die problematischsten Prozesse und schützt das System vor einem Notabschalten. Um zu vermeiden, dass der OOM-Killer PostgreSQL beenden muss, setzen Sie den vm.overcommit_memory Wert auf 2. Das garantiert nicht, dass der OOM-Killer nicht eingreifen muss, verringert jedoch die Wahrscheinlichkeit eines erzwungenen Prozessbeends von PostgreSQL.
Quelle: habr.com
