Может ли rsync возобновиться после прерывания?

188

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

После перезагрузки я rsyncснова запустился , но из вывода на терминале я обнаружил, что rsyncвсе еще копировал те, что уже копировали ранее. Но я слышал, что rsyncспособен найти различия между источником и местом назначения, и, следовательно, просто скопировать различия. Так что мне интересно в моем случае, rsyncможет ли возобновить то, что осталось в прошлый раз?

Тим
источник
Да, rsync больше не будет копировать файлы, которые уже скопированы. Есть несколько крайних случаев, когда его обнаружение может потерпеть неудачу. Скопировал ли он все уже скопированные файлы? Какие варианты вы использовали? Каковы были исходная и целевая файловые системы? Если вы снова запустите rsync после того, как все скопировано, будет ли оно копироваться снова?
Жиль
@ Жиль: Спасибо! (1) Мне кажется, я видел, как rsync снова скопировал те же файлы со своего вывода на терминал. (2) Параметры такие же , как и в моем другом посте, то есть sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) Источник и цель - NTFS, источник покупки - внешний жесткий диск, а цель - внутренний жесткий диск. (3) Сейчас он работает и еще не закончен.
Тим
Также есть флаг --partial для возобновления частично переданных файлов (полезно для больших файлов)
jwbensley
3
@Tim Вдобавок ко мне, по крайней мере, наблюдается перекос часов и различия в разрешении по времени (обычная проблема с файловыми системами 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 и не используете rsyncfrom homebrew, у вас (по крайней мере, до El Capitan, включая 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 (спасибо!)

DanielSmedegaardBuus
источник
4
Это говорит, --partialчто достаточно.
Сис Тиммерман
2
@CMCDragonkai На самом деле, проверьте ответ Александра ниже о --partial-dir- похоже, это идеальная пуля для этого. Я, возможно, что-то упустил полностью;)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Я сам проверил его на медленном соединении, и вот что я вижу только --partial : rsync копирует файл во временное имя, соединение прерывается, удаленный rsync в конечном итоге перемещает этот файл к обычному имени и завершает работу, а затем при повторном запуске с --partialи без --append , новый временный файл инициализируется копией частично переданного удаленного файла, затем копия продолжается с того места, где прервалось соединение. (Ubuntu 14.04 / rsync 3.1)
Изката
4
Каков ваш уровень доверия к описанному поведению --checksum? В соответствии с этим manон больше связан с решением, какие файлы пометить для передачи, чем с дельта-передачей (что, по-видимому, является rsyncповедением по умолчанию).
Джонатан Я.
56

TL; DR:

Просто укажите частичный каталог, так как справочные страницы rsync рекомендуют:

--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 использует случайное временное имя файла, которое удаляется при сбое передачи. Как уже упоминалось, с помощью --partialrsync вы можете сохранить неполный файл, как если бы он был успешно передан , чтобы впоследствии можно было добавить его, используя параметры --append-verify/ --append. Однако есть несколько причин, по которым это неоптимально.

  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
N2O
источник
@Flimm не совсем правильно. Если происходит прерывание (на стороне сети или на стороне приема), то при использовании --partial частичный файл сохраняется И он используется при возобновлении rsync. Из man-страницы: «Использование параметра --partial указывает rsync сохранять частичный файл, который должен <b> сделать последующую передачу остальной части файла намного быстрее </ b>».
gaoithe
2
@Flimm и @gaoithe, мой ответ был не совсем точным и определенно не актуальным. Я обновил его, чтобы отразить версию 3+ rsync. Однако важно подчеркнуть, что --partialэто само по себе не возобновляет неудачную передачу. Подробности смотрите в моем ответе :)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Я попробовал это, и этого -Pдостаточно в моем случае. Версии: клиент имеет 3.1.0, а сервер имеет 3.1.1. Я прервал передачу одного большого файла с помощью Ctrl-C. Я думаю, что я что-то упустил
Геттли
Почему vv? т.е. vиспользовали 2 раза?
Мрглом
Где Rsync сохранить часть файла с -azvvP?
Мрглом
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
msgstr "использовать параметр --progress для копирования только тех файлов, которые не были скопированы" Что?
Moi
1
Здесь есть пара ошибок; один очень серьезный: --deleteудалит файлы в месте назначения, которые не существуют в источнике. Менее серьезным является то, что --progressэто не меняет способ копирования; он просто дает вам отчет о проделанной работе по каждому файлу при копировании. (Я исправил серьезную ошибку; заменил ее на --remove-source-files.)
Paul d'Aoust
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
NeverEndingQueue
источник
1

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

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

Чтобы избежать файлов, которые уже были скопированы, используйте -u(или --update: «пропустите файлы, которые новее на приемнике»).

lazysoundsystem
источник