Чи може rsync відновитись після перерви?


188

Раніше я rsyncкопіював велику кількість файлів, але моя ОС (Ubuntu) несподівано перезапустилася.

Після перезавантаження я rsyncзнову запустився , але з висновку на терміналі я виявив, що rsyncвсе ще копіював ті, що вже скопійовані раніше. Але я чув, що rsyncздатний знайти відмінності між джерелом та пунктом призначення, а тому просто скопіювати відмінності. Тож мені цікаво, чи rsyncможна відновити те, що залишилося минулого разу?


Так, rsync не буде копіювати файли, які вже скопійовано. Є кілька крайніх випадків, коли його виявлення може виявитися невдалим. Чи скопіювали всі вже скопійовані файли? Які варіанти ви використовували? Які були вихідні та цільові файлові системи? Якщо ви знову запустите rsync після того, як все скопійовано, чи копіюється він знову?
Жиль

@Gilles: Дякую! (1) Я думаю, що я побачив, що rsync знову копіював ті самі файли зі свого виходу на термінал. (2) Варіанти такі ж, як і в моїй іншій посаді, тобто sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) Джерело та ціль - це NTFS, джерело придбання - зовнішній жорсткий диск, а ціль - внутрішній жорсткий диск. (3) Зараз він працює і ще не закінчився.
Тим

Є також - частковий прапор для відновлення частково переданих файлів (корисний для великих файлів)
jwbensley

3
@Tim Off the top of my head, є щонайменше перекос годинника та відмінності у вирішенні часу (поширена проблема з файловими системами FAT, які зберігають час з кроком 2 секунди; --modify-windowваріант допомагає в цьому).
Жиль

1
якщо у вас не було / або /. в кінці кінця аргументу вихідного коду файлу, тоді він буде робити додаткову копію у підкаталозі, який має те саме ім'я, що і вихідний каталог
Skaperen

Відповіді:


285

Перш за все, щодо частини "резюме" у вашому запитанні --partialякраз і вказує на кінець прийому зберігати частково передані файли, якщо кінець відправки зникає так, ніби вони були повністю передані.

Під час передачі файлів вони тимчасово зберігаються як приховані файли у своїх цільових папках (наприклад .TheFileYouAreSending.lRWzDC) або спеціально вибраній папці, якщо встановити --partial-dirкомутатор. Якщо передача не вдасться і --partialне встановлена, цей прихований файл залишатиметься в цільовій папці під цим криптованим іменем, але якщо --partialвін встановлений, файл буде перейменований на фактичне цільове ім'я файлу (у цьому випадку TheFileYouAreSending), навіть незважаючи на те, що файл не завершено. Справа в тому, що згодом ви можете завершити передачу, запустивши rsync знову за допомогою --appendабо --append-verify.

Отже, сама по собі--partial не відновить невдалу або скасовану передачу. Щоб відновити його, вам доведеться використовувати один із вищезгаданих прапорів при наступному запуску. Отже, якщо вам потрібно переконатися, що ціль ніколи не буде містити файли, які здаються нормальними, але насправді є неповними, не слід використовувати . І навпаки, якщо ви хочете переконатися, що ви ніколи не залишаєте позаду білих файлів, які заховані в цільовому каталозі, і ви знаєте, що зможете завершити передачу пізніше, чи можна вам допомогти.--partial--partial

Що стосується --appendзгаданого вище перемикача, то це фактичний перемикач "відновити", і ви можете ним користуватися, використовуєте ви чи ні --partial. Насправді, коли ви використовуєте --append, тимчасові файли ніколи не створюються. Файли записуються безпосередньо до їхніх цілей. У цьому відношенні --appendдає такий же результат, як і --partialпри невдалій передачі, але без створення цих прихованих тимчасових файлів.

Отже, підводячи підсумок, якщо ви переміщуєте великі файли і хочете, щоб можливість відновити скасовувану або невдалу операцію rsync з точної точки, яка rsyncзупинилася, вам потрібно скористатися --appendабо --append-verifyввімкнути наступну спробу.

Як зазначає @Alex нижче, оскільки версія 3.0.0 rsyncтепер має новий параметр --append-verify, який поводиться так, як робився --appendдо цього перемикача. Ви, мабуть, завжди хочете поведінки --append-verify, тому перевірте свою версію rsync --version. Якщо ви на Mac і не використовуючи rsyncз homebrew, ви (принаймні , до і в тому числі El Capitan) мають більш стару версію і потрібно використовувати --appendзамість --append-verify. Чому вони не продовжували свою поведінку --appendі замість цього називали прибульця --append-no-verify, це трохи спантеличено. У будь-якому випадку, --appendна rsyncперед тим версії 3 така ж , як --append-verifyна новіших версіях.

--append-verifyНе небезпечно: вони завжди будуть читати та порівнювати дані з обох кінців, а не просто вважати, що вони рівні. Це робиться за допомогою контрольних сум, тому в мережі це легко, але потрібно прочитати загальний обсяг даних на обох кінцях дроту, перш ніж реально відновити передачу, додавши до цілі.

По-друге, ви сказали, що "чули, що rsync здатний знаходити відмінності між джерелом та пунктом призначення, а тому просто копіювати відмінності".

Це правильно, і це називається перенесення дельти, але це різна річ. Щоб увімкнути це, ви додаєте перемикач -cабо --checksum. Після використання цього комутатора rsync вивчить файли, які існують на обох кінцях дроту. Він робить це в шматки, порівнює контрольні суми на обох кінцях, і якщо вони відрізняються, він передає лише різні частини файлу. Але, як зазначає @Jonathan нижче, порівняння проводиться лише тоді, коли файли мають однаковий розмір на обох кінцях - різні розміри призведуть до того, що rsync завантажить весь файл, замінивши цільове однойменне ім'я.

Для цього потрібно спочатку трохи обчислити з обох кінців, але може бути надзвичайно ефективним для зменшення навантаження на мережу, якщо, наприклад, ви часто створюєте резервну копію дуже великих файлів фіксованого розміру, які часто містять незначні зміни. Прикладами, які спадають на думку, є віртуальні файли зображень жорсткого диска, що використовуються у віртуальних машинах або iSCSI-цілях.

Примітно, що якщо ви використовуєте --checksumдля передачі партії файлів, які є абсолютно новими в цільовій системі, rsync все одно буде обчислювати контрольні суми у вихідній системі перед їх передачею. Чому я не знаю :)

Отже, коротше:

Якщо ви часто використовуєте rsync, щоб просто "перемістити речі з А на В" і хочете, щоб можливість скасувати цю операцію та пізніше відновити її, не використовуйте --checksum, але не використовуйте --append-verify.

Якщо ви використовуєте rsync для резервного копіювання матеріалів часто, використання, --append-verifyймовірно, не зробить багато для вас, якщо тільки ви не маєте звички надсилати великі файли, які постійно збільшуються у розмірі, але рідко змінюються після написання. Як підказка про бонус, якщо ви створюєте резервну копію пам’яті, що підтримує знімки, наприклад, btrfsабо zfs, додавання --inplaceкомутатора допоможе вам зменшити розміри знімків, оскільки змінені файли не відтворюються, а змінені блоки записуються безпосередньо над старими. Цей перемикач також корисний, якщо ви хочете уникнути створення rsync копій файлів на цільовому рівні, коли відбулися лише незначні зміни.

Під час використання --append-verifyrsync буде вести себе так, як це завжди робиться для всіх файлів однакового розміру. Якщо вони відрізняються модифікацією чи іншими часовими позначками, це замінить ціль джерелом, не перевіряючи ці файли далі. --checksumбуде порівнювати вміст (контрольні суми) кожної пари файлів однакового імені та розміру.

ОНОВЛЕНО 2015-09-01 Змінено для відображення балів, зроблених @Alex (спасибі!)

ОНОВЛЕНО 2017-07-14 Змінено для відображення балів, зроблених @Jonathan (спасибі!)


4
Це говорить --partialдостатньо.
Cees Timmerman


2
@CMCDragonkai Власне, ознайомтеся з відповіддю Олександра нижче --partial-dir- схоже, це ідеальна куля для цього. Я, можливо, щось цілком пропустив;)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Я перевірив це сам на повільному з’єднанні, і це те, що я бачу лише --partial : rsync копіює файл у тимчасове ім'я, з'єднання перервано, віддалений rsync врешті-решт перемістить цей файл до звичайного імені та закриє, потім повторний запуск з --partialі без --append , новий тимчасовий файл ініціалізується копією частково переданого віддаленого файлу, після чого копія продовжується з того місця, де з'єднання загинуло. (Ubuntu 14.04 / rsync 3.1)
Izkata

4
Який у вас рівень впевненості в описаній поведінці --checksum? Згідно з цим, manце пов'язано більше з вирішенням, які файли потрібно позначити для передачі, ніж з дельта-передачею (що, імовірно, є rsyncповедінкою за замовчуванням).
Джонатан Ю.

56

TL; DR:

Просто вкажіть частковий каталог, як рекомендує сторінка rsync man:

--partial-dir=.rsync-partial

Більш тривале пояснення:

Насправді є вбудована функція для цього за допомогою --partial-dirопції, яка має ряд переваг перед --partialта --append-verify/ --appendальтернативою.

Уривок зі сторінок людини 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.

За замовчуванням rsync використовує випадкове тимчасове ім'я файлу, яке видаляється, коли передача не вдається. Як було зазначено, за допомогою --partialви можете змусити rsync зберігати неповний файл так, як би він був успішно переданий , щоб згодом було можливо додати його за допомогою --append-verify/ --appendoptions. Однак є кілька причин, що це неоптимально.

  1. Файли резервної копії можуть бути неповними, і без перевірки віддаленого файлу, який все-таки повинен бути незмінним, це неможливо знати.

  2. Якщо ви намагаєтесь використати --backupі --backup-dir, ви щойно додали нову версію цього файлу, яка раніше ніколи не виходила до історії вашої версії.

Однак якщо ми використовуємо --partial-dir, rsync збереже тимчасовий частковий файл і відновить завантаження за допомогою цього часткового файлу при наступному запуску, і ми не страждатимемо від вищезазначених проблем.


38

Ви можете додати -Pпараметр до своєї команди.

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

Тож замість:

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

Зробіть:

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

Звичайно, якщо ви не хочете оновлювати прогрес, ви можете просто скористатися --partial, тобто:

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

@Flimm не зовсім коректно. Якщо відбувається переривання (мережева або приймальна сторона), тоді при використанні - частково зберігається частковий файл І він використовується, коли rsync поновлюється. На сторінці сторінки: "Використання параметра --partial повідомляє rsync зберігати частковий файл, який повинен <b> зробити подальшу передачу решти файлу набагато швидшою </b>."
gaoithe

2
@Flimm та @gaoithe, моя відповідь була не зовсім точною і, безумовно, не актуальною. Я оновив його, щоб відобразити версію 3 + з rsync. Дуже важливо , щоб стрес, однак, що --partialце НЕ сам відновити невдалу передачу. Детальніше дивіться у моїй відповіді :)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Я спробував це, і цього -Pв моєму випадку достатньо. Версії: клієнт має 3.1.0, а сервер - 3.1.1. Я перервав передачу одного великого файлу ctrl-c. Я думаю, я щось пропускаю.
guettli

Чому vv? тобто vвикористовується 2 рази?
mrgloom

Де rsync зберігає частину файлу -azvvP?
mrgloom

1

Я думаю, що ви примусово телефонуєте, rsyncа отже, всі дані завантажуються, коли ви знову їх згадуєте. Використовуйте --progressопцію для копіювання лише тих файлів, які не скопійовані, і --deleteопцію для видалення будь-яких файлів, якщо вони вже скопійовані, а зараз її немає у вихідній папці ...

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

Якщо ви використовуєте ssh для входу в іншу систему та копіювання файлів,

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

дайте мені знати, чи є помилка в моєму розумінні цієї концепції ...


1
Чи можете ви відредагувати свою відповідь і пояснити, що робить ваш спеціальний дзвінок ssh, і чому ви радите це робити?
Фабієн

2
@Fabien Він каже rsync встановити два параметри ssh (rsync використовує ssh для підключення). Другий повідомляє ssh не вимагати підтвердження, якщо хост, до якого він підключається, ще не відомий (наявний у файлі "відомих хостів"). Перший повідомляє ssh не використовувати відомий за замовчуванням файл хостів (який би був ~ / .ssh / known_hosts). Він замість цього використовує / dev / null, який, звичайно, завжди порожній, і оскільки ssh тоді не знайде хоста там, він зазвичай вимагає підтвердження, отже, варіант два. Підключившись, ssh записує відомий хост в / dev / null, фактично його забуваючи миттєво :)
DanielSmedegaardBuus

1
... але ви, напевно, цікавились, який ефект, якщо такий є, він має на саму операцію rsync. Відповідь - жодна. Він служить лише тому, щоб хост, з яким ви підключаєтесь, не був доданий до вашого відомого файлу хостів SSH. Можливо, він є системним адміністратором, який часто підключається до великої кількості нових серверів, тимчасових систем чи чогось іншого. Я не знаю :)
DanielSmedegaardBuus

4
"Використовувати --progress параметр для копіювання лише тих файлів, які не скопійовані" Що?
Moi

1
Тут є кілька помилок; один дуже серйозний: --deleteвидалить файли в пункті призначення , які не існують у джерелі. Менш серйозним є те, --progressщо не змінює способи копіювання; він просто дає звіт про хід виконання кожного файлу під час його копіювання. (Я виправив серйозну помилку; замінив її --remove-source-files.)
Пауль д'Ауст

1

Я використовую цей простий сценарій. Сміливо налаштовуйте певні прапори та / або параметризуйте їх.

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

Прийшов пізно до цього, але у мене було те саме питання, і я знайшов іншу відповідь.

--partialПрапор ( «тримати частково передані файли» в rsync -h) корисний для великих файлів, як --append( «додати дані на більш короткі файли»), але мова йде про велику кількість файлів.

Щоб уникнути файлів, які вже скопійовані, використовуйте -u(або --update: "пропустіть нові файли на приймачі").

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.