OOM Killer - ucciso il server MySQL


10

Su uno dei nostri master MySQL, OOM Killer è stato invocato e ucciso il server MySQL, causando gravi interruzioni. Di seguito è riportato il registro del 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

Questa macchina ha 64 GB di RAM.

Di seguito sono riportate le variabili di configurazione mysql:

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

Ad eccezione di alcuni dei plugin nagios e degli script di raccolta delle metriche, nient'altro viene eseguito su questa macchina. Qualcuno può aiutarmi a scoprire perché il killer OOM è stato invocato e come posso impedire che venga invocato in futuro. Esiste un modo per dire a Killer OOM di non uccidere il server mysql. So che possiamo impostare un oom_adjvalore molto inferiore per un processo per impedire che venga ucciso dal killer OOM. Ma c'è un altro modo per impedirlo.


2
L'utilizzo della memoria sarà superiore a 48G+ 512M+ 64Mperché ci sono anche alcune spese generali e altre strutture da considerare; c'era una formula per questo da qualche parte ma non riesco a trovarla in questo momento. Non sono sicuro se questo potrebbe causare il soffiaggio 64G. Solo per essere sicuro, freeconferma che 64Gsono disponibili in primo luogo?
frostschutz,

@frostschutz: sì, il comando gratuito mostra 64G.
pradeepchhetri,

Dire all'OOM Killer di non uccidere mysqld molto probabilmente ritarderà il disastro per un breve momento. Meglio correggere la tua configurazione.
scai,

Risposte:


25

Linux sovraccarica la memoria. Ciò significa che consente al processo di richiedere più memoria di quella realmente disponibile sul sistema. Quando un programma prova a malloc (), il kernel dice "OK hai la memoria", ma non riservarlo. La memoria sarà riservata solo quando il processo scriverà qualcosa in questo spazio.

Per vedere la differenza, hai 2 indicatori: Memoria virtuale e Memoria residente. Virtuale è la memoria richiesta dal processo, Resident è la memoria realmente utilizzata dal processo.

Con questo sistema, si può andare in "overbooking", il kernel concede più memoria di quella disponibile. Quindi, quando il sistema passa su 0 byte di memoria libera e Swap, deve sacrificare (uccidere) un processo per ottenere memoria libera.

Questo è quando OOM Killer entra in azione. OOM seleziona un processo in base al consumo di memoria e molti altri elementi (il genitore guadagna 1/2 del punteggio dei suoi figli; se si tratta di un processo di proprietà radice, il punteggio viene diviso per 4, ecc. Dai un'occhiata a Linux- MM.org/OOM_Killer

Puoi influenzare il punteggio OOM sintonizzando il /proc/MySQL_PID/oom_adjfile. Impostandolo su -17, il tuo processo non verrà mai ucciso. Ma prima di farlo , dovresti modificare il tuo file di configurazione MySQL per limitare l'utilizzo della memoria MySQL. Altrimenti, OOM Killer ucciderà altri processi di sistema (come SSH, crontab, ecc ...) e il tuo server si troverà in uno stato molto instabile, portando forse alla corruzione dei dati che è peggio di qualsiasi altra cosa.

Inoltre, potresti considerare di utilizzare più swap.

[MODIFICARE]

Puoi anche modificare il comportamento di overcommit tramite questi 2 sysctls:

vm.overcommit_memory
vm.overcommit_ratio

Come indicato nella documentazione del kernel

overcommit_memory:

Questo valore contiene un flag che abilita il sovraccarico della memoria.

Quando questo flag è 0, il kernel tenta di stimare la quantità di memoria libera rimasta quando userspace richiede più memoria.

Quando questo flag è 1, il kernel finge che ci sia sempre abbastanza memoria fino a quando non si esaurisce.

Quando questo flag è 2, il kernel usa una politica di "non overcommit" che tenta di prevenire qualsiasi sovraccarico di memoria. Si noti che user_reserve_kbytes influisce su questo criterio.

Questa funzione può essere molto utile perché ci sono molti programmi che malloc () enormi quantità di memoria "just-in-case" e non ne usano molto.

Il valore predefinito è 0.

Vedi Documentazione / vm / overcommit-accounting e security / commoncap.c :: cap_vm_enough_memory () per maggiori informazioni.

overcommit_ratio:

Quando overcommit_memory è impostato su 2, lo spazio degli indirizzi impegnati non può superare lo scambio più questa percentuale di RAM fisica. Vedi sopra.

[/MODIFICARE]


1
Questa è la risposta esatta. Ho visto articoli in giro usando oom_score_adjper risolvere questo problema , ma non capiscono veramente il meccanismo del punteggio.
3manuek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.