
Wenn der Datenbankserver in Linux unerwartet stoppt, müssen Sie die Ursache finden. Es kann mehrere Gründe geben. Zum Beispiel SIGSEGV — ein Absturz aufgrund eines Bugs im Backend-Server. Aber das ist selten. Meistens ist einfach der Speicherplatz auf der Festplatte oder der Speicher erschöpft. Wenn der Speicherplatz auf der Festplatte erschöpft ist, gibt es nur einen Ausweg – Platz schaffen und die Datenbank neu starten.
Out-Of-Memory Killer
Wenn Server oder ein Prozess den Speicher erschöpft, bietet Linux zwei Lösungswege: die gesamte System zu beenden oder den Prozess (die Anwendung), die den Speicher verschlingt, zu beenden. Es ist besser, den Prozess zu beenden und das Betriebssystem vor einem Absturz zu bewahren. Kurz gesagt, der Out-Of-Memory Killer ist ein Prozess, der eine Anwendung beendet, um den Kernel vor einem Absturz zu retten. Er opfert die Anwendung, um das Arbeiten des Betriebssystems aufrechtzuerhalten. Lass uns zuerst besprechen, wie OOM funktioniert und wie es kontrolliert wird, und dann sehen, wie der OOM Killer entscheidet, welche Anwendung beendet werden soll.
Eine der Hauptaufgaben von Linux besteht darin, Prozessen Speicher zuzuweisen, wenn sie darum bitten. Normalerweise fragt ein Prozess oder eine Anwendung das Betriebssystem nach Speicher an und verwendet diesen nicht vollständig. Wenn das Betriebssystem jedem, der danach fragt, Speicher zuweist, aber nicht plant, ihn zu nutzen, wird der Speicher sehr schnell erschöpft sein und das System wird abstürzen. Um dies zu vermeiden, reserviert das Betriebssystem Speicher für den Prozess, gibt ihn aber tatsächlich nicht aus. Speicher wird nur zugewiesen, wenn der Prozess tatsächlich bereit ist, ihn zu verwenden. Es kommt vor, dass das Betriebssystem keinen freien Speicher hat, aber Speicher für einen Prozess reserviert und wenn der Prozess ihn braucht, gibt das Betriebssystem ihn aus, wenn es kann. Der Nachteil ist, dass manchmal das Betriebssystem Speicher reserviert, aber zu diesem Zeitpunkt kein Speicher verfügbar ist, was zu einem Systemabsturz führt. OOM spielt in diesem Szenario eine wichtige Rolle und beendet Prozesse, um den Kernel vor Panik zu bewahren. Wenn der PostgreSQL-Prozess zwangsweise beendet wird, erscheint im Log ein Hinweis:
Out of Memory: Killed process 12345 (postgres).Wenn im System wenig Speicher vorhanden ist und er nicht freigegeben werden kann, wird die Funktion out_of_memoryIn dieser Phase bleibt ihr nur noch eins — einen oder mehrere Prozesse zu beenden. Soll der OOM-Killer den Prozess sofort beenden oder kann man warten? Offensichtlich hängt der Aufruf von out_of_memory mit dem Warten auf eine E/A-Operation oder dem Auslagern von Seiten auf die Festplatte zusammen. Daher muss der OOM-Killer zuerst Prüfungen durchführen und auf deren Grundlage entscheiden, welcher Prozess beendet werden muss. Wenn alle nachstehenden Prüfungen positiv ausfallen, wird der Prozess durch OOM beendet.
Prozessauswahl
Wenn der Speicher ausgeht, wird die Funktion out_of_memory()aufgerufen. In ihr gibt es die Funktion select_bad_process(), die eine Bewertung von der Funktion badness()erhält. Der „schlechteste“ Prozess wird betroffen sein. 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.
- Prozesse, die wenig Speicher verwenden, müssen nicht beendet werden.
- Es müssen mindestens Prozesse beendet werden.
- Komplexe Algorithmen, die die Chancen erhöhen, dass die Prozesse beendet werden, die der Benutzer selbst beenden möchte.
Nachdem alle diese Prüfungen durchgeführt wurden, analysiert OOM die Bewertung (oom_score). OOM weist jedem Prozess einen Wert zu und multipliziert diesen dann mit der Menge an Speicher. Prozesse mit höheren Werten haben eine höhere Wahrscheinlichkeit, Opfer des OOM-Killers zu werden. Prozesse, die mit einem privilegierten Benutzer verbunden sind, haben eine niedrigere Bewertung und weniger Chancen auf eine Zwangsbeendigung. oom_score postgres=# SELECT pg_backend_pid(); pg_backend_pid ---------------- 3813 (1 Zeile)
Die Prozess-ID von Postgres ist 3813, daher kann man in einer anderen Shell die Bewertung mit diesem Kernel-Parameter abrufenvagrant@vagrant:~$ sudo cat /proc/3813/oom_score 2 oom_score:
Wenn Sie absolut nicht möchten, dass der OOM-Killer den Prozess beendet, gibt es einen weiteren Kernel-Parameter:oom_score_adj . Fügen Sie einen großen negativen Wert hinzu, um die Wahrscheinlichkeit der Beendigung Ihres wichtigen Prozesses zu verringern.sudo echo -100 > /proc/3813/oom_score_adj
Um den Wert festzulegen, setzen Sie OOMScoreAdjust im Dienstblock:[Service] OOMScoreAdjust=-1000 . Fügen Sie einen großen negativen Wert hinzu, um die Wahrscheinlichkeit der Beendigung Ihres wichtigen Prozesses zu verringern.Oder verwenden Sie
oomprotectim Befehl rcctl rcctl set servicename oomprotect -1000 Zwangsbeendigung des Prozesses.
Wenn ein oder mehrere Prozesse bereits ausgewählt wurden, ruft der OOM-Killer die Funktionoom_kill_task()
auf. Diese Funktion sendet dem Prozess ein Beendigungszeichen. Bei Speichermangel oom_kill()ruft diese Funktion auf, um dem Prozess das SIGKILL-Signal zu senden. Eine Nachricht wird ins Kernel-Log geschrieben. oom_kill() ruft diese Funktion auf, um dem Prozess ein SIGKILL-Signal zu senden. Eine Nachricht wird im Kernelprotokoll aufgezeichnet.
Speicher erschöpft: Prozess [pid] [name] beendet.Wie man den OOM-Killer steuert
In Linux kann der OOM-Killer (Out of Memory Killer) ein- und ausgeschaltet werden (obwohl Letzteres nicht empfohlen wird). Verwenden Sie den Parameter vm.oom-kill, um den OOM-Killer ein- oder auszuschalten. 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 bleibt nicht dauerhaft, sondern gilt nur bis zum nächsten Neustart. Wenn Sie mehr Beständigkeit benötigen, fügen Sie diese Zeile in die Datei ein /etc/sysctl.conf:
echo vm.oom-kill = 1 >> /etc/sysctl.confEine weitere Möglichkeit, den OOM-Killer ein- und auszuschalten, besteht darin, die Variable panic_on_oomzu schreiben. Der Wert kann jederzeit überprüft werden in /proc.
$ cat /proc/sys/vm/panic_on_oom
0Wenn der Wert auf 0 gesetzt wird, tritt beim Speichermangel kein Kernel-Panic auf.
$ echo 0 > /proc/sys/vm/panic_on_oomWenn der Wert auf 1 gesetzt wird, tritt beim Speichermangel ein Kernel-Panic auf.
echo 1 > /proc/sys/vm/panic_on_oomDer OOM-Killer kann nicht nur ein- und ausgeschaltet werden. Wie bereits erwähnt, kann Linux mehr Speicher für Prozesse reservieren, als vorhanden ist, ohne diesen tatsächlich zuzuweisen, und dieses Verhalten wird durch einen Kernelparameter gesteuert. Die entsprechende Variable ist vm.overcommit_memory.
Für diese kann man folgende Werte festlegen:
0: Der Kernel entscheidet selbst, ob zu viel Speicher reserviert werden soll. Dieser Wert ist der Standard in den meisten Linux-Versionen.
1: Der Kernel wird immer zusätzlichen Speicher reservieren. Dies ist riskant, da der Speicher ausgehen kann, da die Prozesse wahrscheinlich irgendwann das anwenden, was gewährt wurde.
2: Der Kernel wird nicht mehr Speicher reservieren, als im Parameter overcommit_ratio.
angegeben ist. In diesem Parameter geben Sie den Prozentsatz des Speichers an, für den Überreservierung zulässig ist. Wenn kein Platz dafür vorhanden ist, wird der Speicher nicht zugewiesen, und die Überreservierung wird abgelehnt. Dies ist die sicherste Option, die für PostgreSQL empfohlen wird. Ein weiterer Faktor, der den OOM-Killer beeinflusst, ist die Swap-Fähigkeit, die durch die Variable gesteuert wird cat /proc/sys/vm/swappiness. Diese Werte geben dem Kern an, wie mit der Paging-Drücke umgegangen werden soll. Je höher der Wert, desto geringer ist die Wahrscheinlichkeit, dass OOM den Prozess beendet. Allerdings wirkt sich das aufgrund der I/O-Operationen negativ auf die Datenbank aus. Umgekehrt gilt: Je niedriger der Wert, desto höher ist die Wahrscheinlichkeit, dass der OOM-Killer eingreift, aber die Datenbankleistung ist ebenfalls höher. Der Standardwert liegt bei 60, aber wenn die gesamte Datenbank im Arbeitsspeicher untergebracht werden kann, setzen Sie besser den Wert auf 1.
Ergebnisse
Lassen Sie sich von dem „Killer“ im OOM-Killer nicht abschrecken. In diesem Fall wird der Killer zum Retter Ihres Systems. Er „tötet“ die problematischsten Prozesse und bewahrt das System vor einem Absturz. Um zu vermeiden, dass der OOM-Killer PostgreSQL beenden muss, setzen Sie für vm.overcommit_memory den Wert auf 2. Das garantiert nicht, dass der OOM-Killer nicht eingreifen muss, verringert jedoch die Wahrscheinlichkeit, dass der PostgreSQL-Prozess gewaltsam beendet wird.
Quelle: habr.com
