67 votes

Rsync a déclenché le killer OOM de Linux sur un seul fichier de 50 Go

J'ai un seul fichier de 50 Go sur le serveur_A et je le copie sur le serveur_B. J'exécute

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

Le serveur_B a 32 Go de RAM avec 2 Go de swap. Il est le plus souvent inactif et devrait avoir beaucoup de RAM libre. Il dispose de beaucoup d'espace disque. À environ 32 Go, le transfert est interrompu car le côté distant a fermé la connexion.

Le serveur_B a maintenant quitté le réseau. Nous demandons au centre de données de le redémarrer. Lorsque je regarde le journal du noyau avant qu'il ne plante, je vois qu'il utilisait 0 octet de swap et que la liste des processus utilisait très peu de mémoire (le processus rsync était répertorié comme utilisant 600 Ko de RAM), mais le oom_killer se déchaînait, et la dernière chose dans le journal est qu'il tue le processus de lecture du noyau de metalog.

Il s'agit du noyau 3.2.59, 32 bits (donc aucun processus ne peut mapper plus de 4 Go de toute façon).

C'est presque comme si Linux donnait plus de priorité à la mise en cache qu'aux démons qui tournent depuis longtemps. Qu'est-ce qui se passe ? Et comment puis-je empêcher que cela se reproduise ?

Voici la sortie de l'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

Voici la sortie 'top' après avoir répété ma commande rsync en tant qu'utilisateur non 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

Voici les paramètres 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

185voto

the-wabbit Points 40039

Lisons donc la sortie de l'oom-killer et voyons ce que l'on peut en tirer.

Lorsque l'on analyse les journaux de tueur à l'arrêt, il est important de regarder ce qui l'a déclenché. La première ligne de votre journal nous donne quelques indices :

[kernel] [1772321.850644] clamd a invoqué oom-killer : gfp_mask=0x84d0, order=0

order=0 nous indique la quantité de mémoire demandée. La gestion de la mémoire du noyau n'est capable de gérer que les numéros de page dans les puissances de 2, donc clamd a demandé 2 0 pages de mémoire ou 4KB.

Les deux bits les plus bas du GFP_MASK (get free page mask) constituent ce qu'on appelle le masque de zone indiquant à l'allocateur de quelle zone il doit obtenir la mémoire :

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

Zones de mémoire est un concept créé principalement pour des raisons de compatibilité. De manière simplifiée, il existe trois zones pour un noyau 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

Dans votre cas, le masque de zones est 0, ce qui signifie que clamd demande de la mémoire à partir de ZONE_NORMAL .

Les autres drapeaux se résolvent en

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

selon le Documentation sur Linux MM donc votre demande a les drapeaux pour GFP_ZERO , GFP_REPEAT , GFP_FS , GFP_IO y GFP_WAIT et ne sont donc pas particulièrement difficiles.

Alors, qu'est-ce qui se passe avec ZONE_NORMAL ? Certaines statistiques génériques peuvent être trouvées plus loin dans la sortie OOM :

[kernel] [1772321.850770] Normal libre:8056kB min:8048kB faible:10060kB high:12072kB active_anon:0kB inactive_anon:0kB active_file:248kB inactive_file:388kB unevictable:0kB isolated(anon) :0kB isolé(fichier):0kB présent:890008kB

On remarque ici que free est juste à 8K de min et bien en dessous low . Cela signifie que le gestionnaire de mémoire de votre hôte est quelque peu en détresse et que kswapd devrait déjà échanger des pages comme il le fait dans le fichier jaune du graphique ci-dessous : Linux memory manager graph

Des informations supplémentaires sur la fragmentation de la mémoire de la zone sont données ici :

[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

indiquant en gros que vous avez une seule page contiguë de 4 Mo, le reste étant fortement fragmenté en pages de 4 Ko principalement.

Récapitulons donc :

  • vous avez un processus userland ( clamd ) en récupérant la mémoire de ZONE_NORMAL alors que l'allocation de mémoire non privilégiée est généralement effectuée à partir de l'application ZONE_HIMEM
  • le gestionnaire de mémoire devrait, à ce stade, être en mesure de servir la page 4K demandée, bien que vous sembliez avoir une pression de mémoire significative dans ZONE_NORMAL
  • le système, en kswapd Les règles de l'UE, devrait J'ai vu une certaine activité de pagination au préalable, mais rien n'a été transféré, même sous la pression de la mémoire dans l'espace de travail. ZONE_NORMAL sans cause apparente
  • Aucune des réponses ci-dessus ne donne une raison précise pour laquelle oom-killer a été invoqué

Tout ceci semble plutôt étrange, mais est au moins à mettre en relation avec ce qui est décrit dans section 2.5 de l'excellent livre "Understanding the Linux Virtual Memory Manager" de John O'Gorman :

L'espace d'adresses utilisable par le noyau (ZONE_NORMAL) étant de taille limitée, le noyau prend en charge le concept de mémoire haute. [...] Pour accéder à une mémoire comprise entre 1 Go et 4 Go, le noyau mappe temporairement les pages de la haute mémoire vers la ZONE_NORMAL avec kmap(). [...]

Cela signifie que pour décrire 1GiB de mémoire, environ 11MiB de mémoire noyau sont nécessaires. Ainsi, avec 16GiB, 176MiB de mémoire sont consommés, mettant une pression significative sur ZONE_NORMAL. Cela ne semble pas trop grave jusqu'à ce que l'on prenne en compte les autres structures qui utilisent ZONE_NORMAL. Même de très petites structures telles que les entrées de table de pages (PTE) nécessitent environ 16MiB dans le pire des cas. Cela fait de 16GiB la limite pratique de la mémoire physique disponible pour Linux sur un x86. .

(c'est moi qui souligne)

Étant donné que la version 3.2 comporte de nombreuses avancées en matière de gestion de la mémoire par rapport à la version 2.6, il ne s'agit pas d'une réponse définitive, mais d'un indice très fort que je suivrais en premier. Réduisez la mémoire utilisable de l'hôte à un maximum de 16G en utilisant soit la fonction mem= paramètre du noyau ou en arrachant la moitié des DIMM du serveur.

En fin de compte, utiliser un noyau 64 bits .

Mec, on est en 2015.

4voto

Eugen Timm Points 121

Quelques éléments...

Ma règle d'or pour l'espace d'échange a été d'avoir au moins deux fois la quantité de RAM physique. Cela permet au démon page/swap de réorganiser la mémoire efficacement.

Le Serveur_B a 32GB de ram, essayez donc de le configurer pour 64GB de swap. IMO, les 2 Go d'espace swap dont dispose votre serveur sont chemin trop faible, surtout pour un serveur.

Si vous n'avez pas de partition supplémentaire que vous pouvez transformer en partition d'échange, vous pouvez tester cela en créant un fichier et en le montant comme une partition d'échange [cela sera lent]. Voir https://www.maketecheasier.com/swap-partitions-on-linux/

Puisque le serveur_B dispose de beaucoup d'espace disque, l'option --inplace n'est pas nécessaire, et peut être indésirable car elle peut être la cause de l'utilisation de 32 Go par rsync. L'option --inplace n'est vraiment utile que si vous manquez d'espace sur le système de fichiers [ce qui n'est pas le cas] ou si vous avez des exigences particulières en matière de performances.

Je pense que rsync voudra utiliser 50 Go de RAM [la taille du fichier] avec vos options actuelles. Normalement, rsync n'a pas besoin de tant de mémoire pour faire son travail, donc une ou plusieurs de vos options peuvent être le problème. Je transfère régulièrement des fichiers de 200 Go sans problème.

Faites quelques tests en n'utilisant aucune option. Faites-le avec des fichiers plus petits, disons 10 Go - cela devrait empêcher la panique du noyau, mais vous permettre de surveiller le comportement qui cause le problème. Surveillez l'utilisation de la mémoire par rsync.

Progressivement, ajoutez des options, une par une, pour voir quelle option [ou combinaison d'options] fait que rsync commence à consommer beaucoup de RAM (par exemple, pendant le transfert, l'utilisation de la RAM par rsync augmente proportionnellement à la quantité de données transférées, etc ).

Si vous avez vraiment besoin des options qui font que rsync conserve une image de fichier in-ram, vous aurez besoin de l'espace swap supplémentaire et la taille maximale de vos fichiers sera limitée en conséquence.

Quelques éléments supplémentaires [MISE À JOUR] :

(1) La trace de la pile du noyau montre que rsync présentait un défaut de page sur une zone mmap. Il est probablement en train de mettre en mémoire le fichier. mmap n'offre aucune garantie de vidage sur le disque. jusqu'à le fichier est fermé [contrairement à la lecture/écriture] qui va immédiatement dans le cache de bloc du FS [où il sera effacé].

(2) Le crash/panique du noyau se produit lorsque la taille du transfert atteint la taille de la RAM. Il est clair que rsync s'empare de cette quantité de mémoire non cache via malloc ou mmap. Une fois encore, avec les options que vous avez spécifiées, rsync allouera 50 Go de mémoire pour transférer un fichier de 50 Go.

(3) Transférez un fichier de 24 Go. Cela va probablement fonctionner. Ensuite, démarrez le noyau avec mem=16G et refaites le test du fichier de 24 Go. Il s'éteindra à 16 Go plutôt qu'à 32 Go. Cela confirmera que rsync a vraiment besoin de mémoire.

(4) Avant de dire que l'ajout de swap est ridicule, essayez d'en ajouter [via la méthode swap-to-file]. C'est beaucoup plus facile à faire et à tester que tous les arguments académiques sur le fait que le swap n'est pas nécessaire. Même si ce n'est pas la solution, vous pouvez apprendre quelque chose de cette expérience. Je parie que le test mem=16G réussira sans panique/crash.

(5) Il y a de fortes chances que rsync es frappant l'échange, mais cela se produit trop rapidement pour être vu avec top avant que OOM ne se déclenche et ne tue rsync. Le temps que rsync atteigne 32 Go, d'autres processus ont déjà été forcés de sortir en swap, en particulier s'ils sont inactifs. Peut-être qu'une combinaison de "free" et "top" vous donnera une meilleure image.

(6) Après que rsync soit tué, il faut du temps pour vider mmap dans le FS. Pas assez vite pour l'OOM et cela commence à tuer d'autres choses [certaines sont évidemment critiques]. C'est-à-dire que le flush mmap et OOM sont en compétition. Ou, OOM a un bug. Sinon, il n'y aurait pas de crash.

(7) D'après mon expérience, une fois qu'un système "frappe le mur de la mémoire", Linux met beaucoup de temps à se rétablir complètement. Et, parfois, il ne se rétablit jamais vraiment correctement et la seule façon d'y remédier est un redémarrage. Par exemple, j'ai 12 Go de RAM. Lorsque je lance un travail qui utilise 40 Go de mémoire [j'ai 120 Go de swap pour les gros travaux] et que je l'arrête, il faut environ 10 minutes pour que le système retrouve une réactivité normale [avec la lumière du disque allumée en permanence].

(8) Exécuter rsync sans options. Cela va fonctionner. Obtenez un exemple de base pour travailler. Puis rajoutez --inplace et testez à nouveau. Puis faites --append-verify à la place. Ensuite, essayez les deux. Trouvez quelle option permet à rsync de faire l'énorme mmap. Puis décidez si vous pouvez vivre sans. Si --inplace est le coupable, c'est une évidence, puisque vous avez beaucoup d'espace disque. Si vous devez avoir l'option, vous devrez obtenir l'espace d'échange pour accommoder le malloc/mmap que rsync fera.

DEUXIÈME MISE À JOUR :

Veuillez faire les tests mem= et smaller file à partir de ce qui précède.

Les questions centrales : Pourquoi rsync est tué par OOM ? Qui/qui ronge la mémoire ?

J'ai lu [mais oublié] que le système était en 32 bits. Donc, je suis d'accord, rsync n'est peut-être pas directement responsable (via malloc/mmap - la glibc implémente de gros mallocs via des mmaps anonymes/privés), et le défaut de page mmap de rsync déclenche OOM par coïncidence. Ensuite, OOM calcule la mémoire totale consommée par rsync directement et indirectement [cache FS, tampons de socket, etc. Donc, surveiller l'utilisation totale de la mémoire peut être utile. Je soupçonne qu'elle augmente au même rythme que le transfert de fichiers. Évidemment, ça ne devrait pas.

Vous pouvez surveiller certaines choses dans /proc ou /proc/rsync_pid via un script perl ou Python dans une boucle rapide [un script bash ne sera probablement pas assez rapide pour l'événement de fin du monde] qui peut surveiller tout ce qui suit plusieurs centaines de fois/sec. Vous pouvez exécuter ceci à une priorité plus élevée que rsync afin qu'il se maintienne en RAM et en cours d'exécution, de sorte que vous puissiez surveiller les choses juste avant le crash et, si possible, pendant l'OOM afin que vous puissiez voir pourquoi l'OOM devient fou :

/proc/meminfo -- pour obtenir des informations plus précises sur l'utilisation de l'espace de pagination au "point d'impact". En fait, il peut être plus utile d'obtenir le chiffre final de la quantité totale de RAM utilisée. Bien que top fournisse cela, il n'est peut-être pas assez rapide pour montrer l'état de l'univers juste avant le "big bang" (par exemple, les 10 dernières millisecondes).

Répertoire /proc/rsync_pid/fd. La lecture des liens symboliques vous permettra d'identifier quel fd est ouvert sur le fichier cible (par exemple, readlink de /proc/rsync_pid/fd/5 --> fichier_cible). Ceci n'a probablement besoin d'être fait qu'une seule fois pour obtenir le numéro de fd [il devrait rester fixe].

Connaissant le numéro de fd, regardez dans /proc/rsync_pid/fdinfo/fd. C'est un fichier texte qui ressemble à :

pos: <file\_position>
flags: blah\_blah
mnt\_id: blah\_blah

Surveiller la valeur "pos" peut être utile car la "dernière position du fichier" peut être utile. Si vous effectuez plusieurs tests avec des tailles et des options mem= différentes, la dernière position du fichier suit-elle l'une d'entre elles [et comment] ? Le suspect habituel : position du fichier == RAM disponible

Mais, le plus simple est de commencer par "rsync local_file server:remote_file" et de vérifier que cela fonctionne. Vous pouvez obtenir des résultats similaires [mais plus rapides] en faisant "ssh server rsync file_a file_b" [vous devrez d'abord créer un fichier_a de 50 Go]. Une façon simple de créer le fichier_a est scp local_system:original_file server:file_a et cela pourrait être intéressant en soi (par exemple, est-ce que cela fonctionne lorsque rsync se plante ? Si scp fonctionne, mais que rsync échoue, cela pointe vers rsync. Si scp échoue, cela indique quelque chose d'autre comme le pilote de la carte réseau). En effectuant le ssh rsync, vous éliminez également la carte réseau de l'équation, ce qui peut être utile. Si cela bloque le système, alors quelque chose ne va vraiment pas. Si cela réussit, [comme je l'ai mentionné] commencez à ajouter les options une par une.

Je n'aime pas insister sur ce point, mais l'ajout de swap via swap-to-file peut modifier/retarder le comportement du crash et peut être utile comme outil de diagnostic. Si le fait d'ajouter, disons 16 Go, de swap retarde le plantage [mesuré par l'utilisation de la mémoire ou la position du fichier cible] de 32 à 46 Go, cela signifie quelque chose.

Il ne s'agit peut-être pas d'un processus particulier, mais d'un pilote de noyau errant qui consomme de la mémoire. Le vmalloc interne du noyau alloue de la mémoire et peut être supprimé. IIRC, il n'est pas lié par l'adressabilité dans toutes les circonstances.

Il est clair que l'OOM est en train de s'embrouiller. C'est-à-dire qu'il tue rsync, mais ne voit pas la mémoire libérée en temps voulu et part à la recherche d'autres victimes. Certaines d'entre elles sont probablement critiques pour le fonctionnement du système.

malloc/mmap mis à part, cela pourrait être causé par un cache FS non nettoyé qui prend beaucoup de temps (par exemple, avec 30 Go de données non nettoyées, en supposant un taux de disque de 300 Mo/sec, cela pourrait prendre 100 secondes pour le nettoyer). Même à ce rythme, OOM peut être trop impatient. Ou bien, l'OOM qui tue rsync ne lance pas la purge du FS assez rapidement [ou pas du tout]. Ou encore, le flush FS se produit assez rapidement, mais il y a une libération "paresseuse" des pages vers le pool libre. Il y a quelques options /proc que vous pouvez définir pour contrôler le comportement du cache FS [je ne me souviens pas de ce qu'elles sont].

Essayez de démarrer avec mem=4G ou un autre petit nombre. Cela pourrait réduire le cache du FS et raccourcir son temps de vidange pour empêcher OOM de chercher d'autres choses à tuer (par exemple, le temps de vidange est réduit de 100 sec à < 1 sec). Cela pourrait aussi démasquer un bug d'OOM qui ne peut pas gérer une RAM physique > 4GB sur un système 32 bit ou autre.

Aussi, un point important : Exécuter en tant que non-root. Les utilisateurs root ne sont pas censés consommer des ressources, ils bénéficient donc de limites plus indulgentes (par exemple, 99% de la mémoire contre 95% pour les utilisateurs non-root). Cela peut expliquer pourquoi OOM est dans un tel état. De plus, cela donne à OOM et al. plus de marge de manœuvre pour faire son travail de récupération de la mémoire.

2voto

Rémi Points 3996

Clamd ? Il semble que vous utilisiez ClamAV et que l'analyse à l'accès soit activée, le moteur antivirus tentant de rechercher les virus dans les fichiers ouverts, en chargeant en mémoire, l'intégralité du contenu de tout fichier ouvert par un autre processus .

En fonction de votre position de sécurité et de la nécessité de ce transfert, vous devriez envisager de désactiver l'analyse à l'accès de ClamAV pendant que vous effectuez le transfert.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X