it-swarm.com.de

Rsync löste den Linux OOM-Killer für eine einzelne 50-GB-Datei aus

Ich habe eine einzelne 50-GB-Datei auf server_A und kopiere sie auf server_B. ich renne

server_A$ rsync --partial --progress --inplace --append-verify 50GB_file [email protected]_B:50GB_file

Server_B hat 32 GB RAM mit 2 GB Swap. Es ist meistens inaktiv und sollte viel freien RAM haben. Es hat viel Speicherplatz. Bei ungefähr 32 GB wird die Übertragung abgebrochen, weil die Remote-Seite schloss die Verbindung.

Server_B hat das Netzwerk jetzt verlassen. Wir bitten das Rechenzentrum, es neu zu starten. Wenn ich mir das Kernel-Protokoll vor dem Absturz ansehe, sehe ich, dass es 0 Byte Swap verwendet und die Prozessliste sehr wenig Speicher verwendet (der rsync-Prozess wurde mit 600 KB RAM aufgelistet), der oom_killer jedoch Es wird wild, und das Letzte im Protokoll ist, wo es den Kernel-Reader-Prozess von Metalog beendet.

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

Es ist fast so, als hätte Linux dem Caching mehr Priorität eingeräumt als langlebigen Daemons. Was gibt?? Und wie kann ich verhindern, dass es wieder passiert?

Hier ist die Ausgabe des 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 dem Wiederholen meines Befehls rsync 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
67
dataless

Lesen wir also die Oom-Killer-Ausgabe und sehen, was daraus gelernt werden kann.

Bei der Analyse von OOM-Killerprotokollen ist es wichtig zu prüfen, was sie ausgelöst hat. Die erste Zeile Ihres Protokolls gibt uns einige Hinweise:

[Kernel] [1772321.850644] Clamd hat Oom-Killer aufgerufen: gfp_mask = 0x84d0, order = 0

order=0 Gibt an, wie viel Speicher angefordert wird. Die Speicherverwaltung des Kernels kann nur Seitenzahlen mit der Potenz 2 verwalten, daher hat clamd 2 angefordert Speicherseiten oder 4 KB.

Die untersten zwei Bits des GFP_MASK (Get Free Page Mask) bilden die sogenannte Zonenmaske, die dem Allokator mitteilt, von welcher Zone der Speicher abgerufen 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

Speicherzonen sind ein Konzept, das hauptsächlich aus Kompatibilitätsgründen erstellt wurde. In einer vereinfachten Ansicht 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 ZONE_NORMAL Anfordert.

Die anderen Flags werden in aufgelöst

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

gemäß der Linux MM-Dokumentation hat Ihre Anforderung also die Flags für GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IO Und GFP_WAIT, Daher nicht besonders wählerisch.

Also, was ist los mit ZONE_NORMAL? Einige generische Statistiken finden Sie weiter unten in der OOM-Ausgabe:

[Kernel] [1772321.850770] Normal frei: 8056 kB min: 8048 kB niedrig: 10060 kB hoch: 12072 kB active_anon: 0 kB inactive_anon : 0kB active_file: 248kB inactive_file: 388kB nicht vorhersehbar: 0kB isoliert (anon): 0kB isoliert (Datei): 0kB vorhanden: 890008kB

Hier fällt auf, dass free Nur 8 KB von min und weit unter low. Dies bedeutet, dass der Speichermanager Ihres Hosts etwas in Bedrängnis ist und kswapd bereits Seiten austauschen sollte, wie es sich in der Phase gelb des folgenden Diagramms befindet: Linux memory manager graph

Weitere Informationen zur Speicherfragmentierung der Zone finden Sie hier:

[Kernel] [1772321.850795] Normal: 830 * 4 kB 80 * 8 kB 0 * 16 kB 0 * 32 kB 0 * 64 kB 0 * 128 kB 0 * 256 kB 0 * 512 kB 0 * 1024 kB 0 * 2048 kB 1 * 4096 kB = 8056 kB

grundsätzlich wird angegeben, dass Sie eine einzelne zusammenhängende Seite mit 4 MB haben, während der Rest stark in hauptsächlich 4 KB große Seiten fragmentiert ist.

Fassen wir also zusammen:

  • sie haben einen Userland-Prozess (clamd), der Speicher von ZONE_NORMAL abruft, während die nicht privilegierte Speicherzuweisung normalerweise von ZONE_HIMEM ausgeführt wird.
  • der Speichermanager sollte zu diesem Zeitpunkt in der Lage sein, die angeforderte 4K-Seite zu bedienen, obwohl Sie in ZONE_NORMAL anscheinend einen erheblichen Speicherdruck haben.
  • das System hat nach den Regeln von kswapd sollte zuvor einige Paging-Aktivitäten gesehen, aber selbst unter Speicherdruck in ZONE_NORMAL wird nichts ausgetauscht. ohne erkennbaren Grund
  • Keiner der oben genannten Gründe gibt einen eindeutigen Grund dafür an, warum oom-killer Aufgerufen wurde

All dies scheint ziemlich seltsam, ist aber zumindest mit dem verbunden, was in Abschnitt 2.5 von John O'Gormans ausgezeichnetem Buch "Understanding the Linux Virtual Memory Manager" beschrieben ist:

Da der vom Kernel (ZONE_NORMAL) verwendbare Adressraum begrenzt ist, unterstützt der Kernel das Konzept des hohen Speichers. [...] Um auf Speicher zwischen 1 GB und 4 GB zuzugreifen, ordnet der Kernel Seiten aus dem hohen Speicher mit kmap () vorübergehend ZONE_NORMAL zu. [...]

Das bedeutet, dass zur Beschreibung von 1 GB Speicher ca. 11 MB Kernel-Speicher erforderlich sind. Somit werden mit 16 GB 176 MB Speicher verbraucht, was einen erheblichen Druck auf ZONE_NORMAL ausübt. Dies klingt nicht schlecht, 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 MB. Dies macht 16 GB über die praktische Grenze für den verfügbaren physischen Speicher Linux auf einem x86.

(Schwerpunkt liegt bei mir)

Da 3.2 gegenüber 2.6 zahlreiche Fortschritte in der Speicherverwaltung aufweist, ist dies keine eindeutige Antwort, sondern ein wirklich starker Hinweis, den ich zuerst verfolgen würde. Reduzieren Sie den nutzbaren Speicher des Hosts auf höchstens 16 GB, indem Sie entweder den Kernel-Parameter mem= Verwenden oder die Hälfte der DIMMs vom Server rippen.

Letztendlich benutze einen 64-Bit-Kernel.

Alter, es ist 2015.

179
the-wabbit

Ein paar Dinge ...

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

Server_B verfügt über 32 GB RAM. Versuchen Sie daher, ihn für 64 GB Swap zu konfigurieren. IMO, die 2 GB Swap-Speicherplatz Ihres Servers ist way zu 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 als Swap-Partition bereitstellen [es wird langsam sein]. Siehe https://www.maketecheasier.com/swap-partitions-on-linux/

Da server_B über ausreichend Speicherplatz verfügt, wird --inplace nicht benötigt und ist möglicherweise unerwünscht, da rsync möglicherweise 32 GB verwendet. --inplace ist nur dann wirklich nützlich, wenn Sie nicht genügend Speicherplatz im Dateisystem haben (was Sie nicht sind) oder besondere Leistungsanforderungen haben.

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

Führen Sie einige Testläufe ohne Optionen durch. Tun Sie dies mit kleineren Dateien, z. B. 10 GB. Dies sollte die Kernel-Panik verhindern, aber Sie können trotzdem das Verhalten überwachen, das das Problem verursacht. Überwachen Sie die Speichernutzung von rsync.

Fügen Sie nach und nach nacheinander Optionen zurück, um zu sehen, welche Option [oder Kombination von Optionen] dazu führt, dass rsync auf RAM startet (z. B. während der Übertragung wächst die RAM-Nutzung von rsync proportional zum Menge der übertragenen Dateidaten usw.).

Wenn Sie wirklich die Optionen benötigen, die dazu führen, dass rsync ein In-Ram-Dateibild beibehält, benötigen Sie zusätzlichen Swap-Speicherplatz, und Ihre maximale Dateigröße wird entsprechend begrenzt.

Noch ein paar Dinge [AKTUALISIERT]:

(1) Das Kernel-Stack-Traceback zeigt, dass rsync in einem mmap-Bereich einen Seitenfehler aufwies. Es wird wahrscheinlich die Datei mmap. mmap bietet keine Garantie dafür, dass es auf die Festplatte geleert wird bis Die Datei ist geschlossen [im Gegensatz zu Lesen/Schreiben], die sofort in den Blockcache FS [wo sie sich befindet] verschoben wird gespült]

(2) Der Kernel-Absturz/die Kernel-Panik tritt auf, wenn die Übertragungsgröße die Größe des Arbeitsspeichers erreicht. Offensichtlich greift rsync über malloc oder mmap auf so viel Nicht-fscache-Speicher zu. Mit den von Ihnen angegebenen Optionen weist rsync erneut 50 GB Speicher für die Übertragung einer 50 GB-Datei zu.

(3) Übertragen Sie eine 24-GB-Datei. Das wird wahrscheinlich funktionieren. Starten Sie dann den Kernel mit mem = 16G und führen Sie den 24-GB-Dateitest erneut durch. Es wird bei 16 GB statt 32 GB ausblasen. 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, einige hinzuzufügen [über die Swap-to-File-Methode]. Dies ist weitaus einfacher zu tun und zu testen als alle akademischen Argumente darüber, wie ein Tausch nicht erforderlich ist. Auch wenn es nicht die Lösung ist, können Sie etwas daraus lernen. Ich wette, dass der mem = 16G-Test ohne Panik/Absturz erfolgreich sein wird.

(5) Es besteht die Möglichkeit, dass rsync is Swap trifft, aber es passiert zu schnell, um mit top zu sehen, bevor OOM einschaltet und rsync beendet. Bis rsync 32 GB erreicht, müssen andere Prozesse bereits ausgetauscht werden, insbesondere wenn sie inaktiv sind. Vielleicht gibt Ihnen eine Kombination aus "frei" und "oben" ein besseres Bild.

(6) Nachdem rsync beendet wurde, dauert es einige Zeit, bis mmap auf den FS übertragen wird. Nicht schnell genug für OOM und es beginnt andere Dinge zu töten [einige sind offensichtlich geschäftskritisch]. Das heißt, die mmap Flush und OOM fahren Rennen. Oder OOM hat einen Fehler. Sonst würde es keinen Absturz geben.

(7) Nach meiner Erfahrung dauert es lange, bis ein System vollständig wiederhergestellt ist, sobald ein System "die Speicherwand erreicht". Und manchmal wird es nie richtig wiederhergestellt und der einzige Weg, es zu löschen, ist ein Neustart. Zum Beispiel habe ich 12 GB RAM. Wenn ich einen Job ausführe, der 40 GB Arbeitsspeicher verwendet [ich habe 120 GB Swap, um große Jobs aufzunehmen] und ihn dann beende, dauert es ungefähr 10 Minuten, bis das System wieder normal reagiert [wenn die Festplattenanzeige die ganze Zeit über leuchtet] .

(8) Führen Sie die Optionen rsync ohne Aus. Das wird funktionieren. Holen Sie sich ein Basisbeispiel zum Arbeiten. Dann wieder hinzufügen - ersetzen und erneut testen. Führen Sie stattdessen --append-verify aus. Dann versuchen Sie beide. Finden Sie heraus, mit welcher Option rsync die riesige mmap ausführt. Dann entscheide, ob du ohne leben kannst. Wenn --inplace der Schuldige ist, ist das ein Kinderspiel, da Sie viel Speicherplatz haben. Wenn Sie die Option haben müssen, müssen Sie den Swap-Bereich erhalten, um die Malloc/mmap aufzunehmen, die rsync ausführt.

ZWEITES UPDATE:

Bitte führen Sie die oben genannten Tests für mem = und kleinere Dateien durch.

Die zentralen Fragen: Warum wird rsync von OOM getötet? Wer/Was kaut Erinnerung?

Ich habe [aber vergessen] gelesen, dass das System 32 Bit ist. Daher stimme ich 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 löst nur zufällig OOM aus. Anschließend berechnet OOM den von rsync direkt und indirekt verbrauchten Gesamtspeicher [FS-Cache, Socket-Puffer usw.] und entscheidet, dass dies der Hauptkandidat ist. Daher kann die Überwachung der gesamten Speichernutzung hilfreich sein. Ich vermute, dass es sich mit der gleichen Geschwindigkeit wie die Dateiübertragung einschleicht. Offensichtlich sollte es nicht.

Einige Dinge, die Sie in/proc oder/proc/rsync_pid über ein Perl- oder python Skript in einer schnellen Schleife überwachen können [ein Bash-Skript ist wahrscheinlich nicht schnell genug für das Ereignis am Ende der Welt ], die alle folgenden mehrere hundert Mal/Sek. überwachen können. Sie können dies mit einer höheren Priorität als rsync ausführen, damit es in RAM bleibt und ausgeführt wird, damit Sie die Dinge kurz vor dem Absturz und hoffentlich während der OOM überwachen können, damit Sie sehen können, warum OOM verrückt wird:

/ proc/meminfo - um mehr Feinkorn für die Swap-Nutzung am "Aufprallpunkt" zu erhalten. Tatsächlich kann es nützlicher sein, die endgültige Zahl darüber zu ermitteln, wie viel RAM insgesamt verwendet wird. Während top dies bereitstellt, ist es möglicherweise nicht schnell genug, um den Zustand des Universums unmittelbar vor dem "Urknall" (z. B. den letzten 10 Millisekunden) anzuzeigen.

Verzeichnis/proc/rsync_pid/fd. Durch Lesen der Symlinks können Sie feststellen, welcher fd in der Zieldatei geöffnet ist (z. B. readlink von/proc/rsync_pid/fd/5 -> target_file). Dies muss wahrscheinlich nur einmal gemacht werden, um die FD-Nummer zu erhalten [es sollte fest bleiben]

Wenn Sie die fd-Nummer kennen, schauen Sie sich/proc/rsync_pid/fdinfo/fd an. Es ist eine Textdatei, die aussieht wie:

 Pos: <Dateiposition> 
 Flags: blah_blah 
 Mnt_id: blah_blah

Das Überwachen des Werts "pos" kann hilfreich sein, da die "letzte Dateiposition" hilfreich sein kann. Wenn Sie mehrere Tests mit unterschiedlichen Größen und mem = -Optionen durchführen, verfolgt die letzte Dateiposition eine dieser [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 überprüfen, ob dies funktioniert. Möglicherweise können Sie ähnliche [aber schnellere] Ergebnisse erzielen, indem Sie "ssh server rsync file_a file_b" ausführen [Sie müssten zuerst eine 50-GB-Datei_a erstellen]. Eine einfache Möglichkeit, file_a zu erstellen, ist scp local_system: original_file server: file_a. Dies kann für sich selbst interessant sein (z. B. funktioniert dies, wenn rsync abstürzt? Wenn scp funktioniert, rsync jedoch fehlschlägt, zeigt dies auf rsync. Wenn scp fehlschlägt, weist dies darauf hin zu etwas anderem wie dem NIC Treiber). Durch Ausführen von ssh rsync wird auch das NIC aus der Gleichung entfernt, was hilfreich sein kann. Wenn dadurch das System abgespritzt wird, stimmt etwas nicht. Wenn dies erfolgreich ist, fügen Sie [wie bereits erwähnt] die Optionen nacheinander hinzu.

Ich hasse es, auf den Punkt einzugehen, aber das Hinzufügen von Swap über Swap-to-File kann das Absturzverhalten ändern/verzögern und als Diagnosetool nützlich sein. Wenn das Hinzufügen von beispielsweise 16 GB Swap den Absturz [gemessen an der Speichernutzung oder der Position der Zieldatei] von 32 GB auf 46 GB verzögert, sagt dies etwas aus.

Es ist möglicherweise kein bestimmter Prozess, sondern ein fehlerhafter Kerneltreiber, der Speicher kaut. Das interne vmalloc des Kernels weist Inhalte zu und kann ausgetauscht werden. IIRC ist nicht unter allen Umständen an die Adressierbarkeit gebunden.

Offensichtlich wird das OOM verwirrt/in Panik versetzt. Das heißt, es tötet rsync, sieht aber nicht, dass der Speicher rechtzeitig freigegeben wird, und sucht nach anderen Opfern. Einige von ihnen sind wahrscheinlich für den Systembetrieb von entscheidender Bedeutung.

abgesehen von malloc/mmap kann dies durch einen nicht geleerten FS Cache verursacht werden, der lange dauert (z. B. bei 30 GB nicht geleerten Daten, bei einer Festplattenrate von 300 MB/s kann das Leeren 100 Sekunden dauern ). Selbst bei dieser Rate kann OOM zu ungeduldig sein. Oder wenn OOM rsync beendet, wird die Spülung FS nicht schnell genug [oder überhaupt] gestartet. Oder FS Flush geschieht schnell genug, aber es gibt eine "faule" Freigabe der Seiten zurück in den freien Pool. Es gibt einige/proc-Optionen, die Sie festlegen können, um das Cache-Verhalten von FS zu steuern [Ich kann mich nicht erinnern, was sie sind].

Versuchen Sie, mit mem = 4G oder einer anderen kleinen Zahl zu booten. Dies kann den FS Cache verkürzen und seine Spülzeit verkürzen, um zu verhindern, dass OOM nach anderen zu tötenden Dingen sucht (z. B. wird die Spülzeit von 100 Sekunden auf <1 Sekunde reduziert). Möglicherweise wird auch ein OOM-Fehler entlarvt, der auf einem 32-Bit-System oder einem ähnlichen System keinen physischen RAM> 4 GB verarbeiten kann.

Ein wichtiger Punkt: Als Nicht-Root ausführen. Von Root-Benutzern wird niemals erwartet, dass sie Ressourcen kauen, daher erhalten sie mehr verzeihende Grenzen (z. B. 99% des Speichers gegenüber 95% bei Nicht-Root-Benutzern). Dies kann erklären, warum sich OOM in einem solchen Zustand befindet. Dies ergibt auch OOM et. al. Mehr Spielraum für die Wiederherstellung des Gedächtnisses.

4
Craig Estey

clamd? Es hört sich so an, als ob Sie ClamAV verwenden und das Scannen beim Zugriff aktiviert haben, wenn die Antiviren-Engine versucht, geöffnete Dateien auf Viren zu scannen , indem der gesamte Inhalt jeder geöffneten Datei in den Speicher geladen wird durch einen anderen Prozess .

Abhängig von Ihrer Sicherheitslage und der Notwendigkeit dieser Übertragung sollten Sie die Deaktivierung des ClamAV-On-Access-Scans während der Übertragung bewerten.

2
oo.