Czy rsync może zostać wznowiony po przerwaniu?

188

Kiedyś rsynckopiowałem dużą liczbę plików, ale mój system operacyjny (Ubuntu) uruchomił się nieoczekiwanie.

Po ponownym uruchomieniu uruchomiłem rsyncponownie, ale z danych wyjściowych na terminalu odkryłem, że rsyncnadal kopiowały te już skopiowane wcześniej. Ale słyszałem, że rsyncjest w stanie znaleźć różnice między źródłem a miejscem docelowym, a zatem po prostu skopiować różnice. Zastanawiam się więc, czy rsyncmogę wznowić to, co zostało po raz ostatni?

Tim
źródło
Tak, rsync nie kopiuje ponownie plików, które zostały już skopiowane. Istnieje kilka przypadków krawędzi, w których jego wykrycie może się nie powieść. Czy skopiował wszystkie już skopiowane pliki? Z jakich opcji korzystałeś? Jakie były źródłowe i docelowe systemy plików? Jeśli uruchomisz rsync ponownie po skopiowaniu wszystkiego, czy kopiuje się ponownie?
Gilles
@Gilles: Dzięki! (1) Myślę, że widziałem, jak rsync ponownie skopiował te same pliki z danych wyjściowych na terminalu. (2) Opcje są takie same jak w moim innym poście, tj sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) Zarówno źródło, jak i cel to NTFS, kup źródło to zewnętrzny dysk twardy, a cel to wewnętrzny dysk twardy. (3) Teraz działa i jeszcze się nie skończył.
Tim
Istnieje również --partial flag wznowić częściowo przesłanych plików (przydatne w przypadku dużych plików)
jwbensley
3
@ Tim Z czubka mojej głowy jest co najmniej przesunięcie zegara i różnice w rozdzielczości czasowej (częsty problem z systemami plików FAT, które przechowują czasy w przyrostach 2-sekundowych, --modify-windowopcja pomaga w tym).
Gilles
1
jeśli nie masz / lub /. na końcu argumentu ścieżki do pliku źródłowego będzie wtedy tworzyć dodatkową kopię w podkatalogu o takiej samej nazwie jak katalog źródłowy
Skaperen

Odpowiedzi:

285

Po pierwsze, jeśli chodzi o część „wznawiania” pytania, --partialpo prostu mówi stronie odbierającej, aby zachowała częściowo przesłane pliki, jeśli strona wysyłająca zniknie, jakby zostały całkowicie przeniesione.

Podczas przesyłania pliki są tymczasowo zapisywane jako pliki ukryte w folderach docelowych (np. .TheFileYouAreSending.lRWzDC) Lub w specjalnie wybranym folderze, jeśli ustawisz --partial-dirprzełącznik. Gdy przesyłanie się nie powiedzie i --partialnie zostanie ustawione, ten ukryty plik pozostanie w folderze docelowym pod tą tajemniczą nazwą, ale jeśli --partialzostanie ustawiony, nazwa pliku zostanie zmieniona na rzeczywistą nazwę pliku docelowego (w tym przypadku TheFileYouAreSending), nawet jeśli plik nie jest kompletny. Chodzi o to, że można później zakończyć przenoszenie ponownie uruchomiony z rsync albo --appendalbo --append-verify.

Tak więc, --partialnie sama wznowić uszkodzonego lub odwołany transfer. Aby go wznowić, przy następnym uruchomieniu będziesz musiał użyć jednej z wyżej wymienionych flag. Tak więc, jeśli musisz upewnić się, że cel nigdy nie będzie zawierał plików, które wydają się być w porządku, ale w rzeczywistości są niekompletne, nie powinieneś używać --partial. I odwrotnie, jeśli chcesz się upewnić, że nigdy nie pozostawisz zabłąkanych plików, które są ukryte w katalogu docelowym, i wiesz, że będziesz w stanie dokończyć transfer później, --partialpomoże Ci to.

W odniesieniu do --appendwspomnianego powyżej przełącznika jest to rzeczywisty przełącznik „wznawiania” i możesz go używać, niezależnie od tego, czy korzystasz --partial. W rzeczywistości, gdy korzystasz --append, nigdy nie są tworzone pliki tymczasowe. Pliki są zapisywane bezpośrednio w swoich obiektach docelowych. Pod tym względem --appenddaje taki sam wynik jak --partialw przypadku nieudanego transferu, ale bez tworzenia ukrytych plików tymczasowych.

Podsumowując, jeśli przenosisz duże pliki i chcesz wznowić anulowaną lub nieudaną operację rsync od dokładnego punktu, który został rsynczatrzymany, musisz użyć --appendlub --append-verifywłączyć kolejną próbę.

Jak wskazuje @Alex poniżej, ponieważ wersja 3.0.0 rsyncma teraz nową opcję --append-verify, która zachowuje się tak, --appendjak przed wprowadzeniem tego przełącznika. Prawdopodobnie zawsze chcesz się zachowywać --append-verify, więc sprawdź swoją wersję za pomocą rsync --version. Jeśli jesteś na Macu i nie korzysta rsyncze homebrewbędziesz (przynajmniej włącznie El Capitan) masz starszą wersję i trzeba użyć --appendzamiast --append-verify. Dlaczego nie utrzymywali tego zachowania --appendi zamiast tego nazwali przybysza, --append-no-verifyjest to nieco zagadkowe. Tak czy inaczej, --appendna rsyncwcześniej wersja 3 jest taka sama jak --append-verifyw nowszych wersjach.

--append-verifynie jest niebezpieczne: zawsze będzie czytać i porównywać dane na obu końcach, a nie tylko zakładać, że są równe. Robi to za pomocą sum kontrolnych, więc jest to łatwe w sieci, ale wymaga odczytu udostępnionej ilości danych na obu końcach drutu, zanim będzie mógł faktycznie wznowić przesyłanie przez dołączenie do celu.

Po drugie, powiedziałeś, że „słyszałeś, że rsync jest w stanie znaleźć różnice między źródłem a miejscem docelowym, a zatem po prostu skopiować różnice”.

Zgadza się i nazywa się to transferem delta, ale to inna sprawa. Aby to włączyć, dodaj przełącznik -club --checksum. Po użyciu tego przełącznika rsync sprawdzi pliki, które istnieją na obu końcach drutu. Robi to w kawałkach, porównuje sumy kontrolne na obu końcach, a jeśli się różnią, przenosi tylko różne części pliku. Ale, jak wskazuje @Jonathan poniżej, porównanie jest wykonywane tylko wtedy, gdy pliki mają ten sam rozmiar na obu końcach - różne rozmiary powodują, że rsync prześle cały plik, zastępując cel o tej samej nazwie.

Wymaga to początkowo trochę obliczeń na obu końcach, ale może być niezwykle skuteczne w zmniejszaniu obciążenia sieci, jeśli na przykład często tworzysz kopie zapasowe bardzo dużych plików o stałym rozmiarze, które często zawierają niewielkie zmiany. Przykładami, które przychodzą na myśl, są pliki obrazów wirtualnych dysków twardych używane w maszynach wirtualnych lub obiektach docelowych iSCSI.

Warto zauważyć, że jeśli użyjesz --checksumdo przeniesienia partii plików, które są całkowicie nowe do systemu docelowego, rsync nadal obliczy ich sumy kontrolne w systemie źródłowym przed przesłaniem ich. Dlaczego nie wiem :)

Krótko mówiąc:

Jeśli często za pomocą rsync po prostu „przenieść rzeczy z punktu A do B” i chcą możliwość anulowania tej operacji a potem wznowić go nie używać --checksum, ale nie używać --append-verify.

Jeśli używasz rsync do częstego tworzenia kopii zapasowych, --append-verifyprawdopodobnie nie zrobisz dla ciebie wiele, chyba że masz zwyczaj wysyłania dużych plików, które stale rosną, ale rzadko są modyfikowane po napisaniu. Jako dodatkową wskazówkę, jeśli tworzysz kopię zapasową w pamięci, która obsługuje migawki, takie jak btrfslub zfs, dodanie --inplaceprzełącznika pomoże zmniejszyć rozmiary migawek, ponieważ zmienione pliki nie są odtwarzane, ale zmienione bloki są zapisywane bezpośrednio nad starymi. Ten przełącznik jest także przydatny, jeśli chcesz uniknąć rsync tworzenia kopii plików w systemie docelowym, gdy wystąpiły tylko niewielkie zmiany.

Podczas używania --append-verifyrsync zachowuje się tak samo jak zawsze we wszystkich plikach o tym samym rozmiarze. Jeśli różnią się modyfikacją lub innymi znacznikami czasu, zastąpi cel źródłem bez dalszego sprawdzania tych plików. --checksumporówna zawartość (sumy kontrolne) każdej pary plików o identycznej nazwie i rozmiarze.

ZAKTUALIZOWANO 01.01.2015 Zmieniono, aby odzwierciedlać punkty wykonane przez @Alex (dzięki!)

ZAKTUALIZOWANO 2017-07-14 Zmieniono, aby odzwierciedlać punkty poczynione przez @Jonathan (dzięki!)

DanielSmedegaardBuus
źródło
4
To mówi, --partialwystarczy.
Cees Timmerman,
2
@CMCDragonkai W rzeczywistości sprawdź poniżej odpowiedź Aleksandra na temat --partial-dir- wygląda na to, że jest to idealna kula do tego. Mogłem coś całkowicie przeoczyć;)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Przetestowałem to sam na wolnym połączeniu, i widzę to tylko z tym --partial: rsync kopiuje plik do nazwy tymczasowej, połączenie zostaje przerwane, zdalne rsync ostatecznie przenosi ten plik do zwykłej nazwy i kończy, a następnie ponownie uruchomiony z --partiallub bez --append , nowy plik tymczasowy jest inicjowany kopią częściowo przesłanego pliku zdalnego, a następnie kopia jest kontynuowana od miejsca, w którym nastąpiło połączenie. (Ubuntu 14.04 / rsync 3.1)
Izkata
4
Jaki jest Twój poziom zaufania do opisywanego zachowania --checksum? Zgodnie z mantym ma to więcej wspólnego z decydowaniem, które pliki oznaczyć do przesłania, niż z transferem delta (co jest prawdopodobnie rsyncdomyślnym zachowaniem).
Jonathan Y.
56

TL; DR:

Po prostu określ katalog częściowy, zgodnie z zaleceniami stron podręcznika rsync:

--partial-dir=.rsync-partial

Dłuższe wyjaśnienie:

W rzeczywistości jest wbudowana funkcja umożliwiająca to przy użyciu --partial-diropcji, która ma kilka zalet w porównaniu z / --partiali .--append-verify--append

Fragment stron man 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.

Domyślnie rsync używa losowej nazwy pliku tymczasowego, która jest usuwana w przypadku niepowodzenia transferu. Jak wspomniano, za pomocą polecenia --partialrsync można zachować niekompletny plik tak, jakby został pomyślnie przesłany , aby można było później dołączyć go za pomocą opcji --append-verify/ --append. Jest jednak kilka powodów, dla których nie jest to optymalne.

  1. Pliki kopii zapasowej mogą być niekompletne i bez sprawdzenia zdalnego pliku, który musi być niezmieniony, nie ma sposobu, aby się dowiedzieć.

  2. Jeśli próbujesz użyć --backupi --backup-dir, właśnie dodałeś nową wersję tego pliku, która nigdy nawet nie wychodziła z historii wersji.

Jeśli jednak użyjemy --partial-dir, rsync zachowa tymczasowy plik częściowy i wznowi pobieranie przy użyciu tego pliku częściowego przy następnym uruchomieniu, a my nie cierpimy z powodu powyższych problemów.

Alexander O'Mara
źródło
38

Możesz dodać -Popcję do swojego polecenia.

Ze manstrony:

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

Więc zamiast:

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

Zrobić:

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

Oczywiście, jeśli nie chcesz aktualizacji postępu, możesz po prostu użyć --partial, tj .:

sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2
N2O
źródło
@Flimm nie całkiem poprawnie. Jeśli występuje przerwa (strona sieciowa lub odbiorcza), wówczas przy użyciu opcji --partial plik częściowy jest zachowywany ORAZ jest używany, gdy wznawia się rsync. Z strony podręcznika: „Użycie opcji --partial nakazuje rsync zachować plik częściowy, który powinien <b> znacznie przyspieszyć późniejsze przesyłanie pozostałej części pliku </b>.”
gaoithe,
2
@Flimm i @gaoithe, moja odpowiedź nie była dość dokładna i zdecydowanie nieaktualna. Zaktualizowałem go, aby odzwierciedlić wersję 3 + rsync. Należy jednak podkreślić, że --partialsamo nie wznawia nieudanego transferu. Zobacz moją odpowiedź, aby poznać szczegóły :)
DanielSmedegaardBuus 1'15
2
@DanielSmedegaardBuus Próbowałem i -Pto wystarczy w moim przypadku. Wersje: klient ma 3.1.0, a serwer 3.1.1. Przerwałem przesyłanie pojedynczego dużego pliku za pomocą Ctrl-C. Chyba coś mi umknęło.
guettli,
Dlaczego vv? tj. vużyty 2 razy?
mrgloom
Gdzie rsync zapisuje część pliku -azvvP?
mrgloom
1

Myślę, że siłą dzwonisz rsynci dlatego wszystkie dane są pobierane, gdy je ponownie przywołujesz. użyj --progressopcji, aby skopiować tylko te pliki, które nie zostały skopiowane, i --deleteopcji usunięcia plików, jeśli zostały już skopiowane, a teraz nie istnieje w folderze źródłowym ...

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

Jeśli używasz ssh do logowania do innego systemu i kopiowania plików,

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

daj mi znać, jeśli mam jakiś błąd w moim rozumieniu tej koncepcji ...

Yadunandana
źródło
1
Czy możesz zredagować swoją odpowiedź i wyjaśnić, co robi twoje specjalne połączenie ssh i dlaczego radzisz to zrobić?
Fabien
2
@Fabien Mówi rsync, aby ustawił dwie opcje ssh (rsync używa ssh do połączenia). Drugi mówi ssh, aby nie pytał o potwierdzenie, jeśli host, z którym się łączy, nie jest już znany (poprzez istnienie w pliku „znanych hostów”). Pierwszy mówi ssh, aby nie używał domyślnego znanego pliku hosts (którym byłby ~ / .ssh / known_hosts). Zamiast tego używa / dev / null, który oczywiście jest zawsze pusty, a ponieważ ssh nie znalazłby tam hosta, zwykle monitowałby o potwierdzenie, stąd opcja druga. Po połączeniu ssh zapisuje znanego obecnie hosta do / dev / null, skutecznie zapominając o tym natychmiast :)
DanielSmedegaardBuus
1
... ale prawdopodobnie zastanawiałeś się, jaki wpływ, jeśli w ogóle, ma on na samą operację rsync. Odpowiedź brzmi: nie. Służy tylko temu, aby host, z którym się łączysz, nie został dodany do pliku znanych hostów SSH. Być może jest administratorem często łączącym się z wieloma nowymi serwerami, systemami tymczasowymi lub czymkolwiek innym. Nie wiem :)
DanielSmedegaardBuus
4
„użyj opcji --progress, aby skopiować tylko te pliki, które nie są kopiowane” Co?
moi
1
Jest tu kilka błędów; jeden jest bardzo poważny: --deleteusunie pliki w miejscu docelowym , które nie istnieją w źródle. Mniej poważne jest to, że --progressnie modyfikuje sposobu kopiowania rzeczy; po prostu daje raport postępu dla każdego pliku podczas kopiowania. (Naprawiłem poważny błąd; zastąpiłem go --remove-source-files).
Paul d'Aoust
1

Używam tego prostego skryptu. Dostosuj niektóre flagi i / lub sparametryzuj je.

#!/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
źródło
1

Spóźniłem się na to, ale miałem to samo pytanie i znalazłem inną odpowiedź.

--partialFlag ( „keep częściowo przeniesione pliki” w rsync -h) jest przydatne w przypadku dużych plików, co jest --append( „dołączyć dane na krótszych plików”), ale pytanie jest o wiele plików.

Aby uniknąć skopiowania plików, użyj -u(lub --update: „pomiń pliki, które są nowsze w odbiorniku”).

lazysoundsystem
źródło