web-dev-qa-db-fra.com

La synchronisation peut-elle reprendre après avoir été interrompue?

J'ai utilisé rsync pour copier un grand nombre de fichiers, mais mon système d'exploitation (Ubuntu) a redémarré de façon inattendue.

Après le redémarrage, j'ai exécuté à nouveau rsync, mais à partir de la sortie sur le terminal, j'ai constaté que rsync copiait toujours ceux déjà copiés auparavant. Mais j'ai entendu dire que rsync est 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 rsync peut reprendre ce qui restait la dernière fois?

203
Tim

Tout d'abord, concernant la partie "CV" de votre question, --partial indique simplement à l'extrémité de réception de conserver les fichiers partiellement transférés si l'extrémité d'envoi disparaît comme s'ils avaient été complètement transférés.

Lors du transfert de fichiers, ils sont temporairement enregistrés en tant que fichiers cachés dans leurs dossiers cibles (par exemple .TheFileYouAreSending.lRWzDC), ou un dossier spécifiquement choisi si vous définissez --partial-dir commutateur. Lorsqu'un transfert échoue et --partial n'est pas défini, ce fichier caché restera dans le dossier cible sous ce nom cryptique, mais si --partial est 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 --append ou --append-verify.

Donc, --partial ne lui-même ne reprend pas un transfert échoué ou annulé. Pour le reprendre, vous devrez utiliser l'un des drapeaux susmentionnés lors de la prochaine exécution. Donc, si vous devez vous assurer que la cible ne contiendra jamais de fichiers qui semblent corrects mais qui sont en fait incomplets, vous ne devez pas utiliser --partial. Inversement, si vous voulez vous assurer de ne jamais laisser derrière vous les fichiers perdus qui sont cachés dans le répertoire cible et que vous savez que vous pourrez terminer le transfert plus tard, --partial est là pour vous aider.

En ce qui concerne le --append commutateur mentionné ci-dessus, il s'agit du commutateur de "reprise" réel, et vous pouvez l'utiliser que vous utilisiez également --partial. En fait, lorsque vous utilisez --append, aucun fichier temporaire n'est jamais créé. Les fichiers sont écrits directement sur leurs cibles. À cet égard, --append donne le même résultat que --partial en cas d'échec du transfert, mais sans créer ces fichiers temporaires masqués.

Donc, pour résumer, si vous déplacez des fichiers volumineux et que vous souhaitez que l'option reprenne une opération rsync annulée ou échouée à partir du moment précis où rsync s'est arrêté, vous devez utiliser le --append ou --append-verify active la prochaine tentative.

Comme @Alex le souligne ci-dessous, depuis la version 3.0.0 rsync a maintenant une nouvelle option, --append-verify, qui se comporte comme --append existait avant que ce commutateur n'existe. Vous voulez probablement toujours le comportement de --append-verify, vérifiez donc votre version avec rsync --version. Si vous utilisez un Mac et n'utilisez pas rsync de homebrew, vous aurez (au moins jusqu'à El Capitan inclus) une version plus ancienne et devrez utiliser --append plutôt que --append-verify. Pourquoi ils n'ont pas gardé le comportement sur --append et a plutôt nommé le nouveau venu --append-no-verify est un peu déroutant. D'une manière ou d'une autre, --append sur rsync avant la version 3 est identique à --append-verify sur les versions les plus récentes.

--append-verify n'est pas dangereux: il lira et comparera toujours les données aux deux extrémités et ne supposera pas seulement qu'elles sont égales. Il le fait en utilisant des sommes de contrôle, donc c'est facile sur le réseau, mais cela nécessite de lire la quantité partagée de données aux deux extrémités du câble avant de pouvoir réellement reprendre le transfert en l'ajoutant à la cible.

Deuxièmement, vous avez dit avoir "entendu 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 autre chose. Pour l'activer, vous ajoutez le -c, ou --checksum commutateur. Une fois ce commutateur utilisé, rsync examinera les fichiers qui existent aux deux extrémités du fil. Il le fait par morceaux, compare les sommes de contrôle aux deux extrémités, et si elles diffèrent, il transfère uniquement les différentes parties du fichier. Mais, comme le souligne @Jonathan ci-dessous, la comparaison n'est effectuée que lorsque les fichiers sont de la même taille aux deux extrémités - des tailles différentes entraîneront rsync à télécharger le fichier entier, écrasant la cible avec le même nom.

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

Il est à noter que si vous utilisez --checksum pour 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 pour simplement "déplacer des éléments de A vers B" et que vous souhaitez l'option d'annuler cette opération et de la reprendre plus tard, ne pas utilisez --checksum, mais faire utilisez --append-verify.

Si vous utilisez souvent rsync pour sauvegarder des éléments, utilisez --append-verify ne fera probablement pas grand chose pour vous, à moins que vous n'ayez l'habitude d'envoyer des fichiers volumineux dont la taille ne cesse d'augmenter 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 btrfs ou zfs, en ajoutant le --inplace switch vous aidera à réduire la taille des instantanés car les fichiers modifiés ne sont pas recréés, mais plutôt les blocs modifiés sont écrits directement sur les anciens. Ce commutateur est également utile si vous souhaitez éviter que rsync crée des copies de fichiers sur la cible lorsque seules des modifications mineures se sont produites.

Lors de l'utilisation de --append-verify, rsync se comportera comme il le fait toujours sur tous les fichiers de même taille. S'ils diffèrent dans la modification ou d'autres horodatages, il écrasera la cible avec la source sans examiner ces fichiers plus en détail. --checksum comparera le contenu (sommes de contrôle) de chaque paire de fichiers de nom et de taille identiques.

MISE À JOUR 2015-09-01 Modifié pour refléter les points soulevés par @Alex (merci!)

MISE À JOUR 2017-07-14 Modifié pour refléter les points soulevés par @Jonathan (merci!)

307

TL; DR:

Spécifiez simplement un répertoire partiel comme le recommandent les pages de manuel rsync:

--partial-dir=.rsync-partial

Explication plus longue:

Il existe en fait une fonctionnalité intégrée pour ce faire en utilisant le --partial-dir, qui présente plusieurs avantages par rapport à --partial et --append-verify/--append alternative.

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 d'un transfert. Comme mentionné, en utilisant --partial vous pouvez faire en sorte que rsync conserve le fichier incomplet comme s'il avait été transféré avec succès, afin qu'il soit possible de l'ajouter ultérieurement en utilisant le --append-verify/--append options. Cependant, il y a plusieurs raisons pour lesquelles ce n'est pas optimal.

  1. Vos fichiers de sauvegarde peuvent ne pas être complets et sans vérifier le fichier distant qui doit toujours être inchangé, il n'y a aucun moyen de le savoir.

  2. Si vous essayez d'utiliser --backup et --backup-dir, vous venez d'ajouter une nouvelle version de ce fichier qui ne s'est même jamais terminée auparavant dans l'historique de vos versions.

Cependant, si nous utilisons --partial-dir, rsync conservera le fichier partiel temporaire et reprendra le téléchargement en utilisant ce fichier partiel la prochaine fois que vous l'exécuterez, et nous ne souffrons pas des problèmes ci-dessus.

67
Alexander O'Mara

Vous voudrez peut-être ajouter le -P option à votre commande.

Depuis la page man:

--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 les mises à jour de progression, vous pouvez simplement utiliser --partial, c'est à dire.:

Sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2
39
N2O

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

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

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

2
lazysoundsystem

J'utilise ce script simple. N'hésitez pas à régler certains drapeaux et/ou à le 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
1
NeverEndingQueue

Je pense que vous appelez de force le rsync et donc toutes les données sont téléchargées lorsque vous vous en souvenez à nouveau. utilisation --progress option pour copier uniquement les fichiers qui ne sont pas copiés et --delete option pour supprimer tous les fichiers s'ils sont déjà copiés et maintenant il n'existe pas 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

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

1
Yadunandana