OOM Killer - öldürülen MySQL sunucusu


10

MySQL master'larımızdan birinde, OOM Killer çağrıldı ve büyük kesintiye yol açan MySQL sunucusunu öldürdü. Çekirdek günlüğü aşağıdadır:

[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

Bu makinede 64GB RAM var.

Mysql yapılandırma değişkenleri şunlardır:

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

Bazı nagios eklentileri ve metrik toplama komut dosyaları dışında, bu makinede başka hiçbir şey çalışmaz. Birisi bana OOM katilinin neden çağrıldığını ve gelecekte çağrılmasını nasıl önleyebilirim? OOM katil mysql sunucusunu öldürmemesini söyleyebilirim herhangi bir yolu var mı. oom_adjOOM katili tarafından öldürülmesini önlemek için bir sürecin değerini çok daha düşük olarak ayarlayabileceğimizi biliyorum . Ancak bunu önlemenin başka bir yolu var mı?


2
Hafıza kullanımı 48G+ 512M+ ' dan daha yüksek olacaktır 64Mçünkü dikkate alınması gereken bazı ek yükler ve diğer yapılar da vardır; bunun için bir yerde bir formül vardı ama şu anda bulamıyorum. Bunun havaya uçmasına neden olup olmayacağından emin değilim 64G. Sadece emin olmak freeiçin 64G, ilk etapta mevcut olduğunu doğrular ?
frostschutz

@ frostschutz: evet, ücretsiz komut 64G gösteriyor.
pradeepchhetri

OOM Katiline mysqld'i öldürmemesini söylemek, büyük olasılıkla felaketi kısa bir süre için erteleyecektir. Yapılandırmanızı daha iyi düzeltin.
scai

Yanıtlar:


25

Linux hafızayı aşırı yüklüyor. Bu, işlemin sistemde gerçekten kullanılabilir olandan daha fazla bellek istemesine izin verdiği anlamına gelir. Bir program malloc () işlevini kullanmaya çalıştığında, çekirdek "Tamam, belleği aldınız" der, ancak ayırmayın. Bellek sadece işlem bu alana bir şeyler yazdığında ayrılacaktır.

Farkı görmek için 2 göstergeniz var: Sanal Bellek ve Yerleşik Bellek. Sanal, işlem tarafından istenen bellektir, Yerleşik, işlem tarafından gerçekten kullanılan bellektir.

Bu sistem ile, "overbooking" girebilir, çekirdek mevcut daha fazla bellek verir. Ardından, sisteminiz 0 bayt boş bellek ve Takas'a geçtiğinde, boş bellek kazanmak için bir süreci feda etmelidir (öldürmelidir) .

İşte o zaman OOM Killer harekete geçer. OOM bir hafızası tüketimine dayalı süreç ve birçok diğer unsurları (ana kazanımlar onun çocuklarının puanın 1/2 seçer; bu bir kök olunan süreç ise, skor 4, vs .. bölünür üzerinde göz Linux- MM.org/OOM_Killer

Dosyayı turarak OOM puanlamasını etkileyebilirsiniz /proc/MySQL_PID/oom_adj. Bunu ayarladığınızda -17, işleminiz asla öldürülmez. Ancak bunu yapmadan önce , MySQL bellek kullanımını sınırlamak için MySQL yapılandırma dosyanızı değiştirmelisiniz. Aksi takdirde, OOM Killer diğer sistem işlemlerini (SSH, crontab, vb ...) öldürür ve sunucunuz çok kararsız bir durumda olur, belki de her şeyden daha kötü olan veri bozulmasına yol açar .

Ayrıca, daha fazla takas kullanmayı düşünebilirsiniz.

[DÜZENLE]

Ayrıca, aşırı yüklenme davranışını şu 2 sistem üzerinden değiştirebilirsiniz:

vm.overcommit_memory
vm.overcommit_ratio

Çekirdek Belgelerinde belirtildiği gibi

overcommit_memory:

Bu değer, bellekte fazla çalışmayı sağlayan bir işaret içerir.

Bu bayrak 0 olduğunda, çekirdek kullanıcı alanı daha fazla bellek istediğinde kalan boş bellek miktarını tahmin etmeye çalışır.

Bu bayrak 1 olduğunda, çekirdek gerçekte bitene kadar her zaman yeterli hafıza olduğunu iddia eder.

Bu bayrak 2 olduğunda, çekirdek, bellekte fazla işlemeyi engellemeye çalışan "asla aşırı yüklenme" ilkesini kullanır. User_reserve_kbytes öğesinin bu politikayı etkilediğini unutmayın.

Bu özellik çok faydalı olabilir, çünkü büyük miktarda hafızayı "her ihtimale karşı" barındıran ve çoğunu kullanmayan birçok program vardır.

Varsayılan değer 0'dır.

Daha fazla bilgi için bkz. Documentation / vm / overcommit-muhasebe ve güvenlik / commoncap.c :: cap_vm_enough_memory ().

overcommit_ratio:

Overcommit_memory öğesi 2 olarak ayarlandığında, işlenen adres alanının takas artı bu fiziksel RAM yüzdesini aşmasına izin verilmez. Yukarıyı görmek.

[/DÜZENLE]


1
Bu doğru cevap. Bunu düzeltmekoom_score_adj için etrafta makaleler görüyorum , ancak puan mekanizmasını tam olarak anlamıyorlar.
3manuek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.