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

Вопрос или проблема

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

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

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

Источник и цель оба находятся на NTFS. Источник — внешний жесткий диск, а цель — внутренний жесткий диск.

Интересно, сможет ли rsync в моем случае возобновить то, что было оставлено в последний раз?

Прежде всего, по поводу части вашего вопроса о “возобновлении”, --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 поможет уменьшить размеры снапшотов, поскольку измененные файлы не будут создаваться заново, а составляющие блоки будут записываться прямо поверх старых. Этот переключатель также полезен, если вы хотите избежать создания копий файлов к системе, когда произошли только незначительные изменения.

При использовании --append-verify rsync будет вести себя так же, как всегда, на всех файлах, имеющих тот же размер. Если они различаются по времени модификации или другим временным меткам, он перезапишет цель исходником без дальнейшего изучения этих файлов. --checksum будет сравнивать содержимое (контрольные суммы) каждой пары файлов одинакового имени и размера.

ОБНОВЛЕНО 2015-09-01 Изменено, чтобы отразить моменты, отмеченные @Alex (спасибо!)

ОБНОВЛЕНО 2017-07-14 Изменено, чтобы отразить моменты, отмеченные @Jonathan (спасибо!)

Кратко:

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

--partial-dir=.rsync-partial

Длинное объяснение:

На самом деле, это функция встроена в rsync и реализована с помощью опции --partial-dir, которая имеет несколько преимуществ перед --partial и альтернативой --append-verify/--append.

Извлечение из руководства по rsync:

--partial-dir=DIR
      Более лучший способ сохранения частичных файлов, чем опция --partial, 
      это указать DIR, который будет использоваться для содержания 
      частичных данных (вместо записи их в файл назначения).
      При следующей передаче rsync использует файл, найденный в этом DIR,
      как данные для ускорения возобновления передачи и затем удаляет его
      после того, как он выполнит свою функцию.

      Заметьте, что если указана опция --whole-file (или видимая), любой файл
      в partial-dir, который был найден для обновляемого файла, просто будет
      удален (поскольку rsync отправляет файлы без использования
      алгоритма дельта-передачи rsync).

      Rsync создаст DIR, если его не существует (только последний dir — не весь путь).
      Это облегчает использование относительного пути (например,
      "--partial-dir=.rsync-partial"), чтобы rsync создавал partial-directory
      в директории файла назначения по мере необходимости, и затем
      удалял его опять, когда частичный файл удален.

      Если значение partial-dir не является абсолютным путем,
      rsync добавит правило исключения в конец всех ваших существующих исключений.
      Это предотвратит отправку любых partial-dir файлов, которые могут
      существовать с отправляющей стороны, и также предотвратит
      несоответствующее удаление partial-dir элементов на принимающей стороне.
      Пример: вышеуказанная опция --partial-dir добавила бы эквивалент "-f '-p
      .rsync-partial/'" в конец любых других правил фильтра.

По умолчанию rsync использует случайное временное имя файла, которое удаляется при неудаче передачи. Как упоминалось, используя --partial, вы можете заставить rsync сохранить неполный файл так, как будто он был успешно передан, чтобы затем можно было добавить к нему с помощью опций --append-verify/--append. Однако есть несколько причин, по которым это не оптимально.

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

  2. Если вы пытаетесь использовать --backup и --backup-dir, вы только что добавили новую версию этого файла, который никогда даже не существовал раньше, в вашу историю версий.

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

Возможно, вы захотите добавить опцию -P в вашу команду.

Из страницы man:

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

  -P     Опция -P эквивалентна --partial --progress. Это
         делает намного проще указать эти две опции для
         длинной передачи, которая может быть прервана.

Так что вместо этого:

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

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

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

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

Несколько важных правил:

  1. rsync использует алгоритм delta-xfer для определения, нужно ли повторно отправлять различающиеся блоки, за исключением, когда используется опция -W, --whole-file.
  2. rsync будет записывать данные во временную директорию и перемещать в назначение, когда процесс завершен, за исключением, когда используется опция --inplace.
  3. когда delta-xfer включен, если вы хотите избежать вычисления контрольной суммы блоков частично отправленных данных, вы можете добавить опцию --append, но одинаковость частично отправленных данных должна быть обеспечена вами самостоятельно.
  4. --append подразумевает --inplace, что само по себе подразумевает --partial

В моем случае я хотел отправлять инкрементальные файлы без значительной нагрузки на процессор и диск, команда следующая

rsync -avPL --inplace --append --bwlimit 30m -e 'ssh -o StrictHostKeyChecking=no' <src> <dst>

Кратко

Это возобновит частичные передачи и добавит сжатие для более быстрых передач

rsync --partial --progress --archive --compress --compress-choice=zstd --compress-level=9 --checksum-choice=xxh3 user@host:~/my_file.txt .

Объяснение флагов

--partial: Возобновление частичной передачи файла

--progress: Показ прогресса передачи и предполагаемого времени завершения

--archive: Сохранение атрибутов файла

--compress: Включение сжатия (по умолчанию zlib)

--compress-choice=zstd: Включение сжатия zstd (более быстрое и качественное сжатие, чем zlib)

--compress-level=9: Увеличение уровня сжатия с умолчания 3 (компромисс с максимальным уровнем 19)

--checksum-choice=xxh3: Использование xxh3 алгоритма хеширования (очень быстрый)

В моем случае rsync завершался и прекращал выполнение. В этом случае я использовал этот простой bash-скрипт while/do.

#!/bin/bash

source="/tmp/source" # Измените это!
destination="/tmp/destination" # Измените это!

while true
do
  if rsync -avz --partial $source $destination; then # SC2181
    echo "rsync завершен нормально"
    exit
  else
    echo "Сбой Rsync. Откат и повторная попытка через 180 секунд..."
    sleep 180
  fi
done

Перед запуском скрипта, вам нужно установить source и destination на значения по вашему выбору.

Я думаю, что вы принудительно вызываете 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

дайте мне знать, если есть какая-то ошибка в моем понимании этой концепции…

Для тех, кто использует GUI Grsync, соответствующая конфигурация следующая:

Во вкладке “Advanced options” отметьте (по крайней мере) флажок “Сохранять частично переданные файлы“.

Затем в поле “Дополнительные опции” введите:

--append-verify

Затем Файл -> Симуляция: чтобы проверить, сработает ли передача (если вы столкнетесь с ошибкой, возможно, вы захотите проверить выбраные другие опции, источник и цель).
И, наконец, Файл -> Выполнить.

С этой конфигурацией, если передача не удастся, вы можете просто закрыть окно передачи и Файл -> Выполнить снова. Это возобновит передачу с момента, на котором она была прервана.

Вы копируете между двумя локальными файловыми системами. Это отключает почти все оптимизации, предлагаемые rsync, и по умолчанию включается --wholefile. Кроме того, вы задействовали файловые системы NTFS, которые не обязательно сохраняют достаточно метаданных, которые rsync использует для проверки того, что файл был скопирован правильно.

Попробуйте так:

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

Здесь я использовал другой набор флагов:

  • Рекурсивно -r, потому что существует древовидная структура директорий, и нам нужно скопировать все это, а не только файлы верхнего уровня
  • Времена модификации -t для того, чтобы rsync мог сделать краткий перебор по размерам файлов и временам модификации, если его прервали и перезапустили
  • Подробно -v, чтобы вы могли видеть, что происходит (вы могли бы использовать -iv, если хотите немного больше информации, и/или --progress, если хотите видеть, что происходит в реальном времени)

Архив -a включает -r и -t, но он также включает больше метаданных, которые не могут надежно копироваться между NTFS файловыми системами. Между оригинальными Linux файловыми системами я обычно использую -a вместо -rt, но не между NTFS или другими не оригинальными файловыми системами.

Я намеренно упустил --partial, так как это не приносит пользы при копировании между двумя локально установленными файловыми системами. И использование --append, чтобы обойти это, создает потенциальную возможность незамеченной ошибки копирования, так как вы обходите еще больше возможностей rsync для выполнения надежных копий.

.

Ответ или решение

Теория: rsync — мощный инструмент для синхронизации и резервного копирования файлов. Одна из ключевых его способностей — передача только изменений между источником и приемником, что позволяет экономить трафик и снижать нагрузку на систему. rsync способен возобновлять прерванные передачи, но для этого необходимо правильно настроить его параметры.

Пример: Когда вы запускаете команду rsync для копирования большого количества файлов, и этот процесс неожиданно прерывается, например, из-за перезагрузки ОС, вы можете столкнуться с тем, что последующие запуски rsync вновь копируют все файлы с начала. Однако rsync обладает функциональностью, позволяющей избежать этого, например, использованием флагов --partial и --append-verify.

Практическое применение: Чтобы максимально эффективно использовать rsync для возобновления прерванных копирований, рекомендуется использовать несколько специфических флагов
в зависимости от сценария:

  1. --partial — сохраняет частично переданные файлы, которые не удаляются при прерывании передачи. При следующей попытке эти файлы могут быть доработаны с помощью --append или --append-verify.

  2. --append-verify — обеспечивает проверку уже скопированной части файла и продолжает с этой точки, предотвращая потенциальные ошибки в данных.

  3. --progress и -P — показывают прогресс передачи, что может быть полезно для больших файлов, так как вы можете видеть, насколько близки к завершению операции.

  4. --checksum — реализует механизм дельта-синхронизации для передачи только измененных блоков внутри файлов, однако это может значительно увеличить нагрузку на процессор, так как требует вычисления контрольных сумм.

В вашем случае, поскольку вы работаете с NTFS файловыми системами, стоит учесть, что rsync может не полностью поддерживать сохранение всех метаданных, что может повлиять на его способность определять уже скопированные файлы. Рекомендуется адаптировать команды для ваших конкретных условий:

sudo rsync -avzP --partial --append-verify /home/path/folder1/ /home/path/folder2

Эта команда помогает избежать повторного копирования уже частично перенесенных файлов и обеспечивает возобновление копирования в случае прерываний.

Оцените материал
Добавить комментарий

Капча загружается...