OOM Killer - mató el servidor MySQL


10

En uno de nuestros maestros de MySQL, OOM Killer fue invocado y mató al servidor MySQL, lo que provocó una gran interrupción. El siguiente es el 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

Esta máquina tiene 64 GB de RAM.

Las siguientes son las variables de configuración de mysql:

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

Excepto algunos de los complementos de nagios y scripts de recopilación de métricas, nada más se ejecuta en esta máquina. ¿Puede alguien ayudarme a averiguar por qué se invocó al asesino de OOM y cómo puedo evitar que se invoque en el futuro? ¿Hay alguna manera de decirle al asesino de OOM que no mate el servidor mysql? Sé que podemos establecer un oom_adjvalor muy bajo para un proceso para evitar que sea asesinado por OOM asesino. Pero, ¿hay alguna otra forma de evitar esto?


2
El uso de memoria será mayor que 48G+ 512M+ 64Mporque también hay algunos gastos generales y otras estructuras a considerar; había una fórmula para esto en alguna parte, pero no puedo encontrarla en este momento. No estoy seguro si esto haría que explote 64G. Sin embargo, solo para asegurarse, ¿ freeconfirma que 64Gestán disponibles en primer lugar?
frostschutz

@frostschutz: sí, el comando gratuito muestra 64G.
pradeepchhetri

Decirle al OOM Killer que no mate a mysqld probablemente retrasará el desastre por un breve momento. Mejor arregle su configuración.
scai

Respuestas:


25

Linux hace un exceso de memoria. Eso significa que permite que el proceso solicite más memoria de la que realmente está disponible en el sistema. Cuando un programa intenta malloc (), el núcleo dice "OK, tienes la memoria", pero no la reservas. La memoria solo se reservará cuando el proceso escriba algo en este espacio.

Para ver la diferencia, tiene 2 indicadores: memoria virtual y memoria residente. Virtual es la memoria solicitada por el proceso, Resident es la memoria realmente utilizada por el proceso.

Con este sistema, puede entrar en "overbooking", el núcleo otorga más memoria de la disponible. Luego, cuando su sistema va a 0 bytes de memoria libre y Swap, debe sacrificar (matar) un proceso para ganar memoria libre.

Ahí es cuando OOM Killer entra en acción. El OOM selecciona un proceso en función de su consumo de memoria y muchos otros elementos (el padre gana la mitad del puntaje de sus hijos; si es un proceso propiedad de la raíz, el puntaje se divide por 4, etc. Eche un vistazo a Linux- MM.org/OOM_Killer

Puede influir en la puntuación OOM ajustando el /proc/MySQL_PID/oom_adjarchivo. Al configurarlo -17, su proceso nunca será eliminado. Pero antes de hacerlo , debe ajustar su archivo de configuración de MySQL para limitar el uso de memoria de MySQL. De lo contrario, el OOM Killer matará a otros procesos del sistema (como SSH, crontab, etc.) y su servidor estará en un estado muy inestable, lo que puede provocar corrupción de datos que es peor que cualquier otra cosa.

Además, puede considerar usar más swap.

[EDITAR]

También puede cambiar su comportamiento de exceso de compromiso a través de estos 2 sysctls:

vm.overcommit_memory
vm.overcommit_ratio

Como se indica en la documentación del núcleo

overcommit_memory:

Este valor contiene un indicador que habilita el compromiso excesivo de memoria.

Cuando este indicador es 0, el núcleo intenta estimar la cantidad de memoria libre que queda cuando el espacio de usuario solicita más memoria.

Cuando este indicador es 1, el kernel finge que siempre hay suficiente memoria hasta que realmente se agote.

Cuando este indicador es 2, el kernel utiliza una política de "nunca comprometerse demasiado" que intenta evitar cualquier exceso de memoria. Tenga en cuenta que user_reserve_kbytes afecta esta política.

Esta característica puede ser muy útil porque hay muchos programas que malloc () enormes cantidades de memoria "por si acaso" y no utilizan gran parte de ella.

El valor predeterminado es 0.

Consulte Documentation / vm / overcommit-accounting and security / commoncap.c :: cap_vm_enough_memory () para obtener más información.

overcommit_ratio:

Cuando overcommit_memory se establece en 2, no se permite que el espacio de direcciones comprometido exceda el intercambio más este porcentaje de RAM física. Véase más arriba.

[/EDITAR]


1
Esta es la respuesta correcta. He estado viendo artículos sobre cómo usarlo oom_score_adjpara solucionar esto, pero realmente no entienden el mecanismo de puntuación.
3manuek
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.