단일 50GB 파일에서 Rsync 트리거 Linux OOM 킬러 0, btch:

server_A에 단일 50GB 파일이 있으며 server_B에 복사하고 있습니다. 난 달린다

server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file

Server_B에는 2GB 스왑이있는 32GB RAM이 있습니다. 대부분 유휴 상태이며 많은 여유 RAM이 있어야합니다. 디스크 공간이 충분합니다. 약 32GB에서 원격 측이 연결을 닫았 기 때문에 전송이 중단됩니다.

Server_B가 이제 네트워크를 끊었습니다. 데이터 센터에 재부팅을 요청합니다. 커널 로그가 다운되기 전에 커널 로그를 보면 스왑이 0 바이트이고 프로세스 목록에 메모리가 거의 사용되지 않는 것으로 나타났습니다 (rsync 프로세스는 600KB의 RAM을 사용하여 나열 됨). 그러나 oom_killer는 거칠고 로그의 마지막 것은 metalog의 커널 리더 프로세스를 죽이는 것입니다.

이것은 커널 3.2.59, 32 비트입니다 (아무 프로세스도 4GB 이상 매핑 할 수 없음).

마치 오래 실행되는 데몬보다 Linux가 캐싱에 더 많은 우선 순위를 부여한 것처럼 보입니다. 무엇을 제공합니까 ?? 다시 발생하는 것을 어떻게 막을 수 있습니까?

다음은 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

루트 사용자가 아닌 사용자로 rsync 명령을 반복 한 후 ‘맨 위’출력이 있습니다.

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

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


답변

oom-killer 출력을 읽고 거기서 배울 수있는 것을 보자.

OOM 킬러 로그를 분석 할 때 트리거 원인을 확인하는 것이 중요합니다. 로그의 첫 줄은 몇 가지 단서를 제공합니다.

[커널] [1772321.850644] clamd가 oom-killer를 호출했습니다. gfp_mask = 0x84d0, order = 0

order=0얼마나 많은 메모리가 요청되고 있는지 알려줍니다. 커널의 메모리 관리는 2의 거듭 제곱으로 만 페이지 번호를 관리 할 수 ​​있으므로 clamd는 2 0 페이지의 메모리 또는 4KB를 요청했습니다 .

GFP_MASK (사용 가능한 페이지 마스크 가져 오기)의 가장 낮은 두 비트 는 할당 자에게 메모리를 가져올 영역을 알려주는 소위 영역 마스크를 구성합니다 .

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

메모리 영역 은 호환성 이유로 주로 만들어진 개념입니다. 단순화 된보기에는 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

귀하의 경우 zonemask는 0입니다. 이는 clamd가에서 메모리를 요청 함을 의미 ZONE_NORMAL합니다.

다른 깃발들은

/*
 * 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 */

에 따라 리눅스 MM 문서 , 그래서 당신의 requst가에 대한 플래그를 가지고 GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOGFP_WAIT따라서 특히 까다 롭고없는 것.

무슨 일이야 ZONE_NORMAL? 일부 일반 통계는 OOM 출력에서 ​​추가로 찾을 수 있습니다.

[커널] [1772321.850770] 일반 무료 : 8056kB 최소 : 8048kB 낮음 : 10060kB 높음 : 12072kB active_anon : 0kB 비활성 _anon : 0kB active_file : 248kB 비활성 _ ​​파일 : 388kB 분리 할 수 ​​없음 : 0kB 격리 됨 ​​(anon) : 0kB 격리 됨 ​​(파일) : 0kB 절연 :

여기에서 눈에 띄는 점 free은 8K min이하 low입니다. 이것은 호스트의 메모리 관리자가 다소 어려움을 겪고 있으며 kswapd는 아래 그래프 의 노란색 단계와 같이 이미 페이지를 스왑 아웃해야 함을 의미합니다 .

영역의 메모리 조각화에 대한 자세한 내용은 다음과 같습니다.

[커널] [1772321.850795] 일반 : 830 * 4kB 80 * 8kB 0 * 16kB 0 * 32kB 0 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 1 * 4096kB = 8056kB

기본적으로 4MB의 단일 연속 페이지가 있고 나머지는 주로 4KB 페이지로 크게 나뉘어 있음을 나타냅니다.

다시 요약하자 :

  • 당신의 (a 유저 랜드 프로세스가 clamd메모리를 받고) ZONE_NORMAL보통에서 수행 할 것이다 권한이없는 메모리 할당 반면,ZONE_HIMEM
  • 이 단계에서 메모리 관리자는 요청 된 4K 페이지를 제공 할 수 있었지만 ZONE_NORMAL
  • 로 시스템 kswapd의 규칙은 해야 사전에 어떤 페이징 활동을 봐 왔지만, 아무것도, 심지어 메모리의 압력, 스왑되지되는 ZONE_NORMAL명백한 이유없이,
  • 위의 어느 것도 왜 oom-killer호출되었는지에 대한 확실한 이유는 없습니다.

이 모든 것은 다소 이상해 보이지만 최소한 John O’Gorman의 “Linux Virtual Memory Manager 이해”서적의 2.5 절에 설명 된 내용과 관련이 있습니다 .

커널이 사용할 수있는 주소 공간 (ZONE_NORMAL)의 크기가 제한되어 있기 때문에 커널은 높은 메모리 개념을 지원합니다. […] 1GiB와 4GiB 범위의 메모리에 액세스하기 위해 커널은 kmap ()을 사용하여 페이지를 고용량 메모리에서 ZONE_NORMAL로 임시 매핑합니다. […]

즉, 1GiB의 메모리를 설명하려면 약 11MiB의 커널 메모리가 필요합니다. 따라서 16GiB에서는 176MiB의 메모리가 사용되므로 ZONE_NORMAL에 상당한 압력이 가해집니다. ZONE_NORMAL을 사용하는 다른 구조를 고려할 때까지 이것은 나쁘게 들리지 않습니다. PTE (Page Table Entry)와 같은 매우 작은 구조라도 최악의 경우 약 16MiB가 필요합니다. 이로 인해 16GiB는 x86에서 사용 가능한 실제 메모리 Linux의 실제 제한에 대해 설명합니다 .

(강조는 내 것입니다)

3.2는 2.6보다 메모리 관리에서 많은 발전을 이루었으므로 이것은 확실한 대답이 아니라 내가 먼저 추구 할 강력한 힌트입니다. mem=커널 매개 변수를 사용하거나 서버에서 DIMM의 절반을 리핑 하여 호스트의 사용 가능한 메모리를 최대 16G로 줄이십시오 .

궁극적 으로 64 비트 커널을 사용하십시오 .

야, 2015 년이야.


답변

몇 가지 …

스왑 공간에 대한 나의 경험의 규칙은 물리적 램의 최소 2 배가되어야한다는 것입니다. 이를 통해 페이지 / 스왑 데몬이 메모리를 효율적으로 재구성 할 수 있습니다.

Server_B에는 32GB의 램이 있으므로 64GB의 스왑에 맞게 구성하십시오. IMO, 서버가이 스왑 공간의 2GB의 인 방법 , 특히 서버, 너무 낮은.

스왑 파티션으로 만들 수있는 추가 파티션이없는 경우 파일을 생성하고 스왑 파티션으로 마운트하여 테스트 할 수 있습니다 [느려질 것]. https://www.maketecheasier.com/swap-partitions-on-linux/를 참조 하십시오

server_B는 충분한 디스크 공간을 가지고 있기 때문에 –inplace가 필요하지 않으며 rsync가 32GB를 사용하는 원인 일 수 있으므로 바람직하지 않을 수 있습니다. –inplace는 파일 시스템 공간이 부족하거나 특별한 성능 요구 사항이있는 경우에만 유용합니다.

내 생각에 rsync는 현재 옵션과 함께 50GB의 램 [파일 크기]을 사용하려고합니다. 일반적으로 rsync는 작업을 수행하기 위해 많은 메모리가 필요하지 않으므로 하나 이상의 옵션이 문제 일 수 있습니다. 문제없이 200GB 파일을 정기적으로 전송합니다.

옵션을 사용하지 않고 테스트를 수행하십시오. 10GB와 같은 작은 파일을 사용하면 커널 패닉을 방지 할 수 있지만 여전히 문제를 일으키는 동작을 모니터링 할 수 있습니다. rsync의 메모리 사용량을 모니터하십시오.

점차적으로 옵션을 한 번에 하나씩 다시 추가하여 어떤 옵션 [또는 옵션 조합]이 rsync가 RAM에서 피그 아웃을 시작하게하는지 확인합니다 (예 : 전송이 진행되는 동안 rsync의 램 사용량은 전송 된 파일 데이터의 양에 비례하여 증가합니다, 기타.).

rsync가 일부 in-ram 파일 이미지를 유지하도록하는 옵션이 정말로 필요한 경우 추가 스왑 공간이 필요하며 최대 파일 크기가 그에 따라 제한됩니다.

몇 가지 더 [업데이트] :

(1) 커널 스택 추적은 rsync가 mmap 영역에서 페이지 오류를 일으켰 음을 보여줍니다. 아마도 파일을 지우고있을 것입니다. mmap은 [읽기 / 쓰기와 달리] 파일이 닫힐 때까지 디스크로 플러시 될 것이라는 보장을하지 않습니다. [읽기 / 쓰기와 달리] FS 블록 캐시로 바로갑니다 [플러시 될 위치]

(2) 전송 크기가 RAM 크기에 도달하면 커널 충돌 / 패닉이 발생합니다. 분명히 rsync는 malloc 또는 mmap을 통해 많은 비 fscache 메모리를 가져옵니다. 다시 한 번 지정한 옵션으로 rsync는 50GB의 메모리를 할당하여 50GB 파일을 전송합니다.

(3) 24GB 파일을 전송하십시오. 아마도 효과가있을 것입니다. 그런 다음 mem = 16G로 커널을 부팅하고 24GB 파일 테스트를 다시 수행하십시오. 32GB가 아닌 16GB로 나옵니다. 이것은 rsync에 실제로 메모리가 필요하다는 것을 확인합니다.

(4) 스왑 추가가 터무니 없다고 말하기 전에 [스왑-파일 방법을 통해] 일부를 추가해보십시오. 스왑이 필요하지 않은 방법에 대한 모든 학문적 주장보다 훨씬 쉽게 수행하고 테스트 할 수 있습니다. 해결책이 아니더라도 무언가를 배울 수 있습니다. mem = 16G 테스트가 패닉 / 크래쉬없이 성공할 것이라고 확신합니다.

(5) rsync 스왑을 칠 가능성이 있지만 OOM이 시작되고 rsync를 종료하기 전에 top으로 볼 수 없습니다. rsync가 32GB가 될 때까지, 특히 유휴 상태 인 경우 다른 프로세스가 이미 스왑되도록 강제되었습니다. 아마도 “무료”와 “위”의 조합은 더 나은 사진을 제공 할 것입니다.

(6) rsync가 종료 된 후 mmap를 FS로 플러시하는 데 시간이 걸립니다. OOM만큼 빠르지 않으며 다른 것들을 죽이기 시작합니다 [일부는 미션 크리티컬입니다]. 즉, mmap flush와 OOM이 레이싱 중입니다. 또는 OOM에 버그가 있습니다. 그렇지 않으면 충돌이 발생하지 않습니다.

(7) 내 경험에 따르면, 일단 시스템이 “메모리 벽에 부딪 치면”Linux를 완전히 복구하는 데 시간이 오래 걸립니다. 그리고 때로는 실제로 제대로 복구되지 않으며 그것을 지우는 유일한 방법은 재부팅입니다. 예를 들어 12GB의 RAM이 있습니다. 40GB의 메모리를 사용하는 작업 (대규모 작업을 수용하기 위해 120GB의 스왑이 있음)을 실행 한 다음 종료하면 시스템이 정상적인 응답 상태로 돌아 오는 데 약 10 분이 소요됩니다 (디스크 표시등은 계속 켜져 있음). .

(8) 옵션 없이 rsync 실행하십시오 . 작동합니다. 작업 할 기본 예를 가져옵니다. 그런 다음 다시 추가하고 다시 테스트하십시오. 그런 다음 –append-verify를 대신 수행하십시오. 그런 다음 두 가지를 모두 시도하십시오. 거대한 mmap을 수행하는 rsync 옵션을 찾으십시오. 그런 다음없이 살 수 있는지 결정하십시오. –inplace가 범인이라면 디스크 공간이 충분하기 때문에 당연한 일입니다. 옵션이 필요한 경우 rsync가 수행 할 malloc / mmap을 수용 할 수있는 스왑 공간을 확보해야합니다.

두 번째 업데이트 :

위의 mem = 및 더 작은 파일 테스트를 수행하십시오.

중심 질문 : 왜 rsync가 OOM에 의해 살해됩니까? 씹는 기억은 누구입니까?

나는 시스템이 32 비트라는 것에 대해 읽었지만 잊었다. 따라서 rsync가 직접 책임을지지 않을 수도 있습니다 (malloc / mmap을 통해 -glibc는 익명 / 개인 mmap을 통해 큰 malloc을 구현합니다). rsync의 mmap 페이지 오류는 우연의 일치로 OOM을 트리거합니다. 그런 다음 OOM은 rsync가 직접 및 간접적으로 소비하는 총 메모리 (FS 캐시, 소켓 버퍼 등)를 계산하여 주요 후보로 결정합니다. 따라서 총 메모리 사용량을 모니터링하는 것이 도움이 될 수 있습니다. 파일 전송과 같은 속도로 충돌하는 것 같습니다. 분명히해서는 안됩니다.

빠른 루프에서 perl 또는 python 스크립트를 통해 / proc 또는 / proc / rsync_pid에서 모니터링 할 수있는 것 [bash 스크립트는 아마도 세계 종말 이벤트에 대해 충분히 빠르지 않을 것입니다.] 다음 몇 백 번 / 초. rsync보다 높은 우선 순위로 이것을 실행할 수 있으므로 RAM과 자체 실행 상태로 유지되므로 충돌 직전과 OOM 중에 희망 사항을 모니터링하여 OOM이 미친 이유를 알 수 있습니다.

/ proc / meminfo- “영향 지점”에서 스왑 사용에 대해보다 세밀한 정보를 얻습니다. 실제로, 얼마나 많은 RAM이 사용되는지에 대한 최종 수를 얻는 것이 더 유용 할 수 있습니다. top이이를 제공하지만 “빅뱅”직전의 우주 상태를 표시하기에는 충분히 빠르지 않을 수 있습니다 (예 : 마지막 10 밀리 초)

/ proc / rsync_pid / fd 디렉토리 심볼릭 링크를 읽으면 대상 파일에서 열린 fd를 식별 할 수 있습니다 (예 : / proc / rsync_pid / fd / 5-> target_file의 읽기 링크). 이것은 아마도 fd 번호를 얻기 위해 한 번만 수행하면된다 [고정되어야한다]

fd 번호를 알고 있으면 / proc / rsync_pid / fdinfo / fd를보십시오. 다음과 같은 텍스트 파일입니다.

위치 : <file_position>
플래그 : blah_blah
mnt_id : blah_blah

“마지막 파일 위치”가 유용 할 수 있으므로 “pos”값을 모니터링하면 도움이 될 수 있습니다. 다양한 크기와 mem = 옵션을 사용하여 여러 테스트를 수행하는 경우 마지막 파일 위치가 이러한 방법을 추적합니까? 일반적인 용의자 : 파일 위치 == 사용 가능한 RAM

그러나 가장 간단한 방법은 “rsync local_file server : remote_file”로 시작하여 작동하는지 확인하는 것입니다. “ssh server rsync file_a file_b”[먼저 50GB file_a를 만들어야합니다]를 수행하여 유사한 [그러나 더 빠른] 결과를 얻을 수 있습니다. file_a를 작성하는 간단한 방법은 scp local_system : original_file server : file_a이며 이는 그 자체로 흥미로울 수 있습니다 (예 : rsync가 충돌 할 때 작동합니까? scp가 작동하지만 rsync가 실패하면 rsync를 가리킴) scp가 실패하면이 점 NIC 드라이버와 같은 다른 것으로). ssh rsync를 수행하면 NIC가 방정식에서 빠져 나와 도움이 될 수 있습니다. 그것이 시스템을 호스로 만들면 실제로 잘못된 것입니다. 성공하면 [앞서 언급했듯이] 옵션을 하나씩 다시 추가하기 시작합니다.

요점을 다루는 것이 싫지만 파일 간 스왑을 통해 스왑을 추가하면 충돌 동작이 변경 / 지연 될 수 있으며 진단 도구로 유용 할 수 있습니다. 16GB와 같은 스왑을 추가하면 [메모리 사용량 또는 대상 파일 위치로 측정 된] 충돌이 32GB에서 46GB로 지연되면 무언가를 말합니다.

특정 프로세스는 아니지만 메모리를 씹는 잘못된 커널 드라이버 일 수 있습니다. 커널의 내부 vmalloc은 물건을 할당하고 교환 할 수 있습니다. IIRC, 모든 상황에서 접근성에 구속되지는 않습니다.

분명히 OOM은 혼란스럽고 당황하고 있습니다. 즉, 그것은 rsync를 죽이지 만 메모리가 적시에 해제 된 것을 보지 않고 다른 희생자를 찾습니다. 그들 중 일부는 아마도 시스템 작동에 중요합니다.

malloc / mmap을 제외하면 시간이 오래 걸리는 플러시되지 않은 FS 캐시로 인해 발생할 수 있습니다 (예 : 디스크 속도가 300MB / 초라고 가정하면 플러시하는 데 100 초가 걸릴 수 있음). 그 속도에서도 OOM이 너무 조급할 수 있습니다. 또는 OOM killing rsync가 FS 플러시를 충분히 빨리 시작하지 않습니다. 또는 FS 플러시가 충분히 빠르지 만 사용 가능한 풀로 페이지의 “게으른”릴리스가 있습니다. FS 캐시 동작을 제어하기 위해 설정할 수있는 / proc 옵션이 있습니다 [그들이 무엇인지 기억할 수 없습니다].

mem = 4G 또는 다른 작은 숫자로 부팅 해보십시오. 이로 인해 FS 캐시가 줄어들고 플러시 시간이 단축되어 OOM이 죽일 다른 항목을 찾지 않도록 할 수 있습니다 (예 : 플러시 시간이 100 초에서 <1 초로 감소). 또한 32 비트 시스템 등에서 4GB를 초과하는 물리적 램을 처리 할 수없는 OOM 버그를 마스크 해제 할 수 있습니다.

또한 중요한 점은 루트가 아닌 것으로 실행하십시오. 루트 사용자는 리소스를 씹을 것으로 예상되지 않으므로 더 많은 허용 한계가 있습니다 (예 : 메모리의 99 % 대 루트가 아닌 사용자의 경우 95 %). 이것은 OOM이 왜 그런 상태인지 설명 할 수 있습니다. 또한, 이것은 OOM et. 알. 기억을 되 찾는 일을 할 더 많은 헤드 룸.


답변

조개? ClamAV를 사용하는 것처럼 들리고 안티 바이러스 엔진이 열려있는 파일에서 바이러스가 있는지 검사 하여 다른 프로세스에서 연 모든 파일의 전체 내용을 메모리에로드하여 온 액세스 검색을 사용하는 것처럼 보입니다 .

보안 상태와이 전송의 필요성에 따라 전송을 수행하는 동안 ClamAV 온 액세스 검색 사용 안함을 평가해야합니다.