Назад | Перейти на главную страницу

Rsync запустил убийцу OOM Linux для одного файла размером 50 ГБ

У меня есть один файл размером 50 ГБ на server_A, и я копирую его на server_B. я бегу

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

Server_B имеет 32 ГБ ОЗУ с 2 ГБ подкачки. Он в основном простаивает и должен иметь много свободной оперативной памяти. На нем много места на диске. При размере примерно 32 ГБ передача прерывается, поскольку удаленная сторона закрыла соединение.

Server_B отключен от сети. Просим дата-центр его перезагрузить. Когда я смотрю на журнал ядра до его сбоя, я вижу, что он использовал 0 байтов подкачки, а список процессов использовал очень мало памяти (процесс rsync был указан как использующий 600 КБ ОЗУ), но oom_killer был сходит с ума, и последнее, что в журнале - это то, где он убивает процесс чтения ядра metalog.

Это 32-разрядное ядро ​​3.2.59 (так что ни один процесс не может отображать более 4 ГБ).

Это почти как если бы 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 от имени пользователя без полномочий 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

Вот параметры 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, порядок = 0

order=0 сообщает нам, сколько памяти запрошено. Управление памятью ядра может управлять номерами страниц только в степени 2, поэтому clamd запросил 20 страниц памяти или 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

В вашем случае маска зоны равна 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 */

согласно Документация Linux MM, поэтому в вашем запросе есть флаги для GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IO и GFP_WAIT, поэтому не особо разборчивый.

Так что с ZONE_NORMAL? Некоторую общую статистику можно найти в выходных данных OOM:

[ядро] [1772321.850770] Нормальное бесплатно: 8056 КБ мин: 8048 КБ низкое: 10060 КБ высокий: 12072 КБ active_anon: 0 КБ неактивный_анон: 0 КБ active_file: 248 КБ неактивный_файл: 388 КБ непредсказуемо: 0 КБ изолированно (анон): 0 КБ изолированно (файл): 0 КБ присутствует: 890008 КБ

Примечательно здесь то, что free всего 8K от min и путь под low. Это означает, что диспетчер памяти вашего хоста находится в некотором затруднительном положении, и kswapd должен уже выгружать страницы, как и в желтый фаза графика ниже:

Дополнительная информация о фрагментации памяти в зоне приведена здесь:

[ядро] [1772321.850795] Нормальный: 830 * 4 КБ 80 * 8 КБ 0 * 16 КБ 0 * 32 КБ 0 * 64 КБ 0 * 128 КБ 0 * 256 КБ 0 * 512 КБ 0 * 1024 КБ 0 * 2048 КБ 1 * 4096 КБ = 8056 КБ

в основном утверждается, что у вас есть одна непрерывная страница размером 4 МБ, а остальная часть сильно фрагментирована в основном на страницы размером 4 КБ.

Итак, давайте резюмируем:

  • у вас есть пользовательский процесс (clamd) получение памяти от ZONE_NORMAL тогда как выделение непривилегированной памяти обычно выполняется из ZONE_HIMEM
  • на этом этапе диспетчер памяти должен иметь возможность обслуживать запрошенную страницу 4K, хотя у вас, похоже, есть значительная нехватка памяти в ZONE_NORMAL
  • система, по kswapdправила, должен заранее видели некоторую пейджинговую активность, но ничего не выгружается, даже при нехватке памяти в ZONE_NORMAL, без видимой причины
  • Ничего из вышеперечисленного не дает четкой причины, почему oom-killer был вызван

Все это кажется довольно странным, но, по крайней мере, связано с тем, что описано в раздел 2.5 превосходной книги Джона О'Гормана «Общие сведения о диспетчере виртуальной памяти Linux»:

Поскольку адресное пространство, используемое ядром (ZONE_NORMAL), ограничено по размеру, ядро ​​поддерживает концепцию высокой памяти. [...] Для доступа к памяти в диапазоне от 1 ГБ до 4 ГБ ядро ​​временно отображает страницы из верхней памяти в ZONE_NORMAL с помощью kmap (). [...]

Это означает, что для описания 1 ГБ памяти требуется примерно 11 МБ памяти ядра. Таким образом, с 16 ГБ потребляется 176 МБ памяти, что оказывает значительное давление на ZONE_NORMAL. Звучит неплохо, пока не будут учтены другие структуры, использующие ZONE_NORMAL. Даже очень маленькие структуры, такие как записи таблиц страниц (PTE), в худшем случае требуют около 16 МБ. Это составляет 16 ГБ, что составляет практический предел доступной физической памяти Linux на x86..

(курсив мой)

Поскольку в 3.2 есть множество улучшений в управлении памятью по сравнению с 2.6, это не однозначный ответ, но действительно сильный намек, на который я хотел бы обратить внимание в первую очередь. Уменьшите полезную память хоста до 16 ГБ, используя mem= параметра ядра или путем извлечения половины модулей DIMM из сервера.

В конечном итоге использовать 64-битное ядро.

Чувак, это 2015 год.

Несколько вещей ...

Мое практическое правило для пространства подкачки заключалось в том, чтобы иметь как минимум вдвое больше физического барана. Это позволяет демону страницы / подкачки эффективно реорганизовывать память.

Server_B имеет 32 ГБ оперативной памяти, поэтому попробуйте настроить его на 64 ГБ подкачки. ИМО, 2 ГБ пространства подкачки на вашем сервере путь слишком низкий, особенно для сервера.

Если у вас нет дополнительного раздела, который можно превратить в раздел подкачки, вы можете проверить это, создав файл и смонтировав его как раздел подкачки [это будет медленно]. Видеть https://www.maketecheasier.com/swap-partitions-on-linux/

Поскольку server_B имеет много места на диске, --inplace не требуется и может быть нежелательным, поскольку может быть причиной того, что rsync использует 32 ГБ. --inplace действительно полезен только в том случае, если у вас мало места в файловой системе [чего у вас нет] или у вас есть особые требования к производительности.

Я предполагаю, что rsync захочет использовать 50 ГБ оперативной памяти [размер файла] с вашими текущими параметрами. Обычно rsync не требует много памяти для выполнения своей работы, поэтому проблема может быть в одном или нескольких вариантах. Обычно я без проблем передаю файлы размером 200 ГБ.

Сделайте несколько тестовых прогонов без каких-либо опций. Сделайте это с файлами меньшего размера, скажем, 10 ГБ - это должно предотвратить панику ядра, но все же позволит вам отслеживать поведение, вызывающее проблему. Следите за использованием памяти rsync.

Постепенно добавляйте параметры возврата, по одной, чтобы увидеть, какой параметр [или комбинация параметров] заставляет rsync начать извлекать выгоду из ОЗУ (например, пока происходит передача, использование оперативной памяти rsync увеличивается пропорционально объему передаваемых файловых данных, и т.д.).

Если вам действительно нужны параметры, которые заставляют rsync сохранять некоторый образ файла в оперативной памяти, вам понадобится дополнительное пространство подкачки, и ваш максимальный размер файла будет соответственно ограничен.

Еще несколько вещей [ОБНОВЛЕНО]:

(1) Отслеживание стека ядра показывает, что rsync вызвал сбой страницы в области mmap. Вероятно, это файл mmaping. mmap не гарантирует, что он будет сброшен на диск до того как файл закрывается [в отличие от чтения / записи], который сразу же попадает в кеш блоков FS [где он будет сброшен]

(2) Сбой ядра / паника происходит, когда размер передачи достигает размера ОЗУ. Очевидно, что rsync захватывает столько памяти, отличной от fscache, через malloc или mmap. Еще раз, с указанными вами параметрами, rsync выделит 50 ГБ памяти для передачи файла размером 50 ГБ.

(3) Передайте файл размером 24 ГБ. Вероятно, это сработает. Затем загрузите ядро ​​с mem = 16G и снова выполните тест файла размером 24 ГБ. Он выйдет на 16 ГБ, а не на 32 ГБ. Это подтвердит, что rsync действительно нуждается в памяти.

(4) Прежде чем вы скажете, что добавление подкачки нелепо, попробуйте добавить что-нибудь [с помощью метода подкачки в файл]. Это гораздо проще сделать и проверить, чем все академические аргументы о том, что подкачка не требуется. Даже если это не решение, вы можете чему-то научиться. Готов поспорить, что тест mem = 16G пройдет успешно без паники / сбоя.

(5) Скорее всего, rsync является происходит обмен, но это происходит слишком быстро, чтобы увидеть с помощью top, прежде чем OOM сработает и убьет rsync. К тому времени, когда rsync достигнет 32 ГБ, другие процессы уже были вынуждены отказаться от обмена, особенно если они простаивают. Возможно, комбинация «бесплатно» и «сверху» даст вам лучшую картину.

(6) После завершения работы rsync требуется время, чтобы сбросить mmap в FS. Недостаточно быстро для OOM и начинает убивать другие вещи [некоторые, очевидно, критически важны]. То есть ммап флеш и OOM гоняются. Или в OOM есть ошибка. В противном случае не было бы аварии.

(7) По моему опыту, как только система «упирается в стену памяти», Linux требуется много времени для полного восстановления. И иногда он никогда не восстанавливается должным образом, и единственный способ очистить его - это перезагрузка. Например, у меня 12 ГБ оперативной памяти. Когда я запускаю задание, использующее 40 ГБ памяти [у меня есть 120 ГБ подкачки для размещения больших заданий], а затем завершаю его, системе требуется около 10 минут, чтобы вернуться к нормальному быстродействию [с постоянно горящим индикатором диска] .

(8) Запустите rsync без параметры. Это сработает. Получите базовый пример для работы. Затем добавьте обратно --inplace и повторите попытку. Затем вместо этого выполните --append-verify. Затем попробуйте оба. Выясните, какая опция заставляет rsync делать огромный mmap. Затем решите, сможете ли вы жить без него. Если виной всему --inplace, это не проблема, поскольку у вас достаточно места на диске. Если у вас должна быть опция, вам нужно будет получить пространство подкачки для размещения malloc / mmap, которое будет выполнять rsync.

ВТОРОЕ ОБНОВЛЕНИЕ:

Выполните тесты файлов mem = и меньшего размера, как указано выше.

Центральный вопрос: почему OOM убивает rsync? Кто / что такое жевательная память?

Я читал [но забыл] о 32-битной системе. Итак, я согласен, rsync не может нести прямую ответственность (через malloc / mmap - glibc реализует большие mallocs через анонимные / частные mmap), а ошибка страницы mmap rsync просто запускает OOM случайно. Затем OOM вычисляет общий объем памяти, прямо или косвенно потребляемой rsync [кэш FS, буферы сокетов и т. Д.], И решает, что это главный кандидат. Итак, мониторинг общего использования памяти может быть полезным. Я подозреваю, что он подкрадывается с той же скоростью, что и передача файлов. Очевидно, что не должно.

Некоторые вещи, которые вы можете отслеживать в / proc или / proc / rsync_pid с помощью сценария perl или python в быстром цикле [сценарий bash, вероятно, не будет достаточно быстрым для события конца света], который может отслеживать все следующие несколько сотен раз / сек. Вы можете запустить это с более высоким приоритетом, чем rsync, чтобы он оставался в ОЗУ и работал, чтобы вы могли отслеживать события непосредственно перед сбоем и, надеюсь, во время OOM, чтобы вы могли понять, почему OOM сходит с ума:

/ proc / meminfo - чтобы получить больше подробностей об использовании свопа в "точке удара". На самом деле, получение окончательного количества используемой оперативной памяти может быть более полезным. Хотя это и обеспечивает top, этого может быть недостаточно, чтобы показать состояние Вселенной непосредственно перед "большим взрывом" (например, последние 10 миллисекунд).

Каталог / proc / rsync_pid / fd. Чтение символических ссылок позволит вам определить, какой fd открыт в целевом файле (например, ссылка для чтения / proc / rsync_pid / fd / 5 -> target_file). Вероятно, это нужно сделать только один раз, чтобы получить номер fd [он должен оставаться неизменным]

Зная номер fd, посмотрите / proc / rsync_pid / fdinfo / fd. Это текстовый файл, который выглядит так:

pos: <file_position>
flags: blah_blah
mnt_id: blah_blah

Мониторинг значения «pos» может быть полезным, так как может быть полезна «последняя позиция файла». Если вы выполните несколько тестов с разными размерами и параметрами mem =, отслеживает ли последняя позиция файла какие-либо из этих [и как]? Обычное подозрение: позиция файла == доступная оперативная память

Но самый простой способ - начать с «rsync local_file server: remote_file» и проверить, что работает. Вы можете получить аналогичные [но более быстрые] результаты, выполнив «ssh server rsync file_a file_b» [сначала вам нужно создать файл file_a размером 50 ГБ]. Простым способом создания file_a является scp local_system: original_file server: file_a, и это может быть интересно само по себе (например, работает ли это при сбое rsync? Если scp работает, но rsync не работает, это указывает на rsync. Если scp не работает, это указывает к чему-то еще, например к драйверу сетевой карты). Выполнение ssh rsync также исключает сетевой адаптер из уравнения, что может быть полезно. Если это залит систему, значит, что-то действительно не так. Если это удастся, [как я уже упоминал] начните добавлять параметры один за другим.

Я не хочу вдаваться в подробности, но добавление подкачки через swap-to-file может изменить / задержать поведение при сбое и может быть полезно в качестве диагностического инструмента. Если добавление, скажем, 16 ГБ подкачки задерживает сбой (измеряемый по использованию памяти или положению целевого файла) с 32 ГБ до 46 ГБ, то это о чем-то говорит.

Это может быть не какой-то конкретный процесс, а ошибочный драйвер ядра, который жует память. Внутренний vmalloc ядра выделяет материал, и его можно выгрузить. IIRC, он не связан адресностью ни при каких обстоятельствах.

Ясно, что OOM запутался / запаниковал. То есть он убивает rsync, но не видит, что память своевременно освобождается, и ищет других жертв. Некоторые из них, вероятно, имеют решающее значение для работы системы.

Помимо malloc / mmap, это может быть вызвано не очищенным кешем FS, который занимает много времени (например, с 30 ГБ незаброшенных данных, предполагая, что скорость диска составляет 300 МБ / с, для его очистки может потребоваться 100 секунд). Даже в этом случае OOM может быть слишком нетерпеливым. Или OOM, убивающий rsync, не запускает флеш-память достаточно быстро [или вообще]. Либо сброс файловой системы происходит достаточно быстро, но при этом происходит «ленивый» выпуск страниц обратно в пул свободных страниц. Есть несколько параметров / proc, которые вы можете установить для управления поведением кэша FS [я не могу вспомнить, что это такое].

Попробуйте загрузиться с mem = 4G или другим небольшим числом. Это может сократить кеш-память FS и сократить время его очистки, чтобы OOM не искал другие вещи, которые можно было бы убить (например, время очистки сокращено со 100 до <1 секунды). Это также может выявить ошибку OOM, которая не может обрабатывать физическую оперативную память> 4 ГБ в 32-битной системе или что-то подобное.

Также важный момент: запускать без полномочий root. От пользователей root никогда не ожидается, что они будут пережевывать ресурсы, поэтому им предоставляются более щадящие ограничения (например, 99% памяти против 95% для пользователей без полномочий root). Это может объяснить, почему OOM находится в таком состоянии. Кроме того, это дает OOM et. al. больше места для восстановления памяти.

clamd? Похоже, вы используете ClamAV и включили сканирование при доступе, когда антивирусное ядро ​​пытается сканировать открытые файлы на наличие вирусов, загружая в память, все содержимое каждого файла, открытого любым другим процессом.

В зависимости от вашей системы безопасности и необходимости этой передачи вам следует оценить отключение сканирования ClamAV при доступе во время выполнения передачи.