
Tengo un único archivo de 50 GB en el servidor_A y lo estoy copiando en el servidor_B. Corro
server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file
Server_B tiene 32 GB de RAM con 2 GB de intercambio. Está mayormente inactivo y debería haber tenido mucha RAM libre. Tiene mucho espacio en disco. Aproximadamente a 32 GB, la transferencia se cancela porque el lado remoto cerró la conexión.
Server_B ahora se ha desconectado de la red. Le pedimos al centro de datos que lo reinicie. Cuando miro el registro del kernel antes de que fallara, veo que estaba usando 0 bytes de intercambio y que la lista de procesos estaba usando muy poca memoria (el proceso rsync figuraba como usando 600 KB de RAM), pero oom_killer estaba volviéndose loco, y lo último en el registro es donde mata el proceso de lectura del kernel de metalog.
Este es el kernel 3.2.59, de 32 bits (por lo que, de todos modos, ningún proceso puede asignar más de 4 GB).
Es casi como si Linux le diera más prioridad al almacenamiento en caché que a los demonios en ejecución de larga duración. ¿¿Lo que da?? ¿Y cómo puedo evitar que vuelva a suceder?
Aquí está el resultado de oom_killer:
Sep 23 02:04:16 [kernel] [1772321.850644] clamd invoked oom-killer: gfp_mask=0x84d0, order=0, oom_adj=0, oom_score_adj=0
Sep 23 02:04:16 [kernel] [1772321.850649] Pid: 21832, comm: clamd Tainted: G C 3.2.59 #21
Sep 23 02:04:16 [kernel] [1772321.850651] Call Trace:
Sep 23 02:04:16 [kernel] [1772321.850659] [<c01739ac>] ? dump_header+0x4d/0x160
Sep 23 02:04:16 [kernel] [1772321.850662] [<c0173bf3>] ? oom_kill_process+0x2e/0x20e
Sep 23 02:04:16 [kernel] [1772321.850665] [<c0173ff8>] ? out_of_memory+0x225/0x283
Sep 23 02:04:16 [kernel] [1772321.850668] [<c0176438>] ? __alloc_pages_nodemask+0x446/0x4f4
Sep 23 02:04:16 [kernel] [1772321.850672] [<c0126525>] ? pte_alloc_one+0x14/0x2f
Sep 23 02:04:16 [kernel] [1772321.850675] [<c0185578>] ? __pte_alloc+0x16/0xc0
Sep 23 02:04:16 [kernel] [1772321.850678] [<c0189e74>] ? vma_merge+0x18d/0x1cc
Sep 23 02:04:16 [kernel] [1772321.850681] [<c01856fa>] ? handle_mm_fault+0xd8/0x15d
Sep 23 02:04:16 [kernel] [1772321.850685] [<c012305a>] ? do_page_fault+0x20e/0x361
Sep 23 02:04:16 [kernel] [1772321.850688] [<c018a9c4>] ? sys_mmap_pgoff+0xa2/0xc9
Sep 23 02:04:16 [kernel] [1772321.850690] [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850694] [<c08ba7e6>] ? error_code+0x5a/0x60
Sep 23 02:04:16 [kernel] [1772321.850697] [<c08b0000>] ? cpuid4_cache_lookup_regs+0x372/0x3b2
Sep 23 02:04:16 [kernel] [1772321.850700] [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850701] Mem-Info:
Sep 23 02:04:16 [kernel] [1772321.850703] DMA per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850704] CPU 0: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850706] CPU 1: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850707] CPU 2: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850709] CPU 3: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850711] CPU 4: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850713] CPU 5: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850714] CPU 6: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850716] CPU 7: hi: 0, btch: 1 usd: 0
Sep 23 02:04:16 [kernel] [1772321.850718] Normal per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850719] CPU 0: hi: 186, btch: 31 usd: 70
Sep 23 02:04:16 [kernel] [1772321.850721] CPU 1: hi: 186, btch: 31 usd: 116
Sep 23 02:04:16 [kernel] [1772321.850723] CPU 2: hi: 186, btch: 31 usd: 131
Sep 23 02:04:16 [kernel] [1772321.850724] CPU 3: hi: 186, btch: 31 usd: 76
Sep 23 02:04:16 [kernel] [1772321.850726] CPU 4: hi: 186, btch: 31 usd: 29
Sep 23 02:04:16 [kernel] [1772321.850728] CPU 5: hi: 186, btch: 31 usd: 61
Sep 23 02:04:16 [kernel] [1772321.850731] CPU 7: hi: 186, btch: 31 usd: 17
Sep 23 02:04:16 [kernel] [1772321.850733] HighMem per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850734] CPU 0: hi: 186, btch: 31 usd: 2
Sep 23 02:04:16 [kernel] [1772321.850736] CPU 1: hi: 186, btch: 31 usd: 69
Sep 23 02:04:16 [kernel] [1772321.850738] CPU 2: hi: 186, btch: 31 usd: 25
Sep 23 02:04:16 [kernel] [1772321.850739] CPU 3: hi: 186, btch: 31 usd: 27
Sep 23 02:04:16 [kernel] [1772321.850741] CPU 4: hi: 186, btch: 31 usd: 7
Sep 23 02:04:16 [kernel] [1772321.850743] CPU 5: hi: 186, btch: 31 usd: 188
Sep 23 02:04:16 [kernel] [1772321.850744] CPU 6: hi: 186, btch: 31 usd: 25
Sep 23 02:04:16 [kernel] [1772321.850746] CPU 7: hi: 186, btch: 31 usd: 158
Sep 23 02:04:16 [kernel] [1772321.850750] active_anon:117913 inactive_anon:9942 isolated_anon:0
Sep 23 02:04:16 [kernel] [1772321.850751] active_file:106466 inactive_file:7784521 isolated_file:0
Sep 23 02:04:16 [kernel] [1772321.850752] unevictable:40 dirty:0 writeback:61 unstable:0
Sep 23 02:04:16 [kernel] [1772321.850753] free:143494 slab_reclaimable:128312 slab_unreclaimable:4089
Sep 23 02:04:16 [kernel] [1772321.850754] mapped:6706 shmem:308 pagetables:915 bounce:0
Sep 23 02:04:16 [kernel] [1772321.850759] DMA free:3624kB min:140kB low:172kB high:208kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolate
d(file):0kB present:15808kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:240kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tm
p:0kB pages_scanned:0 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850763] lowmem_reserve[]: 0 869 32487 32487
Sep 23 02:04:16 [kernel] [1772321.850770] Normal free:8056kB min:8048kB low:10060kB high:12072kB active_anon:0kB inactive_anon:0kB active_file:248kB inactive_file:388kB unevictable:0kB isolated(anon)
:0kB isolated(file):0kB present:890008kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:513008kB slab_unreclaimable:16356kB kernel_stack:1888kB pagetables:3660kB unstable:0
kB bounce:0kB writeback_tmp:0kB pages_scanned:1015 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850774] lowmem_reserve[]: 0 0 252949 252949
Sep 23 02:04:16 [kernel] [1772321.850785] lowmem_reserve[]: 0 0 0 0
Sep 23 02:04:16 [kernel] [1772321.850788] DMA: 0*4kB 7*8kB 3*16kB 6*32kB 4*64kB 6*128kB 5*256kB 2*512kB 0*1024kB 0*2048kB 0*4096kB = 3624kB
Sep 23 02:04:16 [kernel] [1772321.850795] Normal: 830*4kB 80*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 8056kB
Sep 23 02:04:16 [kernel] [1772321.850802] HighMem: 13*4kB 14*8kB 2*16kB 2*32kB 0*64kB 0*128kB 2*256kB 2*512kB 3*1024kB 0*2048kB 136*4096kB = 561924kB
Sep 23 02:04:16 [kernel] [1772321.850809] 7891360 total pagecache pages
Sep 23 02:04:16 [kernel] [1772321.850811] 0 pages in swap cache
Sep 23 02:04:16 [kernel] [1772321.850812] Swap cache stats: add 0, delete 0, find 0/0
Sep 23 02:04:16 [kernel] [1772321.850814] Free swap = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.850815] Total swap = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.949081] 8650736 pages RAM
Sep 23 02:04:16 [kernel] [1772321.949084] 8422402 pages HighMem
Sep 23 02:04:16 [kernel] [1772321.949085] 349626 pages reserved
Sep 23 02:04:16 [kernel] [1772321.949086] 7885006 pages shared
Sep 23 02:04:16 [kernel] [1772321.949087] 316864 pages non-shared
Sep 23 02:04:16 [kernel] [1772321.949089] [ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name
(rest of process list omitted)
Sep 23 02:04:16 [kernel] [1772321.949656] [14579] 0 14579 579 171 5 0 0 rsync
Sep 23 02:04:16 [kernel] [1772321.949662] [14580] 0 14580 677 215 5 0 0 rsync
Sep 23 02:04:16 [kernel] [1772321.949669] [21832] 113 21832 42469 37403 0 0 0 clamd
Sep 23 02:04:16 [kernel] [1772321.949674] Out of memory: Kill process 21832 (clamd) score 4 or sacrifice child
Sep 23 02:04:16 [kernel] [1772321.949679] Killed process 21832 (clamd) total-vm:169876kB, anon-rss:146900kB, file-rss:2712kB
Aquí está el resultado 'superior' después de repetir mi comando rsync como usuario no root:
top - 03:05:55 up 8:43, 2 users, load average: 0.04, 0.08, 0.09
Tasks: 224 total, 1 running, 223 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0% us, 0.0% sy, 0.0% ni, 99.9% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 33204440k total, 32688600k used, 515840k free, 108124k buffers
Swap: 1959892k total, 0k used, 1959892k free, 31648080k cached
Aquí están los parámetros de sysctl vm:
# sysctl -a | grep '^vm'
vm.overcommit_memory = 0
vm.panic_on_oom = 0
vm.oom_kill_allocating_task = 0
vm.oom_dump_tasks = 1
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.dirty_background_ratio = 1
vm.dirty_background_bytes = 0
vm.dirty_ratio = 0
vm.dirty_bytes = 15728640
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.nr_pdflush_threads = 0
vm.swappiness = 60
vm.lowmem_reserve_ratio = 256 32 32
vm.drop_caches = 0
vm.min_free_kbytes = 8192
vm.percpu_pagelist_fraction = 0
vm.max_map_count = 65530
vm.laptop_mode = 0
vm.block_dump = 0
vm.vfs_cache_pressure = 100
vm.legacy_va_layout = 0
vm.stat_interval = 1
vm.mmap_min_addr = 4096
vm.vdso_enabled = 2
vm.highmem_is_dirtyable = 0
vm.scan_unevictable_pages = 0
Respuesta1
Entonces, leamos el resultado final y veamos qué se puede aprender de allí.
Al analizar los registros asesinos de OOM, es importante observar qué lo desencadenó. La primera línea de su registro nos da algunas pistas:
[núcleo] [1772321.850644] clamd invocó a oom-killer:gfp_mask=0x84d0, orden=0
order=0
nos está diciendo cuánta memoria se está solicitando. La administración de memoria del kernel solo puede administrar números de página en potencias de 2, por lo que clad ha solicitado 2 0 páginas de memoria o 4 KB.
Los dos bits más bajos de GFP_MASK (obtener máscara de página gratuita) constituyen el llamadomáscara de zona decirle al asignador de qué zona obtener la memoria:
Flag value Description
0x00u 0 implicitly means allocate from ZONE_NORMAL
__GFP_DMA 0x01u Allocate from ZONE_DMA if possible
__GFP_HIGHMEM 0x02u Allocate from ZONE_HIGHMEM if possible
Zonas de memoriaes un concepto creado principalmente por razones de compatibilidad. En una vista simplificada, hay tres zonas para un Kernel x86:
Memory range Zone Purpose
0-16 MB DMA Hardware compatibility (devices)
16 - 896 MB NORMAL space directly addressable by the Kernel, userland
> 896 MB HIGHMEM userland, space addressable by the Kernel via kmap() calls
En su caso, la máscara de zona es 0, lo que significa que clad está solicitando memoria de ZONE_NORMAL
.
Las otras banderas están resolviendo
/*
* Action modifiers - doesn't change the zoning
*
* __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt
* _might_ fail. This depends upon the particular VM implementation.
*
* __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
* cannot handle allocation failures.
*
* __GFP_NORETRY: The VM implementation must not retry indefinitely.
*/
#define __GFP_WAIT 0x10u /* Can wait and reschedule? */
#define __GFP_HIGH 0x20u /* Should access emergency pools? */
#define __GFP_IO 0x40u /* Can start physical IO? */
#define __GFP_FS 0x80u /* Can call down to low-level FS? */
#define __GFP_COLD 0x100u /* Cache-cold page required */
#define __GFP_NOWARN 0x200u /* Suppress page allocation failure warning */
#define __GFP_REPEAT 0x400u /* Retry the allocation. Might fail */
#define __GFP_NOFAIL 0x800u /* Retry for ever. Cannot fail */
#define __GFP_NORETRY 0x1000u /* Do not retry. Might fail */
#define __GFP_NO_GROW 0x2000u /* Slab internal usage */
#define __GFP_COMP 0x4000u /* Add compound page metadata */
#define __GFP_ZERO 0x8000u /* Return zeroed page on success */
#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
#define __GFP_NORECLAIM 0x20000u /* No realy zone reclaim during allocation */
de acuerdo con laDocumentación de Linux MM, por lo que su solicitud tiene las banderas para GFP_ZERO
, GFP_REPEAT
, GFP_FS
y , por lo que no es particularmente exigente.GFP_IO
GFP_WAIT
Entonces, ¿qué pasa ZONE_NORMAL
? Algunas estadísticas genéricas se pueden encontrar más adelante en la salida de OOM:
[núcleo] [1772321.850770] Normallibre: 8056 kB mínimo: 8048 kB bajo: 10060 kBalto:12072kB active_anon:0kB inactive_anon:0kB archivo_activo:248kB archivo_inactivo:388kB inevitable:0kB aislado(anon):0kB aislado(archivo):0kB presente:890008kB
Lo notable aquí es quefree
está a solo 8K demin
y muy por debajolow
. Esto significa que el administrador de memoria de su host está en problemas y kswapd ya debería estar intercambiando páginas tal como está en elamarillofase del siguiente gráfico:
Aquí se proporciona más información sobre la fragmentación de la memoria de la zona:
[núcleo] [1772321.850795] Normal: 830*4kB 80*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 8056kB
Básicamente, indica que tiene una única página contigua de 4 MB y el resto está muy fragmentado principalmente en páginas de 4 KB.
Así que recapitulemos:
- tiene un proceso de área de usuario (
clamd
) del que obtiene memoria,ZONE_NORMAL
mientras que la asignación de memoria sin privilegios generalmente se realizaría desdeZONE_HIMEM
- el administrador de memoria debería haber podido en esta etapa entregar la página 4K solicitada, aunque parece que tiene una presión de memoria significativa en
ZONE_NORMAL
- el sistema, por
kswapd
las reglas,deberíaHe visto alguna actividad de paginación de antemano, pero no se intercambia nada, incluso bajo presión de memoria enZONE_NORMAL
, sin causa aparente - Ninguno de los anteriores proporciona una razón definitiva de por qué
oom-killer
se ha invocado.
Todo esto parece bastante extraño, pero al menos debe estar relacionado con lo que se describe ensección 2.5 del excelente libro de John O'Gorman "Understanding the Linux Virtual Memory Manager":
Como el espacio de direcciones utilizable por el kernel (ZONE_NORMAL) es de tamaño limitado, el kernel admite el concepto de memoria alta. [...] Para acceder a la memoria entre el rango de 1GiB y 4GiB, el kernel asigna temporalmente páginas de memoria alta a ZONE_NORMAL con kmap(). [...]
Eso significa que para describir 1 GiB de memoria, se requieren aproximadamente 11 MiB de memoria del kernel. Así, con 16GiB, se consumen 176MiB de memoria, lo que ejerce una presión significativa sobre ZONE_NORMAL. Esto no suena tan mal hasta que se tengan en cuenta otras estructuras que utilizan ZONE_NORMAL. Incluso las estructuras muy pequeñas, como las entradas de tablas de páginas (PTE), requieren alrededor de 16 MiB en el peor de los casos.Esto hace que 16GiB sea aproximadamente el límite práctico de memoria física disponible en Linux en un x86..
(el énfasis es mío)
Dado que 3.2 tiene numerosos avances en la administración de memoria con respecto a 2.6, esta no es una respuesta definitiva, pero es una pista realmente fuerte que seguiría primero. Reduzca la memoria utilizable del host a como máximo 16G utilizando el mem=
parámetro del kernel o extrayendo la mitad de los DIMM del servidor.
Por último,utilizar un kernel de 64 bits.
Amigo, es 2015.
Respuesta2
Unas pocas cosas ...
Mi regla general para el espacio de intercambio ha sido tener al menos el doble de RAM física. Esto permite que el demonio de página/intercambio tenga la capacidad de reorganizar la memoria de manera eficiente.
Server_B tiene 32 GB de RAM, así que intente configurarlo para 64 GB de intercambio. En mi opinión, los 2 GB de espacio de intercambio que tiene su servidor sonformademasiado bajo, especialmente para un servidor.
Si no tiene una partición adicional que pueda convertir en una partición de intercambio, puede probar esto creando un archivo y montándolo como una partición de intercambio [será lento]. Verhttps://www.maketecheasier.com/swap-partitions-on-linux/
Dado que server_B tiene mucho espacio en disco, --inplace no es necesario y puede no ser deseado, ya que puede ser lo que hace que rsync use 32 GB. --inplace solo es realmente útil si tiene poco espacio en el sistema de archivos [lo cual no es así] o si tiene algún requisito de rendimiento especial.
Supongo que rsync querrá usar 50 GB de RAM [el tamaño del archivo] con sus opciones actuales. Normalmente, rsync no necesita tanta memoria para hacer su trabajo, por lo que una o más de sus opciones pueden ser el problema. Rutinariamente transfiero archivos de 200 GB sin problemas.
Realice algunas pruebas sin opciones. Haga esto con archivos más pequeños, digamos de 10 GB; esto debería evitar el pánico del kernel, pero aún le permitirá monitorear el comportamiento que está causando el problema. Supervise el uso de memoria de rsync.
Gradualmente, vuelva a agregar opciones, una a la vez, para ver qué opción [o combinación de opciones] hace que rsync comience a consumir RAM (por ejemplo, mientras se realiza la transferencia, el uso de RAM de rsync crece proporcionalmente a la cantidad de datos de archivos transferidos, etc.).
Si realmente necesita las opciones que hacen que rsync conserve alguna imagen de archivo en la RAM, necesitará espacio de intercambio adicional y el tamaño máximo de su archivo se limitará en consecuencia.
Algunas cosas más [ACTUALIZADO]:
(1) El rastreo de la pila del kernel muestra que rsync tenía un error de página en un área mmap. Probablemente esté mapeando el archivo. mmap no ofrece garantía de que se vacíe en el discohastael archivo se cierra [a diferencia de la lectura/escritura], lo que va directamente al caché del bloque FS [donde se vaciará]
(2) La falla/pánico del kernel ocurre cuando el tamaño de la transferencia alcanza el tamaño de la RAM. Claramente, rsync está capturando tanta memoria que no es fscache a través de malloc o mmap. Una vez más, con las opciones que has especificado, rsync asignará 50 GB de memoria para transferir un archivo de 50 GB.
(3) Transfiera un archivo de 24 GB. Probablemente eso funcione. Luego, inicie el kernel con mem=16G y vuelva a realizar la prueba del archivo de 24 GB. Funcionará con 16 GB en lugar de 32 GB. Esto confirmará que rsync realmente necesita la memoria.
(4) Antes de decir que agregar swap es ridículo, intente agregar algo [mediante el método swap-to-file]. Esto es mucho más fácil de hacer y probar que todos los argumentos académicos sobre cómo no se requiere el intercambio. Incluso si no es la solución, es posible que aprenda algo de ello. Apuesto a que la prueba mem=16G tendrá éxito sin pánico ni bloqueo.
(5) Lo más probable es que rsyncesAl presionar swap, pero sucede demasiado rápido para verlo con top antes de que OOM entre en acción y elimine rsync. Para cuando rsync llega a 32 GB, otros procesos ya se han visto obligados a realizar un intercambio, especialmente si están inactivos. Quizás una combinación de "gratis" y "superior" le dé una mejor idea.
(6) Después de que se elimina rsync, se necesita tiempo para descargar mmap al FS. No es lo suficientemente rápido para OOM y comienza a matar otras cosas [algunas obviamente son de misión crítica]. Es decir, mmap rubor y OOM están compitiendo. O OOM tiene un error. De lo contrario, no habría ningún accidente.
(7) En mi experiencia, una vez que un sistema "llega al muro de la memoria", Linux tarda mucho en recuperarse por completo. Y, a veces, nunca se recupera correctamente y la única forma de solucionarlo es reiniciar. Por ejemplo, tengo 12 GB de RAM. Cuando ejecuto un trabajo que usa 40 GB de memoria [tengo 120 GB de intercambio para acomodar trabajos grandes] y luego lo finalizo, el sistema tarda unos 10 minutos en volver a su capacidad de respuesta normal [con la luz del disco encendida fija todo el tiempo] .
(8) Ejecute rsyncsinopciones. Esto funcionará. Obtenga un ejemplo básico para trabajar. Luego agregue nuevamente --inplace y vuelva a probar. Luego haz --append-verify en su lugar. Entonces, prueba ambos. Descubra qué opción hace que rsync haga el mmap enorme. Luego decide si puedes vivir sin él. Si --inplace es el culpable, es una obviedad, ya que tienes mucho espacio en disco. Si debe tener la opción, deberá obtener el espacio de intercambio para acomodar el malloc/mmap que hará rsync.
SEGUNDA ACTUALIZACIÓN:
Realice las pruebas mem= y archivos más pequeños de lo anterior.
Las preguntas centrales: ¿Por qué OOM elimina rsync? ¿Quién/Qué mastica la memoria?
Leí [pero olvidé] que el sistema era de 32 bits. Entonces, estoy de acuerdo, es posible que rsync no sea directamente responsable (a través de malloc/mmap; glibc implementa mallocs grandes a través de mmaps anónimos/privados), y la falla de la página mmap de rsync simplemente activa OOM por coincidencia. Luego, OOM calcula la memoria total consumida por rsync directa e indirectamente [caché FS, buffers de socket, etc.] y decide que es el candidato principal. Por lo tanto, puede resultar útil monitorear el uso total de la memoria. Sospecho que aumenta al mismo ritmo que la transferencia de archivos. Obviamente, no debería.
Algunas cosas se pueden monitorear en /proc o /proc/rsync_pid a través de un script perl o python en un bucle rápido [un script bash probablemente no será lo suficientemente rápido para el evento del fin del mundo] que puede monitorear todo lo siguiente varios cientos de veces/seg. Puedes ejecutar esto con una prioridad más alta que rsync para que se mantenga en la RAM y en ejecución para que puedas monitorear las cosas justo antes del bloqueo y, con suerte, durante OOM para que puedas ver por qué OOM se vuelve loco:
/proc/meminfo: para obtener información más detallada sobre el uso del intercambio en el "punto de impacto". En realidad, obtener el número final de cuánta RAM se está utilizando en total puede ser más útil. Si bien top proporciona esto, puede que no sea lo suficientemente rápido para mostrar el estado del universo justo antes del "big bang" (por ejemplo, los últimos 10 milisegundos).
Directorio /proc/rsync_pid/fd. Leer los enlaces simbólicos le permitirá identificar qué fd está abierto en el archivo de destino (por ejemplo, enlace de lectura de /proc/rsync_pid/fd/5 --> target_file). Probablemente esto solo deba hacerse una vez para obtener el número fd [debería permanecer fijo]
Conociendo el número fd, mire /proc/rsync_pid/fdinfo/fd. Es un archivo de texto que se parece a:
pos: <posición_archivo> banderas: bla_blah mnt_id: bla_bla
Monitorear el valor "pos" puede resultar útil, ya que la "posición del último archivo" puede resultar útil. Si realiza varias pruebas con diferentes tamaños y opciones mem=, ¿la posición del último archivo rastrea alguna de estas [y cómo]? El sospechoso habitual: posición del archivo == RAM disponible
Pero la forma más sencilla es comenzar con "rsync local_file server:remote_file" y verificar que funcione. Es posible que pueda obtener resultados similares [pero más rápidos] haciendo "ssh server rsync file_a file_b" [primero necesitaría crear un file_a de 50 GB]. Una forma sencilla de crear file_a es scp local_system:original_file server:file_a y esto podría ser interesante en sí mismo (por ejemplo, ¿funciona cuando rsync falla? Si scp funciona, pero rsync falla, esto apunta a rsync. Si scp falla, esto apunta a algo más como el controlador NIC). Hacer ssh rsync también elimina la NIC de la ecuación, lo que puede resultar útil. Si eso daña el sistema, entonces algo anda realmente mal. Si tiene éxito, [como mencioné] comience a agregar nuevamente las opciones una por una.
Odio insistir en el tema, pero agregar algo de intercambio a través de intercambio a archivo puede cambiar/retrasar el comportamiento del bloqueo y puede ser útil como herramienta de diagnóstico. Si agregar, digamos 16 GB, de intercambio retrasa el bloqueo [medido por el uso de la memoria o la posición del archivo de destino] de 32 GB a 46 GB, entonces eso dirá algo.
Puede que no sea ningún proceso en particular, sino un controlador del kernel erróneo que está consumiendo memoria. El vmalloc interno del kernel asigna cosas y se pueden intercambiar. IIRC, no está sujeto a la direccionabilidad en todas las circunstancias.
Claramente, el OOM se está confundiendo o entrando en pánico. Es decir, mata a rsync, pero no ve la memoria liberada de manera oportuna y busca otras víctimas. Algunos de ellos probablemente sean críticos para el funcionamiento del sistema.
Dejando a un lado malloc/mmap, esto podría deberse a que el caché FS no vaciado tarda mucho tiempo (por ejemplo, con 30 GB de datos no vaciados, suponiendo una velocidad de disco de 300 MB/seg, podría tardar 100 segundos en vaciarse). Incluso a ese ritmo, OOM puede estar demasiado impaciente. O bien, OOM al eliminar rsync no inicia el vaciado de FS lo suficientemente rápido [o no inicia nada]. O el vaciado de FS ocurre lo suficientemente rápido, pero tiene una liberación "lenta" de las páginas al grupo gratuito. Hay algunas opciones de /proc que puede configurar para controlar el comportamiento de la caché de FS [no recuerdo cuáles son].
Intente arrancar con mem=4G o algún otro número pequeño. Esto podría reducir el caché de FS y acortar su tiempo de vaciado para evitar que OOM busque otras cosas que eliminar (por ejemplo, el tiempo de vaciado se reduce de 100 segundos a < 1 segundo). También podría desenmascarar un error de OOM que no puede manejar RAM física > 4 GB en un sistema de 32 bits o algo así.
Además, un punto importante: ejecutar como no root. Nunca se espera que los usuarios root consuman recursos, por lo que se les dan límites más indulgentes (por ejemplo, 99% de la memoria frente al 95% para los usuarios que no son root). Esto puede explicar por qué OOM se encuentra en tal estado. Además, esto le da a OOM et. Alabama. más margen para hacer su trabajo de recuperar memoria.
Respuesta3
almeja? Parece que estás usando ClamAV y tienes habilitado el escaneo en acceso donde el motor antivirus intenta escanear los archivos abiertos en busca de virus.al cargar en la memoria, todo el contenido de cada archivo abierto por cualquier otro proceso.
Dependiendo de su postura de seguridad y la necesidad de esta transferencia, debe evaluar la posibilidad de desactivar el escaneo en acceso de ClamAV mientras realiza la transferencia.