OOM Killer - zabity serwer MySQL


10

Na jednym z naszych master MySQL OOM Killer został wywołany i zabił serwer MySQL, co doprowadziło do dużej awarii. Poniżej znajduje się dziennik jądra:

[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

To urządzenie ma 64 GB pamięci RAM.

Poniżej przedstawiono zmienne konfiguracyjne mysql:

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

Z wyjątkiem niektórych wtyczek nagios i skryptów do gromadzenia danych, nic innego nie działa na tym komputerze. Czy ktoś może mi pomóc dowiedzieć się, dlaczego wywołano zabójcę OOM i jak mogę zapobiec jego wywołaniu w przyszłości. Czy jest jakiś sposób, aby powiedzieć OOM Killer, aby nie zabijał serwera MySQL. Wiem, że możemy ustawić oom_adjwartość na bardzo mniej dla procesu, aby zapobiec zabiciu go przez zabójcę OOM. Ale czy jest jakiś inny sposób, aby temu zapobiec.


2
Zużycie pamięci będzie wyższe niż 48G+ 512M+, 64Mponieważ należy wziąć pod uwagę pewne koszty ogólne i inne struktury; gdzieś była na to formuła, ale nie mogę jej teraz znaleźć. Nie jestem pewien, czy spowodowałoby to wybuch 64G. Tylko dla pewności, freepotwierdza, że 64Gsą one dostępne w pierwszej kolejności?
frostschutz

@frostschutz: tak, wolne polecenie pokazuje 64G.
pradeepchhetri

Powiedzenie Zabójcy OOM, by nie zabijał mysqld, najprawdopodobniej po prostu opóźni katastrofę na chwilę. Lepiej napraw konfigurację.
scai

Odpowiedzi:


25

Linux ma zbyt wiele pamięci. Oznacza to, że pozwala procesowi zażądać więcej pamięci niż faktycznie dostępna w systemie. Kiedy program próbuje Malloc (), jądro mówi „OK, masz pamięć”, ale nie rezerwuj jej. Pamięć zostanie zarezerwowana tylko wtedy, gdy proces zapisze coś w tym miejscu.

Aby zobaczyć różnicę, masz 2 wskaźniki: Pamięć wirtualna i Pamięć rezydentna. Wirtualna to pamięć wymagana przez proces, Resident to pamięć rzeczywiście używana przez proces.

Z tym systemem możesz przejść do „overbookingu”, jądro zapewnia więcej pamięci niż jest dostępne. Następnie, gdy twój system ma 0 bajtów wolnej pamięci i Zamień, musi poświęcić (zabić) proces, aby uzyskać wolną pamięć.

Właśnie wtedy OOM Killer zaczyna działać. OOM wybiera proces na podstawie zużycia pamięci i wielu innych elementów (rodzic zyskuje 1/2 wyniku swoich dzieci; jeśli jest to proces będący własnością root, wynik jest dzielony przez 4 itd.). Spójrz na Linux- MM.org/OOM_Killer

Możesz wpływać na punktację OOM, dostrajając /proc/MySQL_PID/oom_adjplik. Ustawiając na -17, twój proces nigdy nie zostanie zabity. Ale zanim to zrobisz , powinieneś dostosować plik konfiguracyjny MySQL , aby ograniczyć użycie pamięci MySQL. W przeciwnym razie OOM Killer zabije inny proces systemowy (jak SSH, crontab itp.), A twój serwer będzie w bardzo niestabilnym stanie, co może prowadzić do uszkodzenia danych, które jest gorsze niż cokolwiek innego.

Możesz także rozważyć użycie większej wymiany.

[EDYTOWAĆ]

Możesz również zmienić to nadmierne zachowanie za pomocą tych 2 systemów:

vm.overcommit_memory
vm.overcommit_ratio

Jak stwierdzono w dokumentacji jądra

overcommit_memory:

Ta wartość zawiera flagę, która umożliwia przeładowanie pamięci.

Gdy ta flaga ma wartość 0, jądro próbuje oszacować ilość wolnej pamięci pozostałej, gdy przestrzeń użytkownika żąda więcej pamięci.

Gdy ta flaga ma wartość 1, jądro udaje, że zawsze ma wystarczającą ilość pamięci, aż do momentu faktycznego wyczerpania się.

Gdy ta flaga ma wartość 2, jądro używa zasady „nigdy nie nadkomituj”, która próbuje zapobiec nadpisywaniu pamięci. Pamiętaj, że user_reserve_kbytes wpływa na tę zasadę.

Ta funkcja może być bardzo przydatna, ponieważ istnieje wiele programów, które malloc () ogromną ilość pamięci „na wszelki wypadek” i nie zużywają jej dużo.

Wartość domyślna to 0.

Aby uzyskać więcej informacji, zobacz Documentation / vm / overcommit-account and security / commoncap.c :: cap_vm_enough_memory ().

overcommit_ratio:

Gdy parametr overcommit_memory jest ustawiony na 2, dozwolona przestrzeń adresowa nie może przekraczać swap plus ten procent fizycznej pamięci RAM. Patrz wyżej.

[/EDYTOWAĆ]


1
To jest właściwa odpowiedź. Widziałem artykuły, jak oom_score_adjto naprawić , ale tak naprawdę nie rozumieją mechanizmu punktacji.
3manuek,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.