Einrichten von Out-Of-Memory Killer unter Linux für PostgreSQL

Einrichten von Out-Of-Memory Killer unter Linux für PostgreSQL

Wenn ein Datenbankserver unter Linux unerwartet beendet wird, müssen Sie den Grund finden. Es kann mehrere Gründe geben. Zum Beispiel, SIGSEGV – Fehler aufgrund eines Fehlers im Backend-Server. Aber das ist selten. Meistens geht Ihnen einfach der Speicherplatz oder der Arbeitsspeicher aus. Wenn Ihnen der Speicherplatz ausgeht, gibt es nur einen Ausweg: Geben Sie Speicherplatz frei und starten Sie die Datenbank neu.

Out-of-Memory-Killer

Wenn einem Server oder Prozess nicht mehr genügend Speicher zur Verfügung steht, bietet Linux zwei Lösungen an: das gesamte System zum Absturz bringen oder den Prozess (die Anwendung) beenden, der Speicher verbraucht. Besser ist es natürlich, den Vorgang abzubrechen und das Betriebssystem vor einem Absturz zu bewahren. Kurz gesagt ist Out-Of-Memory Killer ein Prozess, der eine Anwendung beendet, um einen Absturz des Kernels zu verhindern. Es opfert die Anwendung, um das Betriebssystem am Laufen zu halten. Lassen Sie uns zunächst besprechen, wie OOM funktioniert und wie man es steuert, und dann sehen wir, wie OOM Killer entscheidet, welche Anwendung beendet wird.

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, nutzt ihn jedoch nicht vollständig. Wenn das Betriebssystem jedem, der danach fragt, aber nicht vorhat, ihn zu nutzen, Speicher zur Verfügung stellt, wird der Speicher sehr bald erschöpft sein und das System wird ausfallen. Um dies zu vermeiden, reserviert das Betriebssystem Speicher für den Prozess, gibt ihn aber nicht tatsächlich frei. Speicher wird nur dann zugewiesen, wenn ein Prozess ihn tatsächlich verwenden wird. Es kommt vor, dass das Betriebssystem keinen freien Speicher hat, aber einem Prozess Speicher zuweist, und wenn ein Prozess ihn benötigt, weist das Betriebssystem ihn zu, wenn es kann. Der Nachteil besteht darin, dass das Betriebssystem manchmal Speicher reserviert, im richtigen Moment jedoch kein freier Speicher vorhanden ist und das System abstürzt. OOM spielt in diesem Szenario eine wichtige Rolle und beendet Prozesse, um zu verhindern, dass der Kernel in Panik gerät. Wenn die Beendigung eines PostgreSQL-Prozesses erzwungen wird, erscheint eine Meldung im Protokoll:

Out of Memory: Killed process 12345 (postgres).

Wenn im System nur noch wenig Arbeitsspeicher vorhanden ist und dieser nicht freigegeben werden kann, wird die Funktion aufgerufen out_of_memory. Zu diesem Zeitpunkt muss sie nur noch eines tun: einen oder mehrere Prozesse abschließen. Sollte OOM-Killer den Prozess sofort beenden oder kann er warten? Wenn out_of_memory aufgerufen wird, liegt dies offensichtlich daran, dass auf einen E/A-Vorgang oder eine Auslagerung auf die Festplatte gewartet wird. Daher muss der OOM-Killer zunächst Prüfungen durchführen und auf dieser Grundlage entscheiden, dass der Prozess beendet werden muss. Wenn alle unten aufgeführten Prüfungen positiv ausfallen, bricht OOM den Vorgang ab.

Prozessauswahl

Wenn der Speicher erschöpft ist, wird die Funktion aufgerufen out_of_memory(). Es hat eine Funktion select_bad_process(), der von der Funktion eine Auswertung erhält badness(). Der „schlimmste“ Prozess wird ins Visier genommen. Funktion badness() wählt einen Prozess nach bestimmten Regeln aus.

  1. Der Kernel benötigt für sich selbst etwas Mindestspeicher.
  2. Sie müssen viel Speicher freigeben.
  3. Es besteht keine Notwendigkeit, Prozesse zu beenden, die wenig Speicher verbrauchen.
  4. Es müssen Mindestprozesse abgeschlossen werden.
  5. Komplexe Algorithmen, die die Abschlusschancen derjenigen Prozesse erhöhen, die der Benutzer selbst abschließen möchte.

Nachdem alle diese Prüfungen abgeschlossen sind, prüft OOM die Punktzahl (oom_score). OOM weist zu oom_score jeden Prozess und multipliziert diesen Wert dann mit der Speichermenge. Prozesse mit größeren Werten fallen eher dem OOM-Killer zum Opfer. Prozesse, die dem Root-Benutzer zugeordnet sind, haben eine niedrigere Bewertung und müssen mit geringerer Wahrscheinlichkeit beendet werden.

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

Die Postgres-Prozess-ID ist 3813, daher ist es in einer anderen Shell möglich, den Score mithilfe dieses Kernel-Parameters abzurufen oom_score:

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

Wenn Sie nicht möchten, dass OOM-Killer den Prozess überhaupt abbricht, gibt es eine weitere Kernel-Option: oom_score_adj. Fügen Sie einen großen negativen Wert hinzu, um die Wahrscheinlichkeit zu verringern, dass ein von Ihnen geschätzter Prozess abgeschlossen wird.

sudo echo -100 > /proc/3813/oom_score_adj

Um einen Wert festzulegen oom_score_adj, legen Sie OOMScoreAdjust im Serviceblock fest:

[Service]
OOMScoreAdjust=-1000

Oder verwenden oomprotect in einer Mannschaft rcctl.

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

Beendigung eines Prozesses erzwingen

Wenn bereits ein oder mehrere Prozesse ausgewählt sind, ruft OOM-Killer die Funktion auf oom_kill_task(). Diese Funktion sendet ein Beendigungssignal an den Prozess. Bei Speichermangel oom_kill() Ruft diese Funktion auf, um ein SIGKILL-Signal an den Prozess zu senden. Eine Meldung wird in das Kernel-Protokoll geschrieben.

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

So steuern Sie OOM-Killer

Unter Linux können Sie OOM-Killer aktivieren oder deaktivieren (letzteres wird jedoch nicht empfohlen). Zum Aktivieren oder Deaktivieren verwenden Sie den Parameter vm.oom-kill. Um OOM-Killer zur Laufzeit zu aktivieren, führen Sie den Befehl aus sysctl.

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

Um OOM-Killer zu deaktivieren, geben Sie 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 hinzu /etc/sysctl.conf:

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

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

$ cat /proc/sys/vm/panic_on_oom
0

Wenn Sie den Wert auf 0 setzen, kommt es nicht zu einer Kernel-Panik, wenn der Speicher knapp wird.

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

Wenn Sie den Wert auf 1 setzen, kommt es zu einer Kernel-Panik, wenn der Speicher knapp wird.

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 verfügbar ist, ohne ihn tatsächlich zuzuweisen, und dieses Verhalten wird durch einen Linux-Kernel-Parameter gesteuert. Dafür ist die Variable verantwortlich vm.overcommit_memory.

Sie können dafür folgende Werte angeben:

0: Der Kernel entscheidet selbst, ob zu viel Speicher reserviert wird. Dies ist bei den meisten Linux-Versionen die Standardeinstellung.
1: Der Kernel reserviert immer zusätzlichen Speicher. Dies ist riskant, da der Speicher möglicherweise knapp wird, da die Prozesse ihn höchstwahrscheinlich eines Tages benötigen werden.
2: Der Kernel reserviert nicht mehr Speicher als im Parameter angegeben overcommit_ratio.

Mit diesem Parameter geben Sie den Prozentsatz des Speichers an, der überreserviert werden darf. Wenn kein Platz dafür vorhanden ist, wird kein Speicher zugewiesen und die Reservierung wird verweigert. Dies ist die sicherste für PostgreSQL empfohlene Option. OOM-Killer wird von einem weiteren Element beeinflusst – der Austauschfähigkeit, die durch die Variable gesteuert wird cat /proc/sys/vm/swappiness. Diese Werte teilen dem Kernel mit, wie er mit Paging umgehen soll. Je höher der Wert, desto unwahrscheinlicher ist es, dass OOM den Prozess beendet. Aufgrund von I/O-Vorgängen hat dies jedoch negative Auswirkungen auf die Datenbank. Und umgekehrt – je niedriger der Wert, desto höher ist die Wahrscheinlichkeit eines OOM-Killer-Eingriffs, aber auch die Datenbankleistung ist höher. Der Standardwert ist 60, aber wenn die gesamte Datenbank in den Speicher passt, ist es besser, den Wert auf 1 zu setzen.

Ergebnisse

Lassen Sie sich vom „Killer“ in OOM-Killer nicht einschüchtern. In diesem Fall wird der Mörder der Retter Ihres Systems sein. Es „tötet“ die schlimmsten Prozesse und bewahrt das System vor einem Absturz. Um zu vermeiden, dass OOM-Killer zum Beenden von PostgreSQL verwendet werden muss, setzen Sie auf vm.overcommit_memory Wert 2. Dies garantiert nicht, dass OOM-Killer nicht eingreifen muss, verringert aber die Wahrscheinlichkeit, dass der PostgreSQL-Prozess zum Beenden gezwungen wird.

Source: habr.com

Kommentar hinzufügen