OOM Killer - MySQL-Server getötet

10

Auf einem unserer MySQL-Master wurde OOM Killer aufgerufen und der MySQL-Server getötet, was zu einem großen Ausfall führte. Es folgt das Kernel-Protokoll:

[2006013.230723] mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
[2006013.230733] Pid: 1319, comm: mysqld Tainted: P           2.6.32-5-amd64 #1
[2006013.230735] Call Trace:
[2006013.230744]  [<ffffffff810b6708>] ? oom_kill_process+0x7f/0x23f
[2006013.230750]  [<ffffffff8106bde2>] ? timekeeping_get_ns+0xe/0x2e
[2006013.230754]  [<ffffffff810b6c2c>] ? __out_of_memory+0x12a/0x141
[2006013.230757]  [<ffffffff810b6d83>] ? out_of_memory+0x140/0x172
[2006013.230762]  [<ffffffff810baae8>] ? __alloc_pages_nodemask+0x4ec/0x5fc
[2006013.230768]  [<ffffffff812fca02>] ? io_schedule+0x93/0xb7
[2006013.230773]  [<ffffffff810bc051>] ? __do_page_cache_readahead+0x9b/0x1b4
[2006013.230778]  [<ffffffff810652f8>] ? wake_bit_function+0x0/0x23
[2006013.230782]  [<ffffffff810bc186>] ? ra_submit+0x1c/0x20
[2006013.230785]  [<ffffffff810b4e53>] ? filemap_fault+0x17d/0x2f6
[2006013.230790]  [<ffffffff810cae1e>] ? __do_fault+0x54/0x3c3
[2006013.230794]  [<ffffffff812fce29>] ? __wait_on_bit_lock+0x76/0x84
[2006013.230798]  [<ffffffff810cd172>] ? handle_mm_fault+0x3b8/0x80f
[2006013.230803]  [<ffffffff8103a9a0>] ? pick_next_task+0x21/0x3c
[2006013.230808]  [<ffffffff810168ba>] ? sched_clock+0x5/0x8
[2006013.230813]  [<ffffffff81300186>] ? do_page_fault+0x2e0/0x2fc
[2006013.230817]  [<ffffffff812fe025>] ? page_fault+0x25/0x30

Dieses Gerät verfügt über 64 GB RAM.

Im Folgenden sind die MySQL-Konfigurationsvariablen aufgeführt:

innodb_buffer_pool_size        = 48G
innodb_additional_mem_pool_size = 512M
innodb_log_buffer_size         = 64M

Außer einigen Nagios-Plugins und Metrik-Erfassungsskripten wird auf diesem Computer nichts anderes ausgeführt. Kann mir jemand helfen, herauszufinden, warum der OOM-Killer aufgerufen wurde und wie ich verhindern kann, dass er in Zukunft aufgerufen wird? Kann ich OOM Killer auf irgendeine Weise anweisen, den MySQL-Server nicht zu töten? Ich weiß, dass wir oom_adjfür einen Prozess einen sehr geringen Wert festlegen können, um zu verhindern, dass er vom OOM-Killer getötet wird. Aber gibt es eine andere Möglichkeit, dies zu verhindern?

pradeepchhetri
quelle
2
Die Speichernutzung ist höher als 48G+ 512M+, 64Mda auch einige Overhead- und andere Strukturen zu berücksichtigen sind. Irgendwo gab es eine Formel dafür, aber ich kann sie momentan nicht finden. Ich bin mir nicht sicher, ob dies dazu führen würde, dass es durchbrennt 64G. Nur um sicherzugehen, freebestätigt, dass die 64Güberhaupt verfügbar sind?
Frostschutz
@ Frostschutz: Ja, freier Befehl zeigt 64G.
Pradeepchhetri
Wenn Sie dem OOM Killer sagen, dass er mysqld nicht töten soll, wird sich die Katastrophe höchstwahrscheinlich nur für einen kurzen Moment verzögern. Korrigieren Sie besser Ihre Konfiguration.
Scai

Antworten:

25

Linux führt Speicherüberlastung durch. Dies bedeutet, dass der Prozess mehr Speicher anfordern kann, als tatsächlich auf dem System verfügbar ist. Wenn ein Programm versucht, malloc () zu verwenden, sagt der Kernel "OK, Sie haben den Speicher", aber reservieren Sie ihn nicht. Der Speicher wird nur reserviert, wenn der Prozess etwas in diesen Bereich schreibt.

Um den Unterschied zu erkennen, haben Sie zwei Indikatoren: Virtueller Speicher und Residenter Speicher. Virtuell ist der vom Prozess angeforderte Speicher, Resident ist der vom Prozess tatsächlich verwendete Speicher.

Mit diesem System können Sie in "Überbuchung" gehen, Kernel gewährt mehr Speicher als verfügbar. Wenn Ihr System dann 0 Byte freien Speicher und Swap verwendet, muss es einen Prozess opfern (beenden) , um freien Speicher zu erhalten.

Dann tritt OOM Killer in Aktion. Der OOM wählt einen Prozess basierend auf seinem Speicherverbrauch und vielen anderen Elementen aus (Eltern erhalten die Hälfte der Punktzahl seiner Kinder; wenn es sich um einen Root-Prozess handelt, wird die Punktzahl durch 4 geteilt usw. Schauen Sie sich Linux- an. MM.org/OOM_Killer

Sie können die OOM-Bewertung beeinflussen, indem Sie die /proc/MySQL_PID/oom_adjDatei optimieren . Wenn Sie es auf setzen -17, wird Ihr Prozess niemals beendet. Aber bevor Sie das tun , sollten Sie Ihre MySQL - Konfigurationsdatei zwicken , um MySQL Speicherverbrauch zu begrenzen. Andernfalls beendet der OOM Killer andere Systemprozesse (wie SSH, Crontab usw.) und Ihr Server befindet sich in einem sehr instabilen Zustand, was möglicherweise zu einer Datenbeschädigung führt, die schlimmer ist als alles andere.

Sie können auch mehr Swap verwenden.

[BEARBEITEN]

Sie können das Overcommit-Verhalten auch über die folgenden 2 Systeme ändern:

vm.overcommit_memory
vm.overcommit_ratio

Wie in der Kernel-Dokumentation angegeben

overcommit_memory:

Dieser Wert enthält ein Flag, das eine Überbelegung des Speichers ermöglicht.

Wenn dieses Flag 0 ist, versucht der Kernel, die Menge an freiem Speicher zu schätzen, die übrig bleibt, wenn der Benutzerbereich mehr Speicher anfordert.

Wenn dieses Flag 1 ist, gibt der Kernel vor, dass immer genügend Speicher vorhanden ist, bis er tatsächlich leer ist.

Wenn dieses Flag 2 ist, verwendet der Kernel eine "Never Overcommit" -Richtlinie, die versucht, ein Überbeanspruchen des Speichers zu verhindern. Beachten Sie, dass user_reserve_kbytes diese Richtlinie beeinflusst.

Diese Funktion kann sehr nützlich sein, da es viele Programme gibt, die "nur für den Fall" große Mengen an Speicher speichern und nicht viel davon verwenden.

Der Standardwert ist 0.

Weitere Informationen finden Sie unter Dokumentation / vm / overcommit-Accounting und Sicherheit / commoncap.c :: cap_vm_enough_memory ().

overcommit_ratio:

Wenn overcommit_memory auf 2 gesetzt ist, darf der festgeschriebene Adressraum Swap plus diesen Prozentsatz des physischen RAM nicht überschreiten. Siehe oben.

[/BEARBEITEN]

Adrien M.
quelle
1
Das ist die richtige Antwort. Ich habe Artikel gesehen, oom_score_adjin denen dies behoben wurde , aber sie verstehen den Bewertungsmechanismus nicht wirklich.
3manuek