Rsync può riprendere dopo essere stato interrotto?


188

Ho usato rsyncper copiare un gran numero di file, ma il mio sistema operativo (Ubuntu) riavviato in modo imprevisto.

Dopo il riavvio, ho eseguito di rsyncnuovo, ma dall'output sul terminale, ho scoperto che rsyncancora copiato quelli già copiati prima. Ma ho sentito che rsyncè in grado di trovare le differenze tra origine e destinazione e quindi di copiarle. Quindi mi chiedo nel mio caso se rsyncposso riprendere ciò che è rimasto l'ultima volta?


Sì, rsync non copia nuovamente i file già copiati. Ci sono alcuni casi limite in cui il suo rilevamento può fallire. Ha copiato tutti i file già copiati? Quali opzioni hai usato? Quali erano i filesystem di origine e di destinazione? Se esegui di nuovo rsync dopo aver copiato tutto, lo copia di nuovo?
Gilles,

@Gilles: grazie! (1) Penso di aver visto rsync copiare nuovamente gli stessi file dal suo output sul terminale. (2) Le opzioni sono le stesse del mio altro post, ad es sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) La sorgente e la destinazione sono entrambe NTFS, la fonte di acquisto è un HDD esterno e la destinazione è un HDD interno. (3) Ora è in esecuzione e non è ancora terminato.
Tim

C'è anche il flag --partial per riprendere i file parzialmente trasferiti (utile per file di grandi dimensioni)
jwbensley

3
@Tim Dalla parte superiore della mia testa, c'è almeno un disallineamento dell'orologio e differenze nella risoluzione temporale (un problema comune con i filesystem FAT che memorizzano i tempi con incrementi di 2 secondi, l' --modify-windowopzione aiuta in questo).
Gilles,

1
se non avevi / o /. alla fine dell'argomento del percorso sorgente del file, verrà
eseguita

Risposte:


285

Prima di tutto, per quanto riguarda la parte "riprendi" della tua domanda, --partialbasta dire all'estremità ricevente di conservare i file parzialmente trasferiti se l'estremità di invio scompare come se fossero completamente trasferiti.

Durante il trasferimento di file, vengono temporaneamente salvati come file nascosti nelle loro cartelle di destinazione (ad es. .TheFileYouAreSending.lRWzDC) O in una cartella scelta in modo specifico se si imposta l' --partial-diropzione. Quando un trasferimento fallisce e --partialnon è impostato, questo file nascosto rimarrà nella cartella di destinazione con questo nome criptico, ma se --partialimpostato, il file verrà rinominato con il nome del file di destinazione effettivo (in questo caso TheFileYouAreSending), anche se il file non è completo. Il punto è che in seguito è possibile completare il trasferimento eseguendo di nuovo rsync con --appendo --append-verify.

Quindi, --partialnon significa in sé riprendere un trasferimento non riuscito o annullato. Per riprenderlo, dovrai usare uno dei suddetti flag nella prossima corsa. Quindi, se devi assicurarti che la destinazione non contenga mai file che sembrano andare bene ma che in realtà sono incompleti, non dovresti usare --partial. Al contrario, se vuoi assicurarti di non lasciarti mai alle spalle file randagi non riusciti che sono nascosti nella directory di destinazione e sai che sarai in grado di completare il trasferimento in un secondo momento, --partialè lì per aiutarti.

Per quanto riguarda l' --appendopzione sopra menzionata, questa è la vera opzione "riprendi" e puoi usarla anche se stai usando --partial. In realtà, quando si utilizza --append, non vengono mai creati file temporanei. I file vengono scritti direttamente nei loro target. A questo proposito, --appendfornisce lo stesso risultato di --partialun trasferimento non riuscito, ma senza creare quei file temporanei nascosti.

Quindi, per riassumere, se stai spostando file di grandi dimensioni e desideri che l'opzione riprenda un'operazione rsync annullata o non riuscita dal punto esatto in cui è stata rsyncinterrotta, devi utilizzare --appendo --append-verifypassare al tentativo successivo.

Come sottolineato da @Alex di seguito, poiché la versione 3.0.0 rsyncora ha una nuova opzione --append-verify, che si comporta come --appendprima che esistesse quel passaggio. Probabilmente vuoi sempre il comportamento di --append-verify, quindi controlla la tua versione con rsync --version. Se sei su un Mac e non lo usi rsyncda homebrew, avrai (almeno fino a El Capitan incluso) una versione precedente e dovrai usare --appendpiuttosto che --append-verify. Il motivo per cui non hanno mantenuto il comportamento --appende invece hanno nominato il nuovo arrivato --append-no-verifyè un po 'sconcertante. In entrambi i casi, --appendsulla rsyncprima versione 3 è lo stesso che --append-verifysulle versioni più recenti.

--append-verifynon è pericoloso: leggerà e confronterà sempre i dati su entrambe le estremità e non solo supporrà che siano uguali. Lo fa usando checksum, quindi è facile sulla rete, ma richiede la lettura della quantità condivisa di dati su entrambe le estremità del filo prima che possa effettivamente riprendere il trasferimento aggiungendo alla destinazione.

In secondo luogo, hai detto che "hai sentito che rsync è in grado di trovare le differenze tra origine e destinazione e quindi di copiarle".

È corretto e si chiama delta transfer, ma è una cosa diversa. Per abilitarlo, aggiungi l' opzione -co --checksum. Una volta utilizzata questa opzione, rsync esaminerà i file esistenti su entrambe le estremità del filo. Lo fa a blocchi, confronta i checksum su entrambe le estremità e, se differiscono, trasferisce solo le diverse parti del file. Ma, come sottolineato da @Jonathan di seguito, il confronto viene effettuato solo quando i file hanno le stesse dimensioni su entrambe le estremità - dimensioni diverse causeranno rsync per caricare l'intero file, sovrascrivendo la destinazione con lo stesso nome.

Ciò richiede inizialmente un po 'di calcolo su entrambe le estremità, ma può essere estremamente efficiente nel ridurre il carico di rete se, ad esempio, si esegue spesso il backup di file molto grandi file di dimensioni fisse che spesso contengono modifiche minori. Esempi che vengono in mente sono i file di immagine del disco rigido virtuale utilizzati in macchine virtuali o destinazioni iSCSI.

È da notare che se si utilizza --checksumper trasferire un batch di file completamente nuovi nel sistema di destinazione, rsync calcolerà comunque i loro checksum sul sistema di origine prima di trasferirli. Perchè non lo so :)

Quindi, in breve:

Se stai usando spesso rsync per solo "spostare roba da A a B" e vogliono la possibilità di annullare questa operazione e poi riprenderlo, non usare --checksum, ma non usare --append-verify.

Se stai usando rsync per eseguire il backup delle cose spesso, --append-verifyprobabilmente non farà molto per te, a meno che tu non abbia l'abitudine di inviare file di grandi dimensioni che aumentano continuamente di dimensioni ma raramente vengono modificati una volta scritti. Come suggerimento bonus, se si esegue il backup su uno spazio di archiviazione che supporta snapshot come btrfso zfs, l'aggiunta dello --inplaceswitch consente di ridurre le dimensioni dello snapshot poiché i file modificati non vengono ricreati, ma i blocchi modificati vengono scritti direttamente su quelli precedenti. Questa opzione è utile anche se si desidera evitare che rsync crei copie di file sulla destinazione quando si sono verificate solo piccole modifiche.

Durante l'utilizzo --append-verify, rsync si comporterà come sempre su tutti i file della stessa dimensione. Se differiscono per modifiche o altri timestamp, sovrascriveranno la destinazione con l'origine senza esaminare ulteriormente quei file. --checksumconfronterà il contenuto (checksum) di ogni coppia di file con nome e dimensioni identici.

01/09/2015 AGGIORNATO Modificato per riflettere i punti sollevati da @Alex (grazie!)

AGGIORNATO 14/07/2017 Modificato per riflettere i punti sollevati da @Jonathan (grazie!)


4
Questo dice --partialbasta.
Cees Timmerman,


2
@CMCDragonkai In realtà, controlla la risposta di Alexander qui sotto su --partial-dir- sembra che sia il proiettile perfetto per questo. Potrei essermi perso qualcosa del tutto;)
DanielSmedegaard Buu,

2
@DanielSmedegaardBuus L'ho provato io stesso su una connessione lenta, e questo è quello che vedo solo con --partial: rsync copia il file nel nome temporaneo, la connessione viene interrotta, il rsync remoto alla fine sposta quel file sul nome normale ed esce, quindi su rieseguendo con --partiale senza --append , il nuovo file temporaneo viene inizializzato con una copia del file remoto parzialmente trasferito, quindi la copia continua da dove si è interrotta la connessione. (Ubuntu 14.04 / rsync 3.1)
Izkata,

4
Qual è il tuo livello di fiducia nel comportamento descritto di --checksum? Secondo manciò ha più a che fare con la decisione di quali file contrassegnare per il trasferimento che con delta-transfer (che, presumibilmente, è rsyncil comportamento predefinito).
Jonathan Y.

56

TL; DR:

Basta specificare una directory parziale come raccomandato dalle pagine man di rsync:

--partial-dir=.rsync-partial

Spiegazione più lunga:

In realtà esiste una funzione integrata per fare ciò utilizzando l' --partial-diropzione, che presenta diversi vantaggi rispetto all'alternativa --partiale --append-verify/ --append.

Estratto dalle pagine man di 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.

Per impostazione predefinita, rsync utilizza un nome file temporaneo casuale che viene eliminato quando un trasferimento fallisce. Come accennato, l'uso di --partialte può far sì che rsync mantenga il file incompleto come se fosse stato trasferito con successo , in modo che sia possibile aggiungerlo successivamente usando le opzioni --append-verify/ --append. Tuttavia, ci sono diversi motivi per cui questo non è ottimale.

  1. I file di backup potrebbero non essere completi e senza controllare il file remoto che deve essere comunque inalterato, non c'è modo di saperlo.

  2. Se stai tentando di utilizzare --backupe --backup-dir, hai appena aggiunto una nuova versione di questo file che non è nemmeno mai uscita prima dalla cronologia delle versioni.

Tuttavia, se lo utilizziamo --partial-dir, rsync manterrà il file parziale temporaneo e riprenderà il download utilizzando quel file parziale alla successiva esecuzione, e non soffriremo dei problemi di cui sopra.


38

Potresti voler aggiungere l' -Popzione al tuo comando.

Dalla manpagina:

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

Quindi invece di:

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

Fare:

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

Naturalmente, se non desideri gli aggiornamenti sui progressi, puoi semplicemente utilizzare --partial, ad esempio:

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

@Flimm non del tutto corretto. Se si verifica un'interruzione (rete o lato ricevente), quando si utilizza --partial il file parziale viene mantenuto E viene utilizzato quando si riprende rsync. Dalla manpage: "L'uso dell'opzione --partial dice a rsync di mantenere il file parziale che dovrebbe <b> effettuare un successivo trasferimento del resto del file molto più veloce </b>."
Gaoithe

2
@Flimm e @gaoithe, la mia risposta non è stata del tutto precisa, e sicuramente non aggiornata. L'ho aggiornato per riflettere la versione 3+ di rsync. E 'importante sottolineare, però, che --partialsi fa non è per sé riprendere un trasferimento fallito. Vedi la mia risposta per i dettagli :)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus L'ho provato ed -Pè abbastanza nel mio caso. Versioni: client ha 3.1.0 e server ha 3.1.1. Ho interrotto il trasferimento di un singolo file di grandi dimensioni con ctrl-c. Immagino che mi manchi qualcosa.
Guettli,

Perché vv? cioè vusato 2 volte?
MrGloom il

Dove rsync salva parte del file -azvvP?
MrGloom il

1

Penso che stai chiamando forzatamente il rsynce quindi tutti i dati vengono scaricati quando lo ricordi di nuovo. usa l' --progressopzione per copiare solo quei file che non sono stati copiati e l' --deleteopzione per eliminare tutti i file se già copiati e ora non esiste nella cartella sorgente ...

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

Se stai usando ssh per accedere ad un altro sistema e copiare i file,

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

fammi sapere se c'è qualche errore nella mia comprensione di questo concetto ...


1
Puoi per favore modificare la tua risposta e spiegare cosa fa la tua chiamata speciale ssh e perché consigli di farlo?
Fabien,

2
@Fabien Dice a rsync di impostare due opzioni ssh (rsync usa ssh per connettersi). Il secondo dice a ssh di non richiedere conferma se l'host a cui si sta connettendo non è già noto (esistente nel file "host conosciuti"). Il primo dice a ssh di non usare il file hosts noto predefinito (che sarebbe ~ / .ssh / known_hosts). Usa invece / dev / null, che è ovviamente sempre vuoto, e poiché ssh non troverebbe l'host lì dentro, normalmente richiederebbe conferma, quindi l'opzione due. Al momento della connessione, ssh scrive l'host ora noto su / dev / null, dimenticandolo efficacemente all'istante :)
DanielSmedegaardBuus

1
... ma probabilmente ti starai chiedendo quale effetto ha sulla stessa operazione rsync. La risposta è nessuna Serve solo a non aggiungere l'host a cui ti stai connettendo al tuo file host conosciuto SSH. Forse è un amministratore di sistema che si collega spesso a un gran numero di nuovi server, sistemi temporanei o quant'altro. Non lo so :)
DanielSmedegaardBuus

4
"usa l'opzione --progress per copiare solo quei file che non vengono copiati" Cosa?
moi,

1
Ci sono un paio di errori qui; uno è molto serio: --deleteeliminerà i file nella destinazione che non esistono nella fonte. Il meno grave è che --progressnon modifica il modo in cui le cose vengono copiate; ti dà solo un rapporto sullo stato di avanzamento di ogni file mentre viene copiato. (Ho corretto l'errore grave; sostituito con --remove-source-files.)
Paul d'Aoust,

1

Sto usando questo semplice script. Sentiti libero di regolare alcuni flag e / o parametrizzarli.

#!/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

Arrivando tardi a questo, ma avevo la stessa domanda e ho trovato una risposta diversa.

Il --partialflag ("conserva i file parzialmente trasferiti" in rsync -h) è utile per file di grandi dimensioni, come lo è --append("aggiungi dati a file più brevi"), ma la domanda riguarda un numero elevato di file.

Per evitare i file che sono già stati copiati, utilizzare -u(oppure --update: "salta i file più recenti sul ricevitore").

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.