Rsync löste den Linux OOM-Killer bei einer einzelnen 50 GB-Datei aus

Rsync löste den Linux OOM-Killer bei einer einzelnen 50 GB-Datei aus

Ich habe eine einzelne 50 GB große Datei auf Server_A und kopiere sie auf Server_B. Ich führe

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

Server_B hat 32 GB RAM mit 2 GB Swap. Er ist größtenteils im Leerlauf und sollte viel freien RAM haben. Er hat viel Speicherplatz. Bei etwa 32 GB wird die Übertragung abgebrochen, weil die Remote-Seite die Verbindung geschlossen hat.

Server_B ist jetzt vom Netzwerk getrennt. Wir bitten das Rechenzentrum, ihn neu zu starten. Wenn ich mir das Kernel-Protokoll von vor dem Absturz anschaue, sehe ich, dass er 0 Byte Swap verwendet hat und die Prozessliste sehr wenig Speicher verwendet hat (der rsync-Prozess wurde mit 600 KB RAM aufgeführt), aber der oom_killer spielte verrückt und das Letzte im Protokoll ist, wo er den Kernel-Reader-Prozess von Metalog beendet.

Dies ist Kernel 3.2.59, 32-Bit (also kann kein Prozess mehr als 4 GB zuordnen).

Es ist fast so, als ob Linux dem Caching mehr Priorität einräumt als langlebigen Daemons. Was ist da los? Und wie kann ich verhindern, dass es wieder passiert?

Hier ist die Ausgabe von 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

Hier ist die „Top“-Ausgabe nach Wiederholung meines rsync-Befehls als Nicht-Root-Benutzer:

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

Hier sind die Sysctl-VM-Parameter:

# 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

Antwort1

Lesen wir also die Ausgabe von oom-killer und sehen wir, was sich daraus lernen lässt.

Bei der Analyse von OOM-Killer-Logs ist es wichtig, sich anzusehen, was den Angriff ausgelöst hat. Die erste Zeile Ihres Logs gibt uns einige Hinweise:

[Kernel] [1772321.850644] clamd hat Oom-Killer aufgerufen:gfp_mask=0x84d0, Reihenfolge=0

order=0teilt uns mit, wie viel Speicher angefordert wird. Die Speicherverwaltung des Kernels kann nur Seitenzahlen in Zweierpotenzen verwalten, daher hat clamd 2 0 Seiten Speicher oder 4 KB angefordert.

Die untersten zwei Bits der GFP_MASK (get free page mask) bilden die sog.Zonenmaske dem Allokator mitteilen, aus welcher Zone der Speicher bezogen werden soll:

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

Speicherzonenist ein Konzept, das hauptsächlich aus Kompatibilitätsgründen entwickelt wurde. Vereinfacht betrachtet gibt es drei Zonen für einen x86-Kernel:

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

In Ihrem Fall ist die Zonenmaske 0, was bedeutet, dass clamd Speicher von anfordert ZONE_NORMAL.

Die anderen Flaggen werden aufgelöst zu

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

entsprechend derLinux MM-Dokumentation, Ihre Anfrage verfügt also über die Flags für GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOund und GFP_WAITist somit nicht besonders wählerisch.

Was ist also los mit ZONE_NORMAL? Einige allgemeine Statistiken finden Sie weiter unten in der OOM-Ausgabe:

[kernel] [1772321.850770] Normalfrei: 8056 kB min: 8048 kB niedrig: 10060 kBhoch: 12072 kB aktiv_anon: 0 kB inaktiv_anon: 0 kB aktiv_datei: 248 kB inaktiv_datei: 388 kB nicht auslagerbar: 0 kB isoliert (anon): 0 kB isoliert (datei): 0 kB vorhanden: 890008 kB

Auffällig ist hier, dassfreeist nur 8K vonminund weit unterlow. Das bedeutet, dass der Speichermanager Ihres Hosts in Schwierigkeiten ist und kswapd bereits Seiten auslagern sollte, da es sich imGelbPhase der Grafik unten: Diagramm des Linux-Speichermanagers

Weitere Informationen zur Speicherfragmentierung der Zone finden Sie hier:

[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

Es besagt im Wesentlichen, dass Sie eine einzelne zusammenhängende Seite mit 4 MB haben, während der Rest stark in hauptsächlich 4-KB-Seiten fragmentiert ist.

Fassen wir also zusammen:

  • Sie haben einen Userland-Prozess ( clamd), der Speicher abruft ZONE_NORMAL, während die nicht privilegierte Speicherzuweisung normalerweise von durchgeführt wirdZONE_HIMEM
  • der Speichermanager sollte zu diesem Zeitpunkt in der Lage sein, die angeforderte 4K-Seite bereitzustellen, obwohl Sie anscheinend erheblichen Speicherdruck haben inZONE_NORMAL
  • das System, nach kswapdden Regeln,sollenhabe vorher einige Paging-Aktivitäten gesehen, aber nichts wird ausgelagert, auch nicht unter Speicherdruck in ZONE_NORMAL, ohne ersichtlichen Grund
  • Keiner der oben genannten Punkte gibt einen eindeutigen Grund dafür an, warum oom-killerer angerufen wurde

Das alles erscheint recht merkwürdig, aber es ist zumindest mit dem zu vergleichen, was inAbschnitt 2.5 von John O'Gormans hervorragendem Buch „Understanding the Linux Virtual Memory Manager“:

Da der vom Kernel nutzbare Adressraum (ZONE_NORMAL) in seiner Größe begrenzt ist, unterstützt der Kernel das Konzept des High Memory. [...] Um auf Speicher im Bereich zwischen 1 GiB und 4 GiB zuzugreifen, ordnet der Kernel Seiten aus dem High Memory mit kmap() vorübergehend in ZONE_NORMAL zu. [...]

Das bedeutet, dass zur Beschreibung von 1 GiB Speicher etwa 11 MiB Kernelspeicher erforderlich sind. Bei 16 GiB werden also 176 MiB Speicher verbraucht, was ZONE_NORMAL erheblich belastet. Das klingt nicht allzu schlimm, bis andere Strukturen berücksichtigt werden, die ZONE_NORMAL verwenden. Selbst sehr kleine Strukturen wie Page Table Entries (PTEs) benötigen im schlimmsten Fall etwa 16 MiB.Damit ist 16GiB ungefähr die praktische Grenze für den verfügbaren physischen Speicher unter Linux auf einem x86.

(Hervorhebung von mir)

Da 3.2 gegenüber 2.6 zahlreiche Verbesserungen in der Speicherverwaltung aufweist, ist dies keine eindeutige Antwort, aber ein wirklich wichtiger Hinweis, dem ich zuerst nachgehen würde. Reduzieren Sie den nutzbaren Speicher des Hosts auf höchstens 16 GB, indem Sie entweder den mem=Kernelparameter verwenden oder die Hälfte der DIMMs aus dem Server entfernen.

Letzten Endes,Verwenden Sie einen 64-Bit-Kernel.

Alter, wir haben 2015.

Antwort2

Ein paar Dinge ...

Meine Faustregel für den Swap-Speicher ist, mindestens die doppelte Menge an physischem RAM zu haben. Dadurch kann der Page/Swap-Daemon den Speicher effizient neu organisieren.

Server_B hat 32 GB RAM, also versuchen Sie, ihn für 64 GB Swap zu konfigurieren. Meiner Meinung nach sind die 2 GB Swap-Speicher Ihres ServersWegzu niedrig, insbesondere für einen Server.

Wenn Sie keine zusätzliche Partition haben, die Sie in eine Swap-Partition umwandeln können, können Sie dies testen, indem Sie eine Datei erstellen und diese als Swap-Partition mounten [das wird langsam sein]. Siehehttps://www.maketecheasier.com/swap-partitions-on-linux/

Da Server_B über reichlich Speicherplatz verfügt, wird --inplace nicht benötigt und ist möglicherweise unerwünscht, da es der Grund dafür sein könnte, dass rsync 32 GB verwendet. --inplace ist nur dann wirklich nützlich, wenn Sie nur wenig Speicherplatz im Dateisystem haben [was nicht der Fall ist] oder besondere Leistungsanforderungen haben.

Ich schätze, dass rsync mit Ihren aktuellen Optionen 50 GB RAM [die Dateigröße] verwenden möchte. Normalerweise benötigt rsync für seine Arbeit nicht so viel Speicher, daher kann eine oder mehrere Ihrer Optionen das Problem sein. Ich übertrage routinemäßig 200 GB große Dateien ohne Probleme.

Führen Sie einige Testläufe ohne Optionen durch. Tun Sie dies mit kleineren Dateien, beispielsweise 10 GB. Dies sollte den Kernel-Panic verhindern, Ihnen aber dennoch ermöglichen, das Verhalten zu überwachen, das das Problem verursacht. Überwachen Sie die Speichernutzung von rsync.

Fügen Sie nach und nach wieder Optionen hinzu, jeweils eine, um zu sehen, welche Option [oder Kombination von Optionen] dazu führt, dass rsync den RAM voll beansprucht (z. B. wächst während der Übertragung die RAM-Nutzung von rsync proportional zur Menge der übertragenen Dateidaten usw.).

Wenn Sie die Optionen, die rsync dazu veranlassen, einige Dateiabbilder im RAM zu behalten, wirklich benötigen, brauchen Sie den zusätzlichen Swap-Speicherplatz und Ihre maximale Dateigröße wird entsprechend begrenzt.

Noch ein paar Dinge [AKTUALISIERT]:

(1) Der Kernel-Stack-Traceback zeigt, dass rsync einen Seitenfehler in einem mmap-Bereich hatte. Wahrscheinlich wird die Datei mmaped. mmap bietet keine Garantie dafür, dass die Datei auf die Festplatte geschrieben wird.bisdie Datei wird geschlossen [im Gegensatz zum Lesen/Schreiben], das sofort in den FS-Blockcache geht [wo sie geleert wird]

(2) Der Kernel stürzt ab/ist in Panik, wenn die Übertragungsgröße die Größe des RAM erreicht. Offensichtlich greift rsync über malloc oder mmap auf so viel Nicht-Fscache-Speicher zu. Noch einmal: Mit den von Ihnen angegebenen Optionen wird rsync 50 GB Speicher für die Übertragung einer 50 GB großen Datei reservieren.

(3) Übertragen Sie eine 24 GB große Datei. Das wird wahrscheinlich funktionieren. Booten Sie dann den Kernel mit mem=16G und führen Sie den 24 GB großen Dateitest erneut durch. Er wird bei 16 GB und nicht bei 32 GB ausfallen. Dies bestätigt, dass rsync den Speicher wirklich benötigt.

(4) Bevor Sie sagen, dass das Hinzufügen von Swap lächerlich ist, versuchen Sie, etwas hinzuzufügen [über die Swap-to-File-Methode]. Das ist viel einfacher zu machen und zu testen als all die akademischen Argumente darüber, dass Swap nicht erforderlich ist. Selbst wenn es nicht die Lösung ist, können Sie etwas daraus lernen. Ich wette, dass der Test mit mem=16G ohne Panik/Absturz erfolgreich sein wird.

(5) Es besteht die Möglichkeit, dass rsyncIstSwap wird ausgeführt, aber es passiert zu schnell, um es mit Top zu sehen, bevor OOM einsetzt und rsync beendet. Bis rsync 32 GB erreicht, wurden andere Prozesse bereits in den Swap gezwungen, insbesondere wenn sie im Leerlauf sind. Vielleicht gibt Ihnen eine Kombination aus „free“ und „top“ ein besseres Bild.

(6) Nachdem rsync beendet wurde, dauert es eine Weile, bis mmap ins FS geschrieben wird. Das geht für OOM nicht schnell genug und es beginnt, andere Dinge zu beenden [einige davon sind offensichtlich unternehmenskritisch]. Das heißt, das Schreiben von mmap und OOM liefern sich ein Wettrennen. Oder OOM hat einen Fehler. Sonst würde es keinen Absturz geben.

(7) Meiner Erfahrung nach dauert es sehr lange, bis sich Linux vollständig erholt, wenn ein System einmal „an die Speicherwand stößt“. Und manchmal wird es nie richtig wiederhergestellt und die einzige Möglichkeit, es zu löschen, ist ein Neustart. Ich habe beispielsweise 12 GB RAM. Wenn ich einen Job ausführe, der 40 GB Speicher verwendet [ich habe 120 GB Swap, um große Jobs unterzubringen] und ihn dann beende, dauert es etwa 10 Minuten, bis das System wieder normal reagiert [wobei die Festplattenleuchte die ganze Zeit durchgängig leuchtet].

(8) Führen Sie rsync ausohneOptionen. Das wird funktionieren. Holen Sie sich ein Basisbeispiel, mit dem Sie arbeiten können. Fügen Sie dann --inplace wieder hinzu und testen Sie erneut. Führen Sie dann stattdessen --append-verify aus. Probieren Sie dann beides aus. Finden Sie heraus, mit welcher Option rsync das riesige mmap ausführt. Entscheiden Sie dann, ob Sie ohne leben können. Wenn --inplace der Übeltäter ist, ist das ein Kinderspiel, da Sie über reichlich Speicherplatz verfügen. Wenn Sie die Option unbedingt haben müssen, müssen Sie den Swap-Speicherplatz bereitstellen, um das malloc/mmap unterzubringen, das rsync ausführen wird.

ZWEITES UPDATE:

Führen Sie bitte die oben genannten Mem=- und kleineren Dateitests durch.

Die zentralen Fragen: Warum wird rsync durch OOM beendet? Wer/Was frisst Speicher?

Ich habe gelesen [aber vergessen], dass das System 32 Bit ist. Ich stimme also zu, dass rsync möglicherweise nicht direkt verantwortlich ist (über malloc/mmap – glibc implementiert große mallocs über anonyme/private mmaps) und der mmap-Seitenfehler von rsync OOM nur zufällig auslöst. Dann berechnet OOM den gesamten von rsync direkt und indirekt verbrauchten Speicher [FS-Cache, Socket-Puffer usw.] und entscheidet, dass dies der Hauptkandidat ist. Daher kann es hilfreich sein, die gesamte Speichernutzung zu überwachen. Ich vermute, dass sie mit der gleichen Geschwindigkeit ansteigt wie die Dateiübertragung. Das sollte sie offensichtlich nicht.

Einige Dinge können Sie in /proc oder /proc/rsync_pid über ein Perl- oder Python-Skript in einer schnellen Schleife überwachen [ein Bash-Skript wird für das Weltuntergangsereignis wahrscheinlich nicht schnell genug sein], das alle der folgenden Dinge mehrere hundert Mal pro Sekunde überwachen kann. Sie können dies mit einer höheren Priorität als rsync ausführen, damit es sich selbst im RAM und am Laufen hält, sodass Sie die Dinge kurz vor dem Absturz und hoffentlich während OOM überwachen können, damit Sie sehen können, warum OOM verrückt spielt:

/proc/meminfo – um die Swap-Nutzung am „Point of Impact“ genauer zu erfassen. Tatsächlich ist es möglicherweise nützlicher, die endgültige Zahl zu erhalten, wie viel RAM insgesamt verwendet wird. Obwohl top dies bereitstellt, ist es möglicherweise nicht schnell genug, um den Zustand des Universums unmittelbar vor dem „Urknall“ anzuzeigen (z. B. die letzten 10 Millisekunden).

/proc/rsync_pid/fd-Verzeichnis. Durch Lesen der symbolischen Links können Sie feststellen, welches FD für die Zieldatei geöffnet ist (z. B. Leselink von /proc/rsync_pid/fd/5 --> Zieldatei). Dies muss wahrscheinlich nur einmal durchgeführt werden, um die FD-Nummer zu erhalten [es sollte unverändert bleiben].

Wenn Sie die fd-Nummer kennen, schauen Sie in /proc/rsync_pid/fdinfo/fd. Es ist eine Textdatei, die folgendermaßen aussieht:

pos: <Dateiposition>
Flaggen: bla_bla
mnt_id: bla_bla

Die Überwachung des „pos“-Werts kann hilfreich sein, da die „letzte Dateiposition“ nützlich sein kann. Wenn Sie mehrere Tests mit unterschiedlichen Größen und Mem=-Optionen durchführen, verfolgt die letzte Dateiposition dann irgendetwas davon [und wie]? Der übliche Verdächtige: Dateiposition == verfügbarer RAM

Am einfachsten ist es jedoch, mit „rsync local_file server:remote_file“ zu beginnen und zu prüfen, ob das funktioniert. Möglicherweise erhalten Sie ähnliche [aber schnellere] Ergebnisse, indem Sie „ssh server rsync file_a file_b“ ausführen [dazu müssten Sie zuerst eine 50 GB große Datei_a erstellen]. Eine einfache Möglichkeit, Datei_a zu erstellen, ist scp local_system:original_file server:file_a, und das könnte an sich schon interessant sein (funktioniert das beispielsweise, wenn rsync abstürzt? Wenn scp funktioniert, aber rsync fehlschlägt, verweist dies auf rsync. Wenn scp fehlschlägt, verweist dies auf etwas anderes wie den NIC-Treiber). Durch das Ausführen von ssh rsync wird auch die NIC aus der Gleichung genommen, was hilfreich sein kann. Wenn das das System ruiniert, stimmt etwas wirklich nicht. Wenn es erfolgreich ist, beginnen Sie [wie erwähnt], die Optionen nacheinander wieder hinzuzufügen.

Ich möchte diesen Punkt nicht überbetonen, aber das Hinzufügen von Swap über Swap-to-File kann das Absturzverhalten ändern/verzögern und kann als Diagnosetool nützlich sein. Wenn das Hinzufügen von beispielsweise 16 GB Swap den Absturz [gemessen an der Speichernutzung oder der Zieldateiposition] von 32 GB auf 46 GB verzögert, dann sagt das schon etwas aus.

Es muss sich nicht um einen bestimmten Prozess handeln, sondern um einen fehlerhaften Kerneltreiber, der Speicher verschlingt. Das interne vmalloc des Kernels weist Daten zu und diese können ausgelagert werden. Soweit ich mich erinnere, ist es nicht unter allen Umständen an die Adressierbarkeit gebunden.

Offensichtlich ist der OOM verwirrt/in Panik. Das heißt, er beendet rsync, sieht aber nicht, dass der Speicher rechtzeitig freigegeben wird, und sucht nach anderen Opfern. Einige davon sind wahrscheinlich kritisch für den Systembetrieb.

Abgesehen von malloc/mmap könnte dies durch einen nicht geleerten FS-Cache verursacht werden, der lange dauert (z. B. kann es bei 30 GB nicht geleerter Daten bei einer angenommenen Festplattenrate von 300 MB/s 100 Sekunden dauern, ihn zu leeren). Selbst bei dieser Rate ist OOM möglicherweise zu ungeduldig. Oder OOM, das rsync beendet, startet die FS-Leerung nicht schnell genug [oder überhaupt nicht]. Oder die FS-Leerung erfolgt schnell genug, aber die Seiten werden „träge“ wieder in den freien Pool freigegeben. Es gibt einige /proc-Optionen, die Sie festlegen können, um das Verhalten des FS-Cache zu steuern [ich kann mich nicht erinnern, welche das sind].

Versuchen Sie, mit mem=4G oder einer anderen kleinen Zahl zu booten. Dies könnte den FS-Cache verkleinern und seine Leerungszeit verkürzen, um OOM davon abzuhalten, nach anderen Dingen zu suchen, die es beenden kann (z. B. wird die Leerungszeit von 100 Sekunden auf < 1 Sekunde reduziert). Es könnte auch einen OOM-Fehler entlarven, der physischen RAM > 4 GB auf einem 32-Bit-System oder Ähnlichem nicht verarbeiten kann.

Außerdem ein wichtiger Punkt: Führen Sie es als Nicht-Root aus. Von Root-Benutzern wird nie erwartet, dass sie Ressourcen verbrauchen, daher gelten für sie großzügigere Grenzen (z. B. 99 % des Speichers gegenüber 95 % für Nicht-Root-Benutzer). Dies könnte erklären, warum sich OOM in einem solchen Zustand befindet. Außerdem gibt dies OOM und anderen mehr Spielraum, um Speicher freizugeben.

Antwort3

Es klingt, als ob Sie ClamAV verwenden und On-Access-Scans aktiviert haben, bei denen die Antiviren-Engine versucht, geöffnete Dateien auf Viren zu scannen.durch Laden des gesamten Inhalts jeder von einem anderen Prozess geöffneten Datei in den Speicher.

Abhängig von Ihrer Sicherheitslage und der Notwendigkeit dieser Übertragung sollten Sie erwägen, die On-Access-Überprüfung von ClamAV während der Übertragung zu deaktivieren.

verwandte Informationen