Rsync peut-il reprendre après avoir été interrompu?

188

J'avais l'habitude rsyncde copier un grand nombre de fichiers, mais mon système d'exploitation (Ubuntu) a redémarré de manière inattendue.

Après le redémarrage, j’ai de rsyncnouveau exécuté , mais à la sortie du terminal, j’ai trouvé que rsyncceux-ci étaient toujours copiés. Mais j'ai entendu dire qu'il rsyncest capable de trouver des différences entre la source et la destination, et donc de simplement copier les différences. Je me demande donc dans mon cas si rsyncpeut reprendre ce qui restait la dernière fois?

Tim
la source
Oui, rsync ne recopiera pas les fichiers déjà copiés. Il existe quelques cas extrêmes où sa détection peut échouer. At-il copié tous les fichiers déjà copiés? Quelles options avez-vous utilisées? Quels étaient les systèmes de fichiers source et cible? Si vous exécutez à nouveau rsync après avoir tout copié, est-ce qu'il copie à nouveau?
Gilles
@ Gilles: Merci! (1) Je pense avoir vu rsync copier à nouveau les mêmes fichiers à partir de sa sortie sur le terminal. (2) Les options sont les mêmes que dans mon autre message, c.-à-d sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) La source et la cible sont à la fois NTFS, la source d'achat est un disque dur externe et la cible est un disque dur interne. (3) Il est en cours d'exécution et n'a pas encore fini.
Tim
Il y a aussi le drapeau --partial pour reprendre les fichiers partiellement transférés (utile pour les gros fichiers)
jwbensley
3
@ Tim Par défaut, il y a au moins un décalage d'horloge et des différences de résolution temporelle (un problème courant avec les systèmes de fichiers FAT qui stockent les temps par incréments de 2 secondes, l' --modify-windowoption aide à résoudre ce problème ).
Gilles
1
si vous n'aviez pas / ou /. à la fin de l'argument du chemin source du fichier, il fera une copie supplémentaire dans un sous-répertoire qui porte le même nom que le répertoire source
Skaperen

Réponses:

285

Tout d’abord, en ce qui concerne la partie "CV" de votre question, --partialindique simplement à la partie destinataire de conserver les fichiers partiellement transférés si la partie envoyée disparaît comme si ceux-ci étaient complètement transférés.

Lors du transfert de fichiers, ils sont temporairement enregistrés en tant que fichiers masqués dans leurs dossiers cibles (par exemple .TheFileYouAreSending.lRWzDC) ou dans un dossier spécifiquement choisi si vous définissez le --partial-dircommutateur. Lorsqu'un transfert échoue et --partialn'est pas défini, ce fichier caché restera dans le dossier cible sous ce nom cryptique, mais s'il --partialest défini, le fichier sera renommé en nom de fichier cible réel (dans ce cas, TheFileYouAreSending), même si le fichier n'est pas complet. Le fait est que vous pouvez terminer le transfert ultérieurement en exécutant à nouveau rsync avec --appendou --append-verify.

Donc, --partialne reprend pas lui-même un transfert échoué ou annulé. Pour le reprendre, vous devrez utiliser l'un des indicateurs susmentionnés lors de la prochaine exécution. Donc, si vous devez vous assurer que la cible ne contiendra jamais de fichiers qui semblent être corrects mais qui sont en réalité incomplets, vous ne devriez pas les utiliser --partial. Inversement, si vous voulez vous assurer de ne jamais laisser de fichiers égarés perdus et cachés dans le répertoire cible, et si vous savez que vous pourrez terminer le transfert ultérieurement, --partialvous pouvez vous aider.

En ce qui concerne le --appendcommutateur mentionné ci-dessus, il s'agit du commutateur "resume", que vous pouvez utiliser, que vous l'utilisiez ou non --partial. En fait, lorsque vous utilisez --append, aucun fichier temporaire n'est créé. Les fichiers sont écrits directement dans leurs cibles. À cet égard, --appenddonne le même résultat que --partialsur un transfert ayant échoué, mais sans créer ces fichiers temporaires masqués.

Donc, pour résumer, si vous déplacez des fichiers volumineux et que vous souhaitez avoir la possibilité de reprendre une opération rsync annulée ou ayant échoué à partir du point exact qui rsyncs'est arrêté, vous devez utiliser la touche --appendou pour --append-verifyactiver la prochaine tentative.

Comme @Alex le souligne ci-dessous, depuis la version 3.0.0 a rsyncmaintenant une nouvelle option --append-verify, qui se comporte comme --appendauparavant. Vous voulez probablement toujours le comportement de --append-verify, alors vérifiez votre version avec rsync --version. Si vous êtes sur un Mac et ne pas utiliser rsyncde homebrew, vous (au moins jusqu'au El Capitan) une version plus ancienne et la nécessité d'utiliser --appendplutôt que --append-verify. Pourquoi ils n'ont pas gardé ce comportement --appendet nommé le nouveau venu --append-no-verifyest un peu déroutant. De toute façon, --appendsur rsyncavant la version 3 est le même que --append-verifysur les versions plus récentes.

--append-verifyn'est pas dangereux: il lira et comparera toujours les données aux deux extrémités et ne supposera pas qu'elles sont égales. Pour ce faire, elle utilise des sommes de contrôle, ce qui facilite les choses sur le réseau, mais nécessite la lecture de la quantité de données partagée aux deux extrémités du câble avant de pouvoir reprendre le transfert en ajoutant à la cible.

Deuxièmement, vous avez dit "avoir entendu dire que rsync était capable de trouver des différences entre la source et la destination, et donc de simplement copier les différences".

C'est exact, et cela s'appelle le transfert delta, mais c'est une chose différente. Pour l'activer, vous ajoutez le -c, ou --checksumbasculez. Une fois ce commutateur utilisé, rsync examinera les fichiers existant aux deux extrémités du fil. Cela se fait par morceaux, compare les sommes de contrôle des deux côtés et, si elles diffèrent, ne transfère que les parties différentes du fichier. Mais, comme @Jonathan le souligne ci-dessous, la comparaison n'est effectuée que lorsque les fichiers ont la même taille aux deux extrémités - des tailles différentes obligeront rsync à télécharger l'intégralité du fichier, en remplaçant la cible par le même nom.

Cela nécessite un peu de calcul aux deux extrémités, mais peut s'avérer extrêmement efficace pour réduire la charge du réseau si, par exemple, vous sauvegardez fréquemment des fichiers très volumineux, des fichiers de taille fixe contenant souvent des modifications mineures. Les exemples qui me viennent à l’esprit sont les fichiers d’image de disque dur virtuel utilisés dans des machines virtuelles ou des cibles iSCSI.

Il est à noter que si vous utilisez --checksumpour transférer un lot de fichiers complètement nouveaux sur le système cible, rsync calculera toujours leurs sommes de contrôle sur le système source avant de les transférer. Pourquoi je ne sais pas :)

Donc, en bref:

Si vous utilisez souvent rsync juste « passer des choses de A à B » et que vous voulez la possibilité d'annuler cette opération et reprendre plus tard, ne pas utiliser --checksum, mais n'utiliser .--append-verify

Si vous utilisez souvent rsync pour sauvegarder des --append-verifyfichiers , leur utilisation ne vous aidera probablement pas beaucoup, sauf si vous avez l'habitude d'envoyer de gros fichiers dont la taille ne cesse de croître, mais qui sont rarement modifiés une fois écrits. En prime, si vous sauvegardez sur un stockage prenant en charge les instantanés tels que btrfsou zfs, l'ajout du --inplacecommutateur vous aidera à réduire la taille des instantanés, car les fichiers modifiés ne sont pas recréés, mais les blocs modifiés sont écrits directement par-dessus les anciens. Ce commutateur est également utile si vous souhaitez éviter que rsync ne crée des copies de fichiers sur la cible lorsque des modifications mineures ont eu lieu.

Lors de l'utilisation --append-verify, rsync se comportera comme il le fait toujours pour tous les fichiers de même taille. S'ils diffèrent par la modification ou d'autres horodatages, la cible sera remplacée par la source sans examiner ces fichiers plus à fond. --checksumcomparera le contenu (sommes de contrôle) de chaque paire de fichiers de nom et de taille identiques.

MIS À JOUR 2015-09-01 Modifié pour refléter les remarques de @Alex (merci!)

MIS À JOUR 2017-07-14 Modifié pour refléter les remarques de @Jonathan (merci!)

DanielSmedegaardBuus
la source
4
Cela dit --partialest suffisant.
Cees Timmerman
2
@CMCDragonkai En fait, consultez la réponse d'Alexander ci-dessous à propos de --partial-dir- cela semble être la solution idéale pour cela. J'ai peut-être complètement manqué quelque chose;)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Je l'ai testé moi-même sur une connexion lente, et c'est ce que je vois uniquement --partial : rsync copie le fichier dans le nom temporaire, la connexion est interrompue, le serveur distant rsync finit par déplacer le fichier vers le nom habituel et se ferme, puis sur Pour relancer avec --partialet sans --append , le nouveau fichier temporaire est initialisé avec une copie du fichier distant partiellement transféré, puis la copie continue à partir de l'endroit où la connexion est morte. (Ubuntu 14.04 / rsync 3.1)
Izkata
4
Quel est votre niveau de confiance dans le comportement décrit --checksum? Selon le, mancela a plus à voir avec le choix des fichiers à marquer pour le transfert qu'avec le transfert delta (qui, vraisemblablement, est rsyncle comportement par défaut).
Jonathan Y.
56

TL; DR:

Spécifiez simplement un répertoire partiel comme le recommande la page de manuel rsync:

--partial-dir=.rsync-partial

Explication plus longue:

Il existe en fait une fonctionnalité intégrée permettant d'utiliser cette --partial-diroption, ce qui présente plusieurs avantages par rapport à --partialet --append-verify/ --appendalternative.

Extrait des pages de manuel de rsync:

--partial-dir=DIR
      A  better way to keep partial files than the --partial option is
      to specify a DIR that will be used  to  hold  the  partial  data
      (instead  of  writing  it  out to the destination file).  On the
      next transfer, rsync will use a file found in this dir  as  data
      to  speed  up  the resumption of the transfer and then delete it
      after it has served its purpose.

      Note that if --whole-file is specified (or  implied),  any  par-
      tial-dir  file  that  is  found for a file that is being updated
      will simply be removed (since rsync  is  sending  files  without
      using rsync's delta-transfer algorithm).

      Rsync will create the DIR if it is missing (just the last dir --
      not the whole path).  This makes it easy to use a relative  path
      (such  as  "--partial-dir=.rsync-partial")  to have rsync create
      the partial-directory in the destination file's  directory  when
      needed,  and  then  remove  it  again  when  the partial file is
      deleted.

      If the partial-dir value is not an absolute path, rsync will add
      an  exclude rule at the end of all your existing excludes.  This
      will prevent the sending of any partial-dir files that may exist
      on the sending side, and will also prevent the untimely deletion
      of partial-dir items on the receiving  side.   An  example:  the
      above  --partial-dir  option would add the equivalent of "-f '-p
      .rsync-partial/'" at the end of any other filter rules.

Par défaut, rsync utilise un nom de fichier temporaire aléatoire, qui est supprimé en cas d'échec du transfert. Comme mentionné, utiliser --partialrsync vous permet de conserver le fichier incomplet comme s'il avait été transféré avec succès , de sorte qu'il soit possible de l'ajouter ultérieurement à l'aide des options --append-verify/ --append. Cependant, il y a plusieurs raisons pour lesquelles cela n'est pas optimal.

  1. Vos fichiers de sauvegarde peuvent ne pas être complets et, sans vérification du fichier distant qui doit rester inchangé, il n’ya aucun moyen de le savoir.

  2. Si vous essayez d'utiliser --backupet --backup-dir, vous venez d'ajouter une nouvelle version de ce fichier qui n'a même jamais été copiée auparavant dans l'historique de vos versions.

Cependant, si nous l'utilisons --partial-dir, rsync conservera le fichier partiel temporaire et reprendra le téléchargement à l'aide de ce fichier partiel lors de sa prochaine exécution, sans que nous ayons à résoudre les problèmes ci-dessus.

Alexander O'Mara
la source
38

Vous voudrez peut-être ajouter l' -Poption à votre commande.

De la manpage:

--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.

  -P     The -P option is equivalent to --partial --progress.   Its  pur-
         pose  is to make it much easier to specify these two options for
         a long transfer that may be interrupted.

Donc au lieu de:

sudo rsync -azvv /home/path/folder1/ /home/path/folder2

Faire:

sudo rsync -azvvP /home/path/folder1/ /home/path/folder2

Bien sûr, si vous ne voulez pas que les mises à jour de progression, vous pouvez simplement utiliser --partial, à savoir:

sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2
N2O
la source
@ Flimm pas tout à fait correct. S'il y a une interruption (côté réseau ou côté réception), en utilisant --partial, le fichier partiel est conservé ET il est utilisé lors de la reprise de rsync. Extrait de la page de manuel: "L'utilisation de l'option --partial indique à rsync de conserver le fichier partiel, ce qui <b> devrait <b> permettre un transfert ultérieur du reste du fichier beaucoup plus rapide </ b>."
Gaoithe
2
@ Flimm et @gaoithe, ma réponse n'était pas tout à fait exacte, et certainement pas à jour. Je l'ai mis à jour pour refléter la version 3 + de rsync. Il est important de souligner, cependant, que --partialcela ne reprend pas en soi un transfert ayant échoué. Voir ma réponse pour plus de détails :)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Je l'ai essayé et -Pc'est suffisant dans mon cas. Versions: le client a 3.1.0 et le serveur a 3.1.1. J'ai interrompu le transfert d'un seul fichier volumineux avec ctrl-c. Je suppose que je manque quelque chose.
Guettli
Pourquoi vv? c'est à dire vutilisé 2 fois?
mrgloom
Où rsync sauve-t-il une partie du fichier -azvvP?
mrgloom
1

Je pense que vous appelez de force le rsyncet que, par conséquent, toutes les données sont téléchargées lorsque vous vous en souvenez. utilisez l' --progressoption pour copier uniquement les fichiers qui ne sont pas copiés et l' --deleteoption pour supprimer tous les fichiers déjà copiés et qui n'existent plus dans le dossier source ...

rsync -avz --progress --delete -e  /home/path/folder1/ /home/path/folder2

Si vous utilisez ssh pour vous connecter à un autre système et copier les fichiers,

rsync -avz --progress --delete -e "ssh -o UserKnownHostsFile=/dev/null -o \
StrictHostKeyChecking=no" /home/path/folder1/ /home/path/folder2

laissez-moi savoir s'il y a une erreur dans ma compréhension de ce concept ...

Yadunandana
la source
1
Pouvez-vous éditer votre réponse et expliquer ce que fait votre appel spécial ssh et pourquoi vous conseillez de le faire?
Fabien
2
@Fabien Il dit à rsync de définir deux options ssh (rsync utilise ssh pour se connecter). La seconde demande à ssh de ne pas demander de confirmation si l'hôte auquel il se connecte n'est pas déjà connu (en existant dans le fichier "hôtes connus"). Le premier indique à ssh de ne pas utiliser le fichier hosts connu par défaut (qui serait ~ / .ssh / known_hosts). Il utilise / dev / null à la place, ce qui est bien sûr toujours vide, et comme ssh ne trouverait pas l'hôte à l'intérieur, il devrait normalement demander confirmation, d'où l'option deux. Lors de la connexion, ssh écrit l’hôte désormais connu sur / dev / null, l’oubliant immédiatement :)
DanielSmedegaardBuus
1
... mais vous vous demandiez probablement quel effet, le cas échéant, il a sur l'opération rsync elle-même. La réponse est non. Cela sert uniquement à ne pas ajouter l'hôte auquel vous vous connectez à votre fichier d'hôtes connus SSH. Peut-être qu'il est un administrateur système qui se connecte souvent à un grand nombre de nouveaux serveurs, de systèmes temporaires ou autres. Je ne sais pas :)
DanielSmedegaardBuus
4
"utilise --progress option pour copier uniquement les fichiers qui ne sont pas copiés" Quoi?
moi
1
Il y a quelques erreurs ici; l'un est très grave: --deletesupprimera les fichiers de la destination qui n'existent pas dans la source. Le moins grave est que --progresscela ne modifie pas la façon dont les choses sont copiées; il vous donne simplement un rapport d’avancement sur chaque fichier lorsqu’il est copié. (J'ai corrigé l'erreur grave; l'ai remplacée par --remove-source-files.)
Paul d'Aoust
1

J'utilise ce script simple. N'hésitez pas à ajuster certains drapeaux et / ou à les paramétrer.

#!/bin/bash

while [ 1 ]
do
    rsync -avz --partial [source] [dest]:
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "Rsync failure. Backing off and retrying..."
        sleep 180
    fi
done
NeverEndingQueue
la source
1

Arriver en retard à ceci, mais j'avais la même question et j'ai trouvé une réponse différente.

Le --partialdrapeau ("conserver les fichiers partiellement transférés" rsync -h) est utile pour les fichiers volumineux, tout comme --append("ajouter des données à des fichiers plus courts"), mais la question concerne un grand nombre de fichiers.

Pour éviter les fichiers déjà copiés, utilisez -u(ou --update: "ignore les fichiers les plus récents sur le récepteur").

lazysoundsystem
la source