The Master Daemon Died- Warnung vor dem Killer
Schon öfter schilderten uns Kunden mysteriöse Abstürze der Datenbank auf Linux. Auffällig dabei war, das der oninit in diesen Fällen keinerlei af-file schrieb. Häufig war die einzige Meldung im online.log die Zeile:
14:28:13 The Master Daemon Died
oder
14:19:49 Assert Failed: Unexpected virtual processor termination: pid = 13697, signal 9 received.
14:19:49 IBM Informix Dynamic Server Version 12.10.FC4
14:19:49 Who: Session(4505, muster@172.1.1.2, -1, 0x5bad2290)
Thread(8282, sqlexec, 59a258a8, 1)
File: mt.c Line: 14630
14:19:49 stack trace for pid 13696 written to /db2/sp2/dump/af.24426af4
14:19:49 See Also: /db2/sp2/dump/af.24426af4
Die Ursache des Problems wird zumindest in der 2. Meldung angedeutet. Am Ende der 1. Zeile steht 'signal 9 received.' Signal 9 ist das Signal SIGKILL. Dieses Signal kann von dem Prozess nicht mehr behandelt werden und wird normalerweise von Administratoren genutzt um hängende Prozesse zu beenden.
Nur beenden Administratoren normalerweise nicht den Datenbankprozeß mit einem kill-Kommando. Hierbei handelt es sich um ein Kernelmodul, dass soweit ich weiß nur bei RedHat-Linux (und RedHat-Derivaten) standardmäßig aktiv ist. Andere Distributionen wie SuSE oder Ubuntu haben dieses gefährliche Modul nicht standardmäßig aktiviert. Der so genannte OOM-Killer (Out of Memory-Killer) sucht sich bei Speicherknappheit einen aus Sicht des Betriebssystems unwichtigen Prozess mit hohen Speicherverbrauch und killt diesen. Das ist auf Datenbankservern häufig der Datenbankprozess, da der Shared Memory zum Speicher der Datenbank gehört.
Ob der OOM-Killer zugeschlagen hat kann man im System-Logfile /var/log/syslog oder /var/log/messages erkennen. Dort gibt es dann einen Eintrag in der Form:
Nov 21 16:13:54 dbserv kernel: Out of Memory: Killed process 4352 (oninit).
Ich kann nicht nachvollziehen, warum RedHat dieses Modul auf einem Server-System standardmäßig aktiviert, aber wir raten dazu es auf Datenbankservern zu deaktivieren. Das ist relativ einfach. In der Datei /etc/sysctl.conf muss folgender Eintrag gemacht werden:
vm.overcommit_memory=2
vm.overcommit_ratio = 80
vm.oom-kill=0
Damit wird beim nächsten Start der Maschine der OOM-Killer nicht mehr aktiviert.
Damit auch beim laufenden Kernel der Killer deaktiviert wird, muss man als root das Kommando:
sysctl vm.overcommit_memory=2
sysctl vm.overcommit_ratio = 80
sysctl vm.oom-kill=0
absetzen. Damit ist der OOM-Killer abgeschaltet. Alternativ kann man auch den oninit-Prozess in die Liste der geschützten Prozesse eintragen.
Wobei hier der Wert vm.overcommit_memory=2 bedeutet das niemals mehr Speicher vergeben wird, als Swap + Memory groß sind. Ist der Speicher aufgebraucht, bekommt der Prozeß einen Fehler bei Speicheranforderungen. Diese Setting schalten den OOM-Killer also nicht ab sondern versucht nur das Auslösen zu vermeiden. Der Wert für vm.overcommit_ratio gibt den Prozentsatz für den phys. Speicher an. Default ist 50%.
Der Idealwert - vm.oom-kill=0 als 'OOM-Killer aus' funktioniert leider nicht auf jedem System. Es wird zwar empfohlen den Wert vm.
echo -17 > /proc/$PID/oom_score_adj
In diesem Beispiel wäre $PID die Prozessnummer des oninit-Prozesses. Hat man mehrere oninit-Prozesse, muss bei allen oninit-Prozessen dieser Eintrag vorgenommen werden.
Dazu eignet sich das Kommando pgrep:
pgrep -f oninit | while read PID; do echo -17 > /proc/$PID/oom_score_adj; done
Diese Zeile trägt für alle oninit-Prozesse die -17 als niedrigste Abschuß-Priorität des Prozesses ein. Die Werte liegen normalerweise zwischen -16 und +15. Der Prozess mit der höchsten Abschuß-Priorität wird als Erstes beendet. Auf alten Systemen muss die Datei oom_adj verwendet werden.
Sollten per onmode-Kommando zur Laufzeit oninit-Prozesse (VP's) hinzugefügt werden, so müssen für diese die Einträge auch gesetzt werden.
Hat man das Paket dstat installiert, so kann man sich anzeigen lassen, welches Programm der OOM-Killer im Moment killen würde, wenn es zu einem Out of Memory Event kommt. Das Kommando dazu ist:
dstat --top-oom
Die Beschreibung dazu 'show process that will be killed by OOM the first'.
Wer mehr über die Funktionsweise des OOM-Killers erfahren möchte kann hier nachlesen. Allgemeines was passiert, wenn Linux Memory-Probleme bekommt gibt es hier und noch eine sehr genaue Beschreibung des Killers mit Möglichjkeiten der Konfiguration gibt es in diesem Artikel.