web-dev-qa-db-fra.com

Reprise de rsync partial (-P/- partial) sur un transfert interrompu

J'essaie de sauvegarder mon serveur de fichiers sur un serveur de fichiers à l'aide de rsync. Rsync ne reprend pas correctement lorsqu'un transfert est interrompu. J'ai utilisé l'option partielle mais rsync ne trouve pas le fichier qu'il a déjà démarré car il le renomme en fichier temporaire et, une fois repris, il crée un nouveau fichier et commence à partir du début.

Voici ma commande:

rsync -avztP -e "ssh -p 2222" /volume1/ myaccont@backup-server-1:/home/myaccount/backup/ --exclude "@spool" --exclude "@tmp"

Lorsque cette commande est exécutée, un fichier de sauvegarde nommé OldDisk.dmg de ma machine locale est créé sur la machine distante sous la forme de .OldDisk.dmg.SjDndj23 .

Maintenant, lorsque la connexion Internet est interrompue et que je dois reprendre le transfert, je dois trouver où rsync s'est arrêté en recherchant le fichier temporaire tel que .OldDisk.dmg.SjDndj23 et le renommer en OldDisk.dmg afin qu’il voie qu’il existe déjà un fichier qu’il peut reprendre.

Comment puis-je résoudre ce problème afin de ne pas intervenir manuellement à chaque fois?

21
Glitches

TL; DR : utilisez --timeout=X (X en secondes) pour modifier le délai d'attente du serveur rsync par défaut, et non --inplace.

Le problème est que les processus du serveur rsync (il y en a deux, voir rsync --server ... dans ps sortie sur le récepteur) continuent de s'exécuter pour attendre que le client rsync envoie des données.

Si les processus du serveur rsync ne reçoivent pas les données pendant un temps suffisant, ils expireront, se termineront automatiquement et seront nettoyés en déplaçant le fichier temporaire vers son nom "propre" (par exemple, aucun suffixe temporaire). Vous pourrez ensuite reprendre.

Si vous ne souhaitez pas attendre le délai d'attente par défaut prolongé pour que le serveur rsync se termine automatiquement, puis, lorsque votre connexion Internet est rétablie, connectez-vous au serveur et nettoyez les processus du serveur rsync manuellement. Cependant, vous devez terminer poliment rsync - sinon, le fichier partiel ne sera pas déplacé; mais plutôt, supprimez-le (et donc il n'y a aucun fichier à reprendre). Pour demander poliment à rsync de terminer, ne pas SIGKILL (par exemple, -9), mais SIGTERM (par exemple, pkill -TERM -x rsync - uniquement à titre d'exemple, veillez à ne faire correspondre que les processus rsync concernés avec votre client).

Heureusement, il existe un moyen plus simple: utilisez l'option --timeout=X (X en secondes); il est également transmis aux processus du serveur rsync.

Par exemple, si vous spécifiez rsync ... --timeout=15 ..., les processus rsync client et serveur se fermeront proprement s’ils n’envoient/ne reçoivent pas de données dans les 15 secondes. Sur le serveur, cela signifie déplacer le fichier temporaire en position, prêt à reprendre.

Je ne suis pas sûr du délai d'expiration par défaut des différents processus rsync qui essaieront d'envoyer/recevoir des données avant leur mort (cela peut varier en fonction du système d'exploitation). Lors de mes tests, les processus rsync du serveur continuent à fonctionner plus longtemps que le client local. Sur une connexion réseau "morte", le client se termine avec un tuyau cassé (par exemple, aucune prise réseau) après environ 30 secondes; vous pouvez expérimenter ou revoir le code source. Cela signifie que vous pouvez essayer de "sortir" de la mauvaise connexion Internet pendant 15 à 20 secondes.

Si vous ne nettoyez pas les processus rsync du serveur (ou attendez qu'ils meurent), mais que vous lanciez immédiatement un autre processus client rsync, deux processus serveur supplémentaires seront lancés (pour l'autre extrémité de votre nouveau processus client). Plus précisément, le nouveau client rsync ne sera pas réutilisé/reconnecté aux processus de serveur rsync existants. Ainsi, vous aurez deux fichiers temporaires (et quatre processus de serveur rsync). Cependant, seul le deuxième fichier temporaire le plus récent contient de nouvelles données en cours d'écriture (reçues de votre nouveau processus client rsync).

Fait intéressant, si vous nettoyez ensuite tous les processus du serveur rsync (par exemple, arrêtez votre client qui arrêtera les nouveaux serveurs rsync, puis SIGTERM les anciens serveurs rsync, il semblerait que tous les fichiers partiels soient fusionnés (assemblés)). imaginez une copie partielle longue qui meurt (et vous pensez que vous avez "perdu" toutes les données copiées), et une courte exécution rsync relancée (oups!) .. vous pouvez arrêter la seconde client, SIGTERM les premiers serveurs, il fusionnera les données et vous pourrez les reprendre.

Enfin, quelques brèves remarques:

  • N'utilisez pas --inplace pour résoudre ce problème. Vous aurez sans aucun doute d'autres problèmes à la suite, man rsync pour les détails.
  • C'est trivial, mais -t dans vos options rsync est redondant, il est impliqué par -a.
  • Une image disque déjà compressée envoyée sur rsync sans compression peut entraîner un temps de transfert plus court (en évitant la double compression). Cependant, je ne suis pas sûr des techniques de compression dans les deux cas. Je le testerais.
  • Autant que je sache --checksum/-c, cela ne vous aidera pas dans ce cas. Cela affecte la manière dont rsync décide si doit transférer un fichier. Cependant, une fois que le premier rsync est terminé, vous pouvez exécuter un deuxième rsync avec -c pour insister sur les sommes de contrôle, afin d'éviter le cas étrange où la taille du fichier et l'heure de modification sont identiques. des deux côtés, mais de mauvaises données ont été écrites.
25
Richard Michael

Désolé, mais les autres réponses ici sont trop compliquées: -7 . Une réponse plus simple fonctionne pour moi: (en utilisant rsync sur -e ssh)

# optionally move rsync temp file, then resume using rsync 
dst$ mv .<filename>.6FuChr <filename>
src$ rsync -avhzP --bwlimit=1000 -e ssh <fromfiles> <user@somewhere>:<destdir>/

Fonctionne également lors de la reprise d'un scp qui a été interrompu. 

Rsync crée un fichier temporaire ... Le fichier temporaire grossit rapidement pour atteindre la taille du fichier partiellement transféré. Le transfert reprend. 

Scp écrit dans le fichier de destination finale. Si le transfert est interrompu, il s’agit d’un fichier tronqué.

Explication des arguments:

-avhz .. h = humanoïde, v = verbose, a = archive, z = compression .. archive lui permet de conserver les valeurs time_t afin que même si les horloges sont épuisées, rsync connaît la date vraie de chaque fichier

-P est l'abréviation de --partial --progress. --partial dit à rsync de conserver les fichiers partiellement transférés (et lors de la reprise, rsync utilisera toujours les fichiers partiellement transférés après le checksum en toute sécurité)

A partir des pages de manuel: http://ss64.com/bash/rsync_options.html

--partial
By default, rsync will delete any partially transferred file if the transfer
is interrupted. In some circumstances it is more desirable to keep partially
transferred files. Using the --partial option tells rsync to keep the partial
file which should make a subsequent transfer of the rest of the file much faster.

--progress
This option tells rsync to print information showing the progress of the transfer.
This gives a bored user something to watch.
This option is normally combined with -v. Using this option without the -v option
will produce weird results on your display.

-P
The -P option is equivalent to --partial --progress.
I found myself typing that combination quite often so I created an option to make
it easier.

REMARQUE: pour une connexion qui est interrompue plusieurs fois: Si vous avez besoin de reprendre après rsync (après l’interruption de la connexion), il est préférable de renommer le fichier temporaire sur la destination. scp crée un fichier de destination portant le même nom que le fichier final. Si scp est interrompu, ce fichier est une version tronquée du fichier. Un rsync (-avzhP) reprendra à partir de ce fichier mais commencera à écrire dans un nom de fichier temporaire tel que ..Yhg7al. 

Procédure à suivre avec scp:

scp; *interrupt*; rsync; [REPEAT_as_needed: *interrupt*; mv .destfile.tmpzhX destfile; rsync;]. 

Procédure à suivre pour démarrer avec rsync: 

rsync; [REPEAT_as_needed: *interrupt*; mv .destfile.tmpzhX destfile; rsync;].
7
gaoithe

J'ai trouvé que l'ajout de --inplace le corrige. Je ne sais pas comment - partial est censé fonctionner sans, mais il a repris mes transferts. Mes fichiers sont toujours assez volumineux et je me demande si je vais me retrouver avec des fichiers corrompus si un transfert commence et, quelques heures plus tard, un autre transfert commence, mais voit un fichier incomplet et ne sait pas qu'il est en cours de téléchargement. il. Quelqu'un sait? Peut-être que certains scripts bash enregistrent l'id du processus actuel sans démarrer un autre transfert?

2
Glitches

si vous avez peur des fichiers corrompus après la reprise, vous pouvez ajouter --checksum pour le forcer à effectuer des vérifications sur tout le fichier à chaque fois. En effet, cela vous coûtera quelques cycles d’E/S de disque et de processeur, mais seulement une légère surcharge du réseau.

0
mogul