OOM a pesar de la memoria disponible (caché)


12

Nos hemos encontrado con el asesino OOM a pesar de que casi la mitad de nuestra memoria se usa para el caché FS. Hemos estado registrando estadísticas de memoria una vez por minuto (según lo informado por arriba), pero parece que hay mucha disponibilidad.

...

Mem:  15339640k total, 15268304k used,    71336k free,     3152k buffers
Swap:        0k total,        0k used,        0k free,  6608384k cached

Mem:  15339640k total, 14855280k used,   484360k free,    13748k buffers
Swap:        0k total,        0k used,        0k free,  6481852k cached

[OOM killer: postgres killed]

Mem:  15339640k total,  8212200k used,  7127440k free,    32776k buffers
Swap:        0k total,        0k used,        0k free,  2394444k cached

...

Detalles de OOM de syslog:

...
Jun 10 05:45:25 db kernel: [11209156.840462] wal-e invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:25 db kernel: [11209156.840469] wal-e cpuset=/ mems_allowed=0
Jun 10 05:45:25 db kernel: [11209156.840474] Pid: 7963, comm: wal-e Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:25 db kernel: [11209156.840477] Call Trace:
Jun 10 05:45:25 db kernel: [11209156.840498]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:25 db kernel: [11209156.840502]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:25 db kernel: [11209156.840506]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
Jun 10 05:45:25 db kernel: [11209156.840511]  [<ffffffff8111f823>] __alloc_pages_nodemask+0x8c3/0x8e0
Jun 10 05:45:25 db kernel: [11209156.840520]  [<ffffffff81216e00>] ? noalloc_get_block_write+0x30/0x30
Jun 10 05:45:25 db kernel: [11209156.840528]  [<ffffffff811566c6>] alloc_pages_current+0xb6/0x120
Jun 10 05:45:25 db kernel: [11209156.840534]  [<ffffffff81116637>] __page_cache_alloc+0xb7/0xd0
Jun 10 05:45:25 db kernel: [11209156.840539]  [<ffffffff81118602>] filemap_fault+0x212/0x3c0
Jun 10 05:45:25 db kernel: [11209156.840553]  [<ffffffff81138c32>] __do_fault+0x72/0x550
Jun 10 05:45:25 db kernel: [11209156.840557]  [<ffffffff8113c2ea>] handle_pte_fault+0xfa/0x200
Jun 10 05:45:25 db kernel: [11209156.840562]  [<ffffffff8100638e>] ? xen_pmd_val+0xe/0x10
Jun 10 05:45:25 db kernel: [11209156.840567]  [<ffffffff81005309>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
Jun 10 05:45:25 db kernel: [11209156.840571]  [<ffffffff8113d559>] handle_mm_fault+0x269/0x370
Jun 10 05:45:25 db kernel: [11209156.840576]  [<ffffffff8100a56d>] ? xen_force_evtchn_callback+0xd/0x10
Jun 10 05:45:25 db kernel: [11209156.840581]  [<ffffffff8100ad42>] ? check_events+0x12/0x20
Jun 10 05:45:25 db kernel: [11209156.840589]  [<ffffffff8165b3cb>] do_page_fault+0x14b/0x520
Jun 10 05:45:25 db kernel: [11209156.840594]  [<ffffffff81160d64>] ? kmem_cache_free+0x104/0x110
Jun 10 05:45:25 db kernel: [11209156.840600]  [<ffffffff811ba2c8>] ? ep_remove+0xa8/0xc0
Jun 10 05:45:25 db kernel: [11209156.840604]  [<ffffffff811bb133>] ? sys_epoll_ctl+0xb3/0x3d0
Jun 10 05:45:25 db kernel: [11209156.840614]  [<ffffffff81658035>] page_fault+0x25/0x30
Jun 10 05:45:25 db kernel: [11209156.840617] Mem-Info:
Jun 10 05:45:25 db kernel: [11209156.840618] Node 0 DMA per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840622] CPU    0: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840624] CPU    1: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840627] CPU    2: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840629] CPU    3: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840631] Node 0 DMA32 per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840634] CPU    0: hi:  186, btch:  31 usd:  30
Jun 10 05:45:25 db kernel: [11209156.840637] CPU    1: hi:  186, btch:  31 usd:  47
Jun 10 05:45:25 db kernel: [11209156.840639] CPU    2: hi:  186, btch:  31 usd:  15
Jun 10 05:45:25 db kernel: [11209156.840641] CPU    3: hi:  186, btch:  31 usd:   2
Jun 10 05:45:25 db kernel: [11209156.840643] Node 0 Normal per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840646] CPU    0: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840648] CPU    1: hi:  186, btch:  31 usd:  14
Jun 10 05:45:25 db kernel: [11209156.840650] CPU    2: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840653] CPU    3: hi:  186, btch:  31 usd:   1
Jun 10 05:45:25 db kernel: [11209156.840658] active_anon:3616567 inactive_anon:4798 isolated_anon:0
Jun 10 05:45:25 db kernel: [11209156.840660]  active_file:98 inactive_file:168 isolated_file:20
Jun 10 05:45:25 db kernel: [11209156.840661]  unevictable:1597 dirty:73 writeback:0 unstable:0
Jun 10 05:45:25 db kernel: [11209156.840662]  free:16921 slab_reclaimable:17631 slab_unreclaimable:7534
Jun 10 05:45:25 db kernel: [11209156.840663]  mapped:1614529 shmem:1613928 pagetables:124012 bounce:0
Jun 10 05:45:25 db kernel: [11209156.840666] Node 0 DMA free:7888kB min:4kB low:4kB high:4kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:7632kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840681] lowmem_reserve[]: 0 4016 15112 15112
Jun 10 05:45:25 db kernel: [11209156.840686] Node 0 DMA32 free:48368kB min:4176kB low:5220kB high:6264kB active_anon:3776804kB inactive_anon:28kB active_file:0kB inactive_file:20kB unevictable:932kB isolated(anon):0kB isolated(file):0kB present:4112640kB mlocked:932kB dirty:0kB writeback:0kB mapped:1458536kB shmem:1458632kB slab_reclaimable:17604kB slab_unreclaimable:8088kB kernel_stack:1872kB pagetables:190616kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:437 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840698] lowmem_reserve[]: 0 0 11095 11095
Jun 10 05:45:25 db kernel: [11209156.840703] Node 0 Normal free:11428kB min:11548kB low:14432kB high:17320kB active_anon:10689464kB inactive_anon:19164kB active_file:528kB inactive_file:652kB unevictable:5456kB isolated(anon):0kB isolated(file):80kB present:11362176kB mlocked:5456kB dirty:292kB writeback:0kB mapped:4999580kB shmem:4997080kB slab_reclaimable:52920kB slab_unreclaimable:22048kB kernel_stack:2584kB pagetables:305432kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:1974 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840715] lowmem_reserve[]: 0 0 0 0
Jun 10 05:45:25 db kernel: [11209156.840720] Node 0 DMA: 2*4kB 3*8kB 1*16kB 3*32kB 3*64kB 3*128kB 2*256kB 1*512kB 2*1024kB 2*2048kB 0*4096kB = 7888kB
Jun 10 05:45:25 db kernel: [11209156.840752] Node 0 DMA32: 5813*4kB 2636*8kB 114*16kB 15*32kB 5*64kB 1*128kB 1*256kB 0*512kB 1*1024kB 0*2048kB 0*4096kB = 48372kB
Jun 10 05:45:25 db kernel: [11209156.840776] Node 0 Normal: 1888*4kB 10*8kB 46*16kB 4*32kB 3*64kB 2*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 11760kB
Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages
Jun 10 05:45:25 db kernel: [11209156.840790] 0 pages in swap cache
Jun 10 05:45:25 db kernel: [11209156.840801] Swap cache stats: add 0, delete 0, find 0/0
Jun 10 05:45:25 db kernel: [11209156.840803] Free swap  = 0kB
Jun 10 05:45:25 db kernel: [11209156.840805] Total swap = 0kB
Jun 10 05:45:25 db kernel: [11209156.909794] 3934192 pages RAM
Jun 10 05:45:25 db kernel: [11209156.909804] 99282 pages reserved
Jun 10 05:45:25 db kernel: [11209156.909809] 18899146 pages shared
Jun 10 05:45:25 db kernel: [11209156.909811] 2198511 pages non-shared
Jun 10 05:45:25 db kernel: [11209156.909817] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
Jun 10 05:45:25 db kernel: [11209156.909835] [  332]     0   332     4308      109   1       0             0 upstart-udev-br
Jun 10 05:45:25 db kernel: [11209156.909845] [  346]     0   346     5384      271   2     -17         -1000 udevd
Jun 10 05:45:25 db kernel: [11209156.909851] [  408]     0   408     5364      174   2     -17         -1000 udevd
...
Jun 10 05:45:25 db kernel: [11209156.910703] [ 7963]   111  7963    17456     2966   0       0             0 wal-e
Jun 10 05:45:25 db kernel: [11209156.910707] [ 7968]   111  7968  1639372     2351   3       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910711] [ 7969]   111  7969  1639371     1934   2       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910716] Out of memory: Kill process 12443 (postgres) score 418 or sacrifice child
Jun 10 05:45:25 db kernel: [11209156.910733] Killed process 12443 (postgres) total-vm:6555152kB, anon-rss:4600kB, file-rss:6396572kB
Jun 10 05:45:30 db kernel: [11209159.293083] postgres invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:31 db kernel: [11209159.293091] postgres cpuset=/ mems_allowed=0
Jun 10 05:45:31 db kernel: [11209159.293095] Pid: 6508, comm: postgres Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:31 db kernel: [11209159.293098] Call Trace:
Jun 10 05:45:31 db kernel: [11209159.293111]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:31 db kernel: [11209159.293115]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:31 db kernel: [11209159.293119]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
...

Podemos intentar aumentar la resolución de estos a aproximadamente una vez por segundo, pero ¿habría alguna razón para una OOM aquí? (Hemos visto http://bl0rg.krunch.be/oom-frag.html pero estamos trabajando con cantidades absolutas de memoria mucho más grandes, la mayoría de las cuales son tomadas por el caché FS del núcleo).

También incluye partes relevantes de nuestro postgresql.confsiguiente:

shared_buffers = 6GB
effective_cache_size = 8GB


Um ... 3.2.0-43? Tiempo de actualizacion. El asesino OOM ha pasado por muchos (demasiados) cambios a lo largo del tiempo. Algunas versiones eran realmente muy cerebrales sobre la contabilidad del uso de memoria compartida ... como PostgreSQL 9.2 y versiones anteriores shared_buffers.
Craig Ringer

@CraigRinger Lamentablemente, existen otras consideraciones, como quedarse con el kernel en la distribución Ubuntu 12.04 para LTS, compatibilidad, actualizaciones de seguridad, etc. Simplemente nos interesa si alguien sabe cómo explicar lo que está sucediendo aquí; si ayuda, pretenda que estamos no estoy interesado en cambiar el status quo / hacer que el problema desaparezca. Por cierto shared_bufferstodavía está en PG9.3.
Yang

shared_bufferstodavía está en 9.3, pero ya no es la memoria compartida POSIX en 9.3. Ha sido reemplazado por una mmap()edregión anónima . Eso soluciona algunos problemas de configuración del kernel y problemas de fijación, aunque dudo que haga que el asesino de OOM esté menos confundido.
Craig Ringer

1
Posiblemente un duplicado de serverfault.com/questions/288319/… , que tiene una respuesta potencial.
richvdh

Respuestas:


4

Parece que usted (y yo en un caso con síntomas muy similares) realmente se ha quedado sin memoria y el cachednúmero lo ha confundido .

Aparentemente, hay casos en que Linux no libera caché de disco grande cuando aumenta la demanda de memoria

En particular (realmente no entiendo por qué), postgres ' shared_bufferspuede ser reportado en "Caché" (el caché de la página). En su caso, el 6481852k cachedin topcoincide con esta línea en el registro del asesino de OOM:

Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages

(1615243 * 4KB ~ = 6481852k), lo que significa que la memoria caché de la página no se eliminó antes de invocar OOM-killer.

Sin embargo, hay pocas páginas respaldadas por archivos (supongo que active_file:98 inactive_file:168es similar a Active (file) / Inactive (file) / proc / meminfo ), por lo que no son las páginas descartables que conocemos y amamos.

La publicación en https://www.depesz.com/2012/06/09/how-much-ram-is-postgresql-using/ muestra un ejemplo de sesión en la que cerrar postgres conduce a la reducción de "en caché" por el tamaño de shared_buffers(desplácese a "Y la mayor parte salió del caché del disco, como se esperaba, porque se usó para shared_buffers" ), desafortunadamente no indica la versión de postgres ni el núcleo que se usó para el experimento.

Estoy usando 3.13.0-67 x86_64 con PG 9.3. En 9.3 cambiaron de usar la memoria compartida Sys V ( shmget) a anónimommap(...R+W, MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE...)+fork() (en 9.4 esto se hizo configurable a través de dynamic_shared_memory_type ). Pero no pude encontrar ninguna explicación de por qué se supone que estos mmap () se muestran en "caché" y por qué, solo https://access.redhat.com/solutions/406773 que dice "Cached: Memory in the pagecache (caché de disco y memoria compartida) "

Dado que hay muchos tipos de memoria compartida , estoy iluminado y confundido ...


Después de varios años, esta es una respuesta mucho mejor, gracias. Todavía queda la pregunta de por qué esto se contabiliza como almacenado en caché, pero estoy marcando esto como aceptado por ahora.
Yang

8
  1. Por amor a todo lo bueno del mundo, configure el espacio de intercambio en sus servidores .
    Realmente necesitas espacio de intercambio . No soy el único que lo dice , es casi una verdad universal por aquí . (<- Esos son tres enlaces) Por
    supuesto, debe tener suficiente RAM para que su servidor de base de datos no se intercambie regularmente , si no lo hace, la solución es dinero (que le lleva a su proveedor y lo utiliza para adquirir más RAM) .

  2. Dado que ahora tiene una RAM adecuada e intercambia para usar si algo sale mal, puede deshabilitar el asesino OOM (deshabilitando el exceso de memoria), como las personas de Postgres le dicen que haga .
    (También puede aplicar su solución alternativa y decirle al OOM-Killer que nunca mate a Postgres, pero solo está jugando a la ruleta rusa con el resto de los procesos de su sistema ...)

  3. (opcional) Escriba una respuesta en Falla del servidor que detalle por qué el comportamiento predeterminado en la mayoría de las distribuciones de Linux es Malo, Incorrecto y viola la especificación POSIX de cómo se supone que se comporta malloc () . Repítalo hasta que todos estén cansados ​​de escucharlo.


También tenga en cuenta que la memoria en caché del núcleo está disponible para que postgres (o cualquier otra aplicación) la use; debe tenerla en cuenta como memoria libre / disponible en sus cálculos.

Si tuviera que arriesgarme a adivinar lo que está sucediendo aquí, diría que tienes una consulta compleja, Postgres está solicitando RAM para ejecutarla, y en lugar de decir "No tengo esa RAM" Linux le dice a Postgres "Claro, puedes tenerlo."
Luego, cuando Postgres realmente intenta usar la RAM, (supuestamente) se da cuenta de que Linux se da cuenta de que NO TIENE la RAM que prometió a Postgres (porque está sobrecomprometida): se le dice al asesino de OOM que libere la RAM y mata obedientemente el programa usando la mayor cantidad de memoria: su servidor de base de datos.

Postgres es un programa bien diseñado. Si se le dice que no puede tener la RAM que está solicitando, lo manejará con gracia (ya sea con menos, o abortando con un mensaje para el usuario).


44
Gracias por la elaboración del intercambio, pero esto no responde a mi pregunta de por qué esto está sucediendo en primer lugar . Sí, entiendo la premisa básica de que Linux se compromete de forma predeterminada y que OOM es cuando nos quedamos sin RAM; podría haber dicho esto en mi pregunta original. Pero la pregunta es ¿por qué está funcionando cuando todavía tengo mucha RAM (gran parte de la misma solo está en el caché FS)? Supongamos que ni siquiera estoy interesado en cambiar nada: que el asesino OOM está bien, siempre y cuando comprenda por qué se está activando.
Yang

2
Después de revisar los enlaces, desafortunadamente hay una serie de afirmaciones sin respaldar evidencia o explicaciones técnicas concretas. Ciertamente, hay muchos entornos Linux en los que el intercambio ni siquiera es una opción (ejemplo: no busque más allá de un Live CD donde ya no hay una partición de intercambio local existente para reutilizar). Además, no estamos interesados ​​en permitir el intercambio basado en nuestras propias experiencias y entorno; preferimos tener la OOM. Se agradecería una respuesta a la pregunta original.
Yang

1
@Yang Supongo que si está creando un servidor para Postgres, querrá seguir las recomendaciones del proyecto Postgres. Mi respuesta es hacer lo que te dicen (apaga al asesino OOM). Si desea esperar y ver si alguien le ofrece una respuesta diferente, ciertamente es libre de hacerlo, pero no me siento cómodo ofreciendo ninguna otra solución: en mi opinión, el asesino de OOM es malo, incorrecto y viola POSIX. Puede ser aceptable en una computadora de escritorio / estación de trabajo, pero deshabilitarlo en los servidores es, en mi opinión, lo correcto.
voretaq7

2
Me he encontrado con esta situación en un servidor que tiene intercambio, y después de saturar la memoria disponible + intercambio, se utilizó el asesino OOM en lugar del núcleo que reclamaba la memoria "en caché", que obviamente estaba de alguna manera bloqueada. Nunca resolví el problema, pero la pregunta original de @ Yang no se responde aquí.
Patrick

2
El intercambio no es la respuesta, solo hace que el problema aparezca más tarde. Necesita intercambiar cuando la RAM está llena y necesita OOM Killer cuando RAM + swap se llena. Si la cantidad de intercambio es cero, necesita OOM Killer antes, pero no puede evitar OOM Killer con swap.
Mikko Rantalainen
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.