Out-of-Memory Killer unter Linux für PostgreSQL konfigurieren


Wenn der Datenbankserver unter Linux unerwartet heruntergefahren wird, müssen Sie den Grund finden. Es kann mehrere Gründe geben. Zum Beispiel SIGSEGV - Absturz aufgrund eines Fehlers im Backend-Server. Das ist aber eine Seltenheit. In den meisten Fällen geht der Speicherplatz oder der Speicher einfach zur Neige. Wenn der Speicherplatz knapp wird, besteht eine Möglichkeit darin, Speicherplatz freizugeben und die Datenbank neu zu starten.


Out-of-Memory-Killer


Wenn der Server oder Prozess nicht genügend Arbeitsspeicher hat, bietet Linux zwei Lösungen an: Absturz des gesamten Systems oder Beenden des Prozesses (der Anwendung), der den Arbeitsspeicher verbraucht. Es ist natürlich besser, den Vorgang abzuschließen und das Betriebssystem vor einer abnormalen Beendigung zu schützen. Kurz gesagt, Out-Of-Memory Killer ist der Prozess, der eine Anwendung beendet, um den Kernel vor einem Absturz zu schützen. Er opfert die Anwendung, um das Betriebssystem am Laufen zu halten. Lassen Sie uns zunächst diskutieren, wie OOM funktioniert und wie es gesteuert wird, und dann sehen, wie OOM Killer entscheidet, welche Anwendung beendet werden soll.


Eine der Hauptaufgaben von Linux besteht darin, Prozessen Speicher zuzuweisen, wenn sie danach fragen. Normalerweise fordert ein Prozess oder eine Anwendung Speicher vom Betriebssystem an, aber sie selbst nutzen ihn nicht vollständig. Wenn das Betriebssystem Speicher an alle ausgibt, die danach fragen, aber nicht vorhaben, ihn zu verwenden, wird der Speicher sehr bald beendet und das System fällt aus. Um dies zu vermeiden, reserviert das Betriebssystem Speicher für den Prozess, gibt ihn jedoch nicht aus. Der Speicher wird nur zugewiesen, wenn der Prozess ihn wirklich verwenden wird. Es kommt vor, dass das Betriebssystem keinen freien Speicher hat, aber dem Prozess Speicher zuweist, und wenn der Prozess ihn benötigt, weist das Betriebssystem ihn zu, wenn dies möglich ist. Der Nachteil ist, dass manchmal das Betriebssystem Speicher reserviert, aber zum richtigen Zeitpunkt kein freier Speicher vorhanden ist und das System abstürzt. OOM spielt in diesem Szenario eine wichtige Rolle und beendet Prozesse, um die Panik des Kernels zu verhindern. Wenn der PostgreSQL-Prozess zwangsweise beendet wird, wird im Protokoll eine Meldung angezeigt:


Out of Memory: Killed process 12345 (postgres). 

Wenn im System nur wenig Speicher vorhanden ist und dieser nicht out_of_memory kann, wird die Funktion out_of_memory . Zu diesem Zeitpunkt hat sie nur noch eines - einen oder mehrere Prozesse abzuschließen. Sollte OOM-Killer den Prozess sofort beenden oder kann ich warten? Wenn out_of_memory aufgerufen wird, ist dies offensichtlich darauf zurückzuführen, dass auf eine E / A-Operation gewartet oder eine Seite auf die Festplatte ausgetauscht wird. Daher muss der OOM-Killer zuerst Überprüfungen durchführen und auf dieser Grundlage entscheiden, dass der Prozess abgeschlossen werden soll. Wenn alle folgenden Überprüfungen ein positives Ergebnis liefern, beendet OOM den Prozess.


Prozessauswahl


Wenn der Speicher out_of_memory() ist, wird die Funktion out_of_memory() . Es hat eine Funktion select_bad_process() , die eine Schätzung von der Funktion select_bad_process() erhält. Die Verteilung des "schlechtesten" Prozesses. Die Funktion badness() wählt einen Prozess nach bestimmten Regeln aus.


  1. Der Kernel benötigt einen minimalen Speicher für sich.
  2. Sie müssen viel Speicher freigeben.
  3. Prozesse, die wenig Speicher benötigen, müssen nicht beendet werden.
  4. Sie müssen ein Minimum an Prozessen ausführen.
  5. Komplexe Algorithmen, die die Abschlusswahrscheinlichkeit für die Prozesse erhöhen, die der Benutzer selbst ausführen möchte.

Nach Abschluss aller dieser Prüfungen prüft OOM die Note ( oom_score ). OOM weist jedem Prozess oom_score und multipliziert diesen Wert dann mit der Speichermenge. Prozesse mit höheren Werten werden eher Opfer von OOM Killer. Prozesse, die einem privilegierten Benutzer zugeordnet sind, haben eine niedrigere Bewertung und erzwingen mit geringerer Wahrscheinlichkeit die Beendigung.


 postgres=# SELECT pg_backend_pid(); pg_backend_pid ----------------    3813 (1 row) 

Die Kennung des Postgres-Prozesses lautet 3813, sodass Sie in einer anderen Shell mithilfe dieses oom_score eine Schätzung erhalten können:


 vagrant@vagrant:~$ sudo cat /proc/3813/oom_score 2 

Wenn Sie nicht möchten, dass OOM-Killer den Vorgang überhaupt abschließt, gibt es einen weiteren Kernel-Parameter: oom_score_adj . Fügen Sie einen großen negativen Wert hinzu, um die Wahrscheinlichkeit zu verringern, dass Sie den von Ihnen geliebten Prozess abschließen.


 sudo echo -100 > /proc/3813/oom_score_adj 

Um den Wert oom_score_adj , setzen Sie OOMScoreAdjust im Serviceblock:


 [Service] OOMScoreAdjust=-1000 

Oder verwenden Sie oomprotect im rcctl .


 rcctl set <i>servicename</i> oomprotect -1000 

Erzwungene Prozessbeendigung


Wenn bereits ein oder mehrere Prozesse ausgewählt sind, ruft OOM-Killer die Funktion oom_kill_task() . Diese Funktion sendet ein Beendigungssignal an den Prozess. Wenn nicht genügend Speicher vorhanden ist, ruft oom_kill() diese Funktion auf, um ein SIGKILL-Signal an den Prozess zu senden. Eine Nachricht wird in das Kernel-Protokoll geschrieben.


 Out of Memory: Killed process [pid] [name]. 

Wie man OOM-Killer kontrolliert


Unter Linux können Sie OOM-Killer aktivieren oder deaktivieren (letzteres wird jedoch nicht empfohlen). Verwenden vm.oom-kill zum Aktivieren und Deaktivieren die Option vm.oom-kill . Führen Sie den Befehl sysctl um OOM-Killer zur Laufzeit zu aktivieren.


 sudo -s sysctl -w vm.oom-kill = 1 

Geben Sie zum Deaktivieren von OOM-Killer im selben Befehl den Wert 0 an:


 sudo -s sysctl -w vm.oom-kill = 0 

Das Ergebnis dieses Befehls wird nicht für immer gespeichert, sondern nur bis zum ersten Neustart. Wenn Sie mehr Persistenz benötigen, fügen Sie diese Zeile zur Datei /etc/sysctl.conf :


 echo vm.oom-kill = 1 >>/etc/sysctl.conf 

Eine andere Möglichkeit zum Aktivieren und Deaktivieren besteht darin, die Variable panic_on_oom zu schreiben. Der Wert kann immer in /proc eingecheckt werden.


 $ cat /proc/sys/vm/panic_on_oom 0 

Wenn Sie den Wert auf 0 setzen, wird die Kernel-Panik nicht ausgelöst, wenn der Speicher leer ist.


 $ echo 0 > /proc/sys/vm/panic_on_oom 

Wenn Sie den Wert auf 1 setzen, tritt eine Kernel-Panik auf, wenn der Speicher leer ist.


 echo 1 > /proc/sys/vm/panic_on_oom 

OOM-Killer kann nicht nur ein- und ausgeschaltet werden. Wir haben bereits gesagt, dass Linux mehr Speicher für Prozesse reservieren kann als vorhanden, diesen jedoch nicht zuweisen kann, und dieses Verhalten wird durch den Linux-Kernel-Parameter gesteuert. Die Variable vm.overcommit_memory ist dafür verantwortlich.


Sie können dafür folgende Werte angeben:


0: Der Kernel selbst entscheidet, ob zu viel Speicher reserviert wird. Dies ist der Standardwert für die meisten Linux-Versionen.
1: Der Kernel reserviert immer zusätzlichen Speicher. Dies ist riskant, da der Speicher enden kann, da die Prozesse höchstwahrscheinlich eines Tages das verlangen werden, was sein soll.
2: Der Kernel reserviert nicht mehr Speicher als im Parameter overcommit_ratio angegeben.


In diesem Parameter geben Sie den Prozentsatz des Speichers an, für den Redundanz zulässig ist. Wenn kein Speicherplatz vorhanden ist und kein Speicher zugewiesen ist, wird die Reservierung abgelehnt. Dies ist die sicherste Option, die für PostgreSQL empfohlen wird. OOM-Killer ist von einem anderen Element betroffen - der Swap-Funktion, die von der Variablen cat /proc/sys/vm/swappiness . Diese Werte teilen dem Kernel mit, wie mit Paging umgegangen werden soll. Je größer der Wert ist, desto unwahrscheinlicher ist es, dass OOM den Prozess beendet. Aufgrund von E / A wirkt sich dies jedoch negativ auf die Datenbank aus. Und umgekehrt: Je kleiner der Wert, desto höher ist die Wahrscheinlichkeit einer OOM-Killer-Intervention, aber auch die Datenbankleistung ist höher. Der Standardwert ist 60, aber wenn die gesamte Datenbank in den Speicher passt, ist es am besten, den Wert auf 1 zu setzen.


Zusammenfassung


Hab keine Angst vor dem Killer in OOM-Killer. In diesem Fall ist der Mörder der Retter Ihres Systems. Es "beendet" die schlimmsten Prozesse und bewahrt das System vor abnormaler Beendigung. Um zu vermeiden, dass OOM-Killer zum vm.overcommit_memory von PostgreSQL verwendet werden muss, setzen Sie vm.overcommit_memory auf 2. Dies garantiert nicht, dass OOM-Killer nicht eingreifen muss, verringert jedoch die Wahrscheinlichkeit, dass ein erzwungener PostgreSQL-Prozess beendet wird.

Source: https://habr.com/ru/post/de464245/


All Articles