OOM Killer - membunuh server MySQL

10

Pada salah satu master MySQL kami, OOM Killer dipanggil dan membunuh server MySQL yang menyebabkan pemadaman besar. Berikut ini adalah log kernel:

[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

Mesin ini memiliki RAM 64GB.

Berikut ini adalah variabel konfigurasi mysql:

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

Kecuali beberapa plugin nagios dan skrip koleksi metrik, tidak ada yang berjalan di mesin ini. Dapatkah seseorang membantu saya untuk mencari tahu mengapa pembunuh OOM dipanggil dan bagaimana saya bisa mencegahnya dipanggil di masa depan. Apakah ada cara saya dapat memberitahu pembunuh OOM untuk tidak membunuh server mysql. Saya tahu kita dapat menetapkan oom_adjnilai menjadi sangat sedikit untuk suatu proses untuk mencegahnya terbunuh oleh pembunuh OOM. Tetapi apakah ada cara lain untuk mencegah hal ini.

pradeepchhetri
sumber
2
Penggunaan memori akan lebih tinggi dari 48G+ 512M+ 64Mkarena ada juga beberapa overhead dan struktur lain yang perlu dipertimbangkan; ada rumus untuk ini di suatu tempat tetapi saya tidak dapat menemukannya sekarang. Tidak yakin apakah ini akan menyebabkannya meledak 64G. Hanya untuk memastikan, freekonfirmasi 64Gapakah tersedia di tempat pertama?
frostschutz
@frostschutz: ya, perintah gratis menunjukkan 64G.
pradeepchhetri
Memberitahu Pembunuh OOM untuk tidak membunuh mysqld akan sangat mungkin hanya menunda bencana untuk sesaat. Lebih baik perbaiki konfigurasi Anda.
scai

Jawaban:

25

Linux melakukan overcommit memori. Itu berarti memungkinkan proses untuk meminta lebih banyak memori daripada yang sebenarnya tersedia di sistem. Ketika sebuah program mencoba untuk malloc (), kernel mengatakan "OK Anda mendapatkan memori", tetapi jangan memesannya. Memori hanya akan dicadangkan ketika proses akan menulis sesuatu di ruang ini.

Untuk melihat perbedaannya, Anda memiliki 2 indikator: Memori Virtual dan Memori Penduduk. Virtual adalah memori yang diminta oleh proses, Resident adalah memori yang benar-benar digunakan oleh proses.

Dengan sistem ini, Anda dapat masuk ke "overbooking", kernel memberikan lebih banyak memori daripada yang tersedia. Kemudian, ketika sistem Anda berjalan pada 0 byte memori bebas dan Swap, ia harus mengorbankan (membunuh) proses untuk mendapatkan memori bebas.

Saat itulah OOM Killer beraksi. OOM memilih proses berdasarkan konsumsi ingatannya, dan banyak elemen lainnya (orang tua memperoleh 1/2 dari skor anak-anaknya; jika ini adalah proses yang dimiliki root, skor dibagi 4, dll. Lihat di Linux- MM.org/OOM_Killer

Anda dapat mempengaruhi penilaian OOM dengan memutar /proc/MySQL_PID/oom_adjfile. Dengan mengaturnya -17, proses Anda tidak akan pernah terbunuh. Tetapi sebelum melakukan itu , Anda harus mengubah file konfigurasi MySQL Anda untuk membatasi penggunaan memori MySQL. Jika tidak, Pembunuh OOM akan membunuh proses sistem lainnya (seperti SSH, crontab, dll ...) dan server Anda akan berada dalam keadaan yang sangat tidak stabil, mungkin mengarah pada korupsi data yang lebih buruk dari apa pun.

Anda juga dapat mempertimbangkan untuk menggunakan lebih banyak swap.

[EDIT]

Anda juga dapat mengubah perilaku overcommit melalui 2 sistem ini:

vm.overcommit_memory
vm.overcommit_ratio

Sebagaimana dinyatakan dalam Dokumentasi Kernel

kenangan berlebihan:

Nilai ini berisi flag yang memungkinkan overcommitment memori.

Ketika flag ini adalah 0, kernel mencoba untuk memperkirakan jumlah memori bebas yang tersisa ketika userspace meminta lebih banyak memori.

Ketika flag ini adalah 1, kernel berpura-pura selalu ada cukup memori sampai benar-benar habis.

Ketika flag ini adalah 2, kernel menggunakan kebijakan "never overcommit" yang berusaha mencegah overcommit memori. Perhatikan bahwa user_reserve_kbytes memengaruhi kebijakan ini.

Fitur ini bisa sangat berguna karena ada banyak program yang malloc () memori dalam jumlah besar "just-in-case" dan tidak menggunakan banyak dari itu.

Nilai standarnya adalah 0.

Lihat Dokumentasi / vm / akuntansi berlebihan dan keamanan / commoncap.c :: cap_vm_enough_memory () untuk informasi lebih lanjut.

overcommit_ratio:

Ketika overcommit_mory diatur ke 2, ruang alamat yang dikomit tidak diizinkan untuk melebihi swap ditambah persentase RAM fisik ini. Lihat di atas.

[/ EDIT]

Adrien M.
sumber
1
Ini adalah jawaban yang benar. Saya telah melihat artikel di sekitar menggunakan oom_score_adjuntuk memperbaikinya , tetapi mereka tidak benar-benar memahami mekanisme skor.
3manuek