
Tenho um único arquivo de 50 GB no server_A e estou copiando-o para o server_B. eu corro
server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file
Server_B possui 32 GB de RAM com 2 GB de swap. Está quase ocioso e deveria ter muita RAM livre. Tem bastante espaço em disco. Em cerca de 32 GB, a transferência é interrompida porque o lado remoto fechou a conexão.
Server_B agora saiu da rede. Pedimos ao data center para reiniciá-lo. Quando olho para o log do kernel antes de ele travar, vejo que ele estava usando 0 bytes de swap e a lista de processos estava usando muito pouca memória (o processo rsync foi listado como usando 600 KB de RAM), mas o oom_killer foi enlouquecendo, e a última coisa no log é onde ele mata o processo de leitura do kernel do metalog.
Este é o kernel 3.2.59, de 32 bits (portanto, nenhum processo pode mapear mais de 4 GB).
É quase como se o Linux desse mais prioridade ao cache do que aos daemons de longa duração. O que da?? E como posso impedir que isso aconteça novamente?
Aqui está a saída do 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
Aqui está a saída 'top' após repetir meu comando rsync como um usuário não 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
Aqui estão os parâmetros 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
Responder1
Então, vamos ler o resultado do oom-killer e ver o que pode ser aprendido com ele.
Ao analisar os logs do Killer OOM, é importante observar o que o desencadeou. A primeira linha do seu log nos dá algumas pistas:
[kernel] [1772321.850644] clamd invocou oom-killer:gfp_mask=0x84d0, pedido=0
order=0
está nos dizendo quanta memória está sendo solicitada. O gerenciamento de memória do kernel só é capaz de gerenciar números de páginas em potências de 2, então clamd solicitou 2 0 páginas de memória ou 4 KB.
Os dois bits mais baixos do GFP_MASK (obter máscara de página gratuita) constituem o chamadomáscara de zona informando ao alocador de qual zona obter a memória:
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 memóriaé um conceito criado principalmente por razões de compatibilidade. Numa visão simplificada, existem três zonas para um 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
No seu caso, zonemask é 0, o que significa que clamd está solicitando memória de ZONE_NORMAL
.
As demais bandeiras estão resolvendo
/*
* 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 acordo comDocumentação Linux MM, portanto , sua solicitação tem os sinalizadores para GFP_ZERO
, GFP_REPEAT
, e , portanto, não sendo particularmente exigente.GFP_FS
GFP_IO
GFP_WAIT
Então, o que há ZONE_NORMAL
? Algumas estatísticas genéricas podem ser encontradas mais adiante na saída do OOM:
[núcleo] [1772321.850770] Normallivre: 8.056 kB mínimo: 8.048 kB baixo: 10.060 kBalto: 12072kB ativo_anon:0kB inativo_anon:0kB arquivo_ativo:248kB arquivo_inativo:388kB inevitável:0kB isolado(anon) :0kB isolado(arquivo):0kB presente:890008kB
Notável aqui é quefree
está a apenas 8K demin
e bem abaixolow
. Isso significa que o gerenciador de memória do seu host está em apuros e o kswapd já deve estar trocando as páginas como está noamarelofase do gráfico abaixo:
Mais algumas informações sobre a fragmentação de memória da zona são fornecidas aqui:
[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
basicamente afirmando que você tem uma única página contígua de 4 MB com o restante fortemente fragmentado em páginas principalmente de 4 KB.
Então vamos recapitular:
- você tem um processo de usuário (
clamd
) obtendo memória,ZONE_NORMAL
enquanto a alocação de memória sem privilégios normalmente seria realizada a partir deZONE_HIMEM
- o gerenciador de memória neste estágio deveria ter sido capaz de atender a página 4K solicitada, embora você pareça ter uma pressão de memória significativa em
ZONE_NORMAL
- o sistema, pelas
kswapd
regras de,devevi alguma atividade de paginação anteriormente, mas nada está sendo trocado, mesmo sob pressão de memóriaZONE_NORMAL
, sem causa aparente - Nenhuma das opções acima fornece uma razão definitiva para o porquê de
oom-killer
ter sido invocado
Tudo isso parece bastante estranho, mas pelo menos deve estar relacionado com o que é descrito noseção 2.5 do excelente livro "Understanding the Linux Virtual Memory Manager" de John O'Gorman:
Como o espaço de endereços utilizável pelo kernel (ZONE_NORMAL) é limitado em tamanho, o kernel tem suporte para o conceito de Alta Memória. [...] Para acessar a memória entre o intervalo de 1GiB e 4GiB, o kernel mapeia temporariamente páginas de alta memória para ZONE_NORMAL com kmap(). [...]
Isso significa que para descrever 1GiB de memória, são necessários aproximadamente 11MiB de memória do kernel. Assim, com 16GiB, são consumidos 176MiB de memória, colocando uma pressão significativa em ZONE_NORMAL. Isso não parece tão ruim até que outras estruturas que usam ZONE_NORMAL sejam levadas em consideração. Mesmo estruturas muito pequenas, como entradas de tabela de páginas (PTEs), requerem cerca de 16 MiB no pior caso.Isso torna 16GiB o limite prático para memória física disponível no Linux em um x86.
(o destaque é meu)
Como o 3.2 tem vários avanços no gerenciamento de memória em relação ao 2.6, esta não é uma resposta definitiva, mas uma dica realmente forte que eu seguiria primeiro. Reduza a memória utilizável do host para no máximo 16G usando o mem=
parâmetro do kernel ou extraindo metade dos DIMMs do servidor.
Em última análise,use um kernel de 64 bits.
Cara, estamos em 2015.
Responder2
Algumas coisas ...
Minha regra geral para espaço de troca é ter pelo menos 2x a quantidade de memória RAM física. Isso permite que o daemon de página/swap reorganize a memória com eficiência.
Server_B tem 32 GB de RAM, então tente configurá-lo para 64 GB de swap. IMO, os 2 GB de espaço de troca que seu servidor possui sãocaminhomuito baixo, especialmente para um servidor.
Se você não tiver uma partição extra que possa transformar em uma partição swap, você pode testar isso criando um arquivo e montando-o como uma partição swap [será lento]. Verhttps://www.maketecheasier.com/swap-partitions-on-linux/
Como server_B tem bastante espaço em disco, --inplace não é necessário e pode ser indesejado, pois pode ser o que está fazendo com que o rsync use 32 GB. --inplace só é realmente útil se você tiver pouco espaço no sistema de arquivos [o que não tem] ou tiver algum requisito especial de desempenho.
Meu palpite é que o rsync desejará usar 50 GB de RAM [o tamanho do arquivo] com suas opções atuais. Normalmente, o rsync não precisa de tanta memória para fazer seu trabalho, então uma ou mais de suas opções podem ser o problema. Eu rotineiramente transfiro arquivos de 200 GB sem problemas.
Faça alguns testes sem opções. Faça isso com arquivos menores, digamos 10 GB - isso deve evitar o kernel panic, mas ainda permitirá monitorar o comportamento que está causando o problema. Monitore o uso de memória do rsync.
Gradualmente, adicione novamente opções, uma de cada vez, para ver qual opção [ou combinação de opções] faz com que o rsync comece a consumir RAM (por exemplo, enquanto a transferência está acontecendo, o uso de memória RAM do rsync aumenta proporcionalmente à quantidade de dados de arquivo transferidos, etc.).
Se você realmente precisa das opções que fazem com que o rsync mantenha alguma imagem de arquivo na memória RAM, você precisará de espaço de troca extra e o tamanho máximo do arquivo será limitado de acordo.
Mais algumas coisas [ATUALIZADO]:
(1) O rastreamento da pilha do kernel mostra que o rsync estava com falha de página em uma área mmap. Provavelmente está mapeando o arquivo. mmap não oferece garantia de que será liberado para o discoatéo arquivo é fechado [ao contrário de leitura/gravação], que vai para o cache do bloco FS imediatamente [onde será liberado]
(2) A falha/pânico do kernel ocorre quando o tamanho da transferência atinge o tamanho da RAM. Claramente, o rsync está capturando muita memória não-fscache via malloc ou mmap. Mais uma vez, com as opções especificadas, o rsync alocará 50 GB de memória para transferir um arquivo de 50 GB.
(3) Transfira um arquivo de 24 GB. Isso provavelmente funcionará. Em seguida, inicialize o kernel com mem=16G e faça o teste do arquivo de 24GB novamente. Ele explodirá em 16 GB em vez de 32 GB. Isso confirmará que o rsync realmente precisa de memória.
(4) Antes de dizer que adicionar swap é ridículo, tente adicionar alguns [através do método swap-to-file]. Isso é muito mais fácil de fazer e testar do que todos os argumentos acadêmicos sobre como a troca não é necessária. Mesmo que não seja a solução, você pode aprender algo com isso. Aposto que o teste mem=16G será bem-sucedido sem pânico/travamento.
(5) Provavelmente, rsyncébater em swap, mas acontece muito rápido para ver com top antes que o OOM entre em ação e mate o rsync. Quando o rsync chega a 32 GB, outros processos já foram forçados a trocar, principalmente se estiverem ociosos. Talvez uma combinação de "grátis" e "top" lhe dê uma imagem melhor.
(6) Depois que o rsync é eliminado, leva algum tempo para liberar o mmap para o FS. Não é rápido o suficiente para OOM e começa a matar outras coisas [algumas são obviamente de missão crítica]. Ou seja, o mmap flush e o OOM estão correndo. Ou o OOM tem um bug. Caso contrário, não haveria acidente.
(7) Na minha experiência, quando um sistema “atinge a parede da memória”, o Linux leva muito tempo para se recuperar totalmente. E, às vezes, ele nunca se recupera adequadamente e a única maneira de limpá-lo é reinicializando. Por exemplo, tenho 12 GB de RAM. Quando executo um trabalho que usa 40 GB de memória [tenho 120 GB de swap para acomodar trabalhos grandes] e depois o encerro, leva cerca de 10 minutos para o sistema retornar à capacidade de resposta normal [com a luz do disco acesa o tempo todo] .
(8) Execute o rsyncsemopções. Isso funcionará. Obtenha um exemplo básico para trabalhar. Em seguida, adicione novamente --inplace e teste novamente. Então faça --append-verify. Então, experimente os dois. Descubra qual opção faz com que o rsync faça o enorme mmap. Então decida se você pode viver sem ele. Se --inplace for o culpado, isso é óbvio, já que você tem bastante espaço em disco. Se você precisar dessa opção, precisará obter o espaço de troca para acomodar o malloc/mmap que o rsync fará.
SEGUNDA ATUALIZAÇÃO:
Por favor, faça os testes mem= e arquivos menores acima.
As questões centrais: Por que o rsync é eliminado pelo OOM? Quem/o que está mastigando memória?
Eu li [mas esqueci] que o sistema era de 32 bits. Portanto, eu concordo, o rsync pode não ser diretamente responsável (via malloc/mmap - glibc implementa grandes mallocs por meio de mmaps anônimos/privados), e a falha da página mmap do rsync apenas aciona o OOM por coincidência. Em seguida, o OOM calcula a memória total consumida pelo rsync direta e indiretamente [cache FS, buffers de soquete, etc.] e decide que é o principal candidato. Portanto, monitorar o uso total da memória pode ser útil. Eu suspeito que isso aumenta na mesma proporção que a transferência de arquivos. Obviamente, não deveria.
Algumas coisas que você pode monitorar em /proc ou /proc/rsync_pid por meio de um script perl ou python em um loop rápido [um script bash provavelmente não será rápido o suficiente para o evento de fim do mundo] que pode monitorar todos as seguintes centenas de vezes/seg. Você pode executar isso com uma prioridade mais alta do que o rsync, para que ele se mantenha na RAM e em execução, para que você possa monitorar as coisas antes da falha e, esperançosamente, durante o OOM, para que você possa ver por que o OOM enlouquece:
/proc/meminfo - para obter mais detalhes sobre o uso de swap no "ponto de impacto". Na verdade, obter o número final de quanta RAM está sendo usada no total pode ser mais útil. Embora top forneça isso, pode não ser rápido o suficiente para mostrar o estado do universo imediatamente antes do "big bang" (por exemplo, os últimos 10 milissegundos).
Diretório /proc/rsync_pid/fd. A leitura dos links simbólicos permitirá identificar qual fd está aberto no arquivo de destino (por exemplo, readlink de /proc/rsync_pid/fd/5 --> target_file). Provavelmente isso só precisa ser feito uma vez para obter o número fd [deve permanecer fixo]
Sabendo o número do fd, consulte /proc/rsync_pid/fdinfo/fd. É um arquivo de texto parecido com:
posição: <posição_do_arquivo> bandeiras: blá_blá mnt_id: blá_blá
Monitorar o valor "pos" pode ser útil, pois a "posição do último arquivo" pode ser útil. Se você fizer vários testes com tamanhos e opções mem= variados, a última posição do arquivo rastreia algum deles [e como]? O suspeito de sempre: posição do arquivo == RAM disponível
Porém, a maneira mais simples é começar com "rsync local_file server:remote_file" e verificar se funciona. Você pode obter resultados semelhantes [mas mais rápidos] executando "ssh server rsync file_a file_b" [você precisaria criar um file_a de 50 GB primeiro]. Uma maneira simples de criar file_a é scp local_system:original_file server:file_a e isso pode ser interessante por si só (por exemplo, isso funciona quando o rsync falha? Se o scp funcionar, mas o rsync falhar, isso aponta para o rsync. Se o scp falhar, isso aponta para algo como o driver da NIC). Fazer o ssh rsync também tira a NIC da equação, o que pode ser útil. Se isso mangueira o sistema, então algo está realmente errado. Se tiver sucesso, [como mencionei] comece a adicionar novamente as opções uma por uma.
Detesto insistir nesse ponto, mas adicionar alguma troca por meio de troca para arquivo pode alterar/atrasar o comportamento da falha e pode ser útil como ferramenta de diagnóstico. Se adicionar, digamos, 16 GB, de swap atrasar a falha [conforme medido pelo uso de memória ou posição do arquivo de destino] de 32 GB para 46 GB, então isso dirá alguma coisa.
Pode não ser um processo específico, mas um driver de kernel incorreto que está consumindo memória. O vmalloc interno do kernel aloca coisas e pode ser trocado. IIRC, não está vinculado à endereçamento em todas as circunstâncias.
Claramente, o OOM está ficando confuso/em pânico. Ou seja, ele mata o rsync, mas não vê a memória liberada em tempo hábil e sai em busca de outras vítimas. Alguns deles são provavelmente críticos para a operação do sistema.
Deixando de lado o malloc/mmap, isso pode ser causado por um cache FS não liberado que leva muito tempo (por exemplo, com 30 GB de dados não liberados, assumindo uma taxa de disco de 300 MB/s, pode levar 100 segundos para liberá-lo). Mesmo nesse ritmo, o OOM pode ser muito impaciente. Ou o OOM matando o rsync não inicia a liberação do FS rápido o suficiente [ou de todo]. Ou a liberação do FS acontece rápido o suficiente, mas tem uma liberação "preguiçosa" das páginas de volta ao pool livre. Existem algumas opções /proc que você pode definir para controlar o comportamento do cache FS [não me lembro quais são].
Tente inicializar com mem=4G ou algum outro número pequeno. Isso pode reduzir o cache do FS e o tempo de liberação para evitar que o OOM procure outras coisas para eliminar (por exemplo, o tempo de liberação é reduzido de 100 segundos para <1 segundo). Também pode desmascarar um bug OOM que não consegue lidar com memória RAM física> 4 GB em um sistema de 32 bits ou algo assim.
Além disso, um ponto importante: execute como não-root. Nunca se espera que os usuários root mastiguem recursos, portanto, eles recebem limites mais tolerantes (por exemplo, 99% de memória versus 95% para usuários não root). Isso pode explicar por que o OOM está nesse estado. Além disso, isso dá OOM et. al. mais espaço para fazer seu trabalho de recuperar a memória.
Responder3
clamo? Parece que você está usando o ClamAV e tem a verificação ao acessar ativada, onde o mecanismo antivírus tenta verificar se há vírus em arquivos abertos,carregando na memória, todo o conteúdo de cada arquivo aberto por qualquer outro processo.
Dependendo da sua postura de segurança e da necessidade dessa transferência, você deve avaliar a desativação da verificação ao acessar o ClamAV enquanto realiza a transferência.