Записывает ли rsync --inplace весь файл или только те части, которые необходимо обновить? (для резервных копий btrfs + rsync)

21

Я читал несколько руководств о том, как объединить снимки btrfs с rsync, чтобы создать эффективное решение для резервного копирования с историей. Однако все зависит от того, rsync --inplaceизменяет ли только те части файлов, которые действительно изменились, или последовательно перезаписывает весь файл. Если он записывает весь файл, то кажется, что btrfs всегда будет создавать новую копию файла, что сделает идею гораздо менее эффективной.

Петр Пудлак
источник
Как он узнает, сможет ли он избежать записи во весь файл? Не нужно ли сначала прочитать весь файл, чтобы выяснить, что изменилось?
Мердад
2
@ Mehrdad да, это так, но чтение целого не проблема. Если rsyncчитает весь файл, а затем ищет и обновляет только те части, которые необходимы, btrfs скопирует только эти обновленные блоки. Но если rsyncчитает и пишет весь файл, то это будет проблемой.
Петр Пудлак
1
@Mehrdad rsyncне только знает, что может избежать записи всего файла, но и делает это, не копируя его полностью по сети. Умная маленькая программа.
Гюнтер Пьез

Ответы:

31

Если вы передадите rsync два локальных пути, по умолчанию будет использоваться «--whole-file», а не delta-Transfer. Итак, вы ищете "--no-whole-file". Вы также получаете дельта-перевод, если вы запросили '-c'.

Вот как вы можете проверить:

$ mkdir a b
$ dd if=/dev/zero of=a/1 bs=1k count=64
$ dd if=/dev/zero of=a/2 bs=1k count=64
$ dd if=/dev/zero of=a/3 bs=1k count=64
$ rsync -av a/ b/
sending incremental file list
./
1
2
3

sent 196831 bytes  received 72 bytes  393806.00 bytes/sec
total size is 196608  speedup is 1.00

Затем коснитесь файла и повторите синхронизацию.

$ touch a/1
$ rsync -av --inplace a/ b/
sending incremental file list
1

sent 65662 bytes  received 31 bytes  131386.00 bytes/sec
total size is 196608  speedup is 2.99

Вы можете убедиться, что он повторно использовал индекс с помощью «ls -li», но обратите внимание, что он отправил целые 64 Кбайт. Попробуйте еще раз с --no-whole-file

$ touch a/1
$ rsync -av --inplace --no-whole-file a/ b/
sending incremental file list
1

sent 494 bytes  received 595 bytes  2178.00 bytes/sec
total size is 196608  speedup is 180.54

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

Обратите внимание (см. Комментарии), что для локальных файловых систем --whole-fileпредполагается (см. Справочную страницу для rsync). С другой стороны, через сеть --no-whole-fileпредполагается, что само --inplaceпо себе будет вести себя как --inplace --no-whole-file.

без данных
источник
Почему не --inplaceподразумевает --no-whole-file?
Геремия,
В --no-whole-fileлюбом случае не по умолчанию?
Геремия,
2
@ Geremia нет, если оба пути являются локальными. И мой пример показывает, что --inplaceэто не --no-whole-fileотносится к версии rsync, которую я использовал в 2013 году, но вы можете повторить этот эксперимент со своей версией rsync.
без данных
Ну, inplaceречь идет не о «сканировании одинаковых / отличающихся блоков», а о перезаписи существующего файла сразу, со смещения 0. (В противном случае создается временная копия, и только затем удаляется старый целевой файл, а временная копия переименовывается. Вероятно, считается более безопасным сохранять старый файл как можно дольше, если процесс прерывается. Конечно, это ухудшает производительность, пиковое потребление памяти (например, большие файлы), возможно фрагментацию ...) ...
Фрэнк Нок
1
Я бы предположил, что это наоборот, --no-whole-fileвсегда подразумевает --inplace, иначе большая часть прироста производительности исчезла бы. Не могу найти это документально, хотя ...
Фрэнк
15

Вот определенный ответ, наверное, со ссылкой на правильную часть руководства:

   --inplace

          [...]

          This option is useful for transferring large files
          with  block-based  changes  or  appended data, and
          also on systems that are disk bound,  not  network
          bound.   It  can  also  help  keep a copy-on-write
                                               *************
          filesystem snapshot from diverging the entire con‐
          *******************
          tents of a file that only has minor changes.
fuujuhi
источник
4

--inplaceПерезаписывает только те регионы, которые изменились. Всегда используйте его при записи в Btrfs.

Габриель
источник
И есть ли у вас доказательства того, что он не перезаписывает другие части файлов?
Петр Пудлак
Относится ли это к ZFS?
ewwhite
@ewwhite: поскольку ZFS - это COW (копирование при записи), как BTRFS, то да.
Геремия,
@ PetrPudlák -vvvпоказывает, что он пропускает подходящие блоки
Том Хейл,
3

Алгоритм дельта-передачи rsync определяет, передается ли весь файл или только части, которые отличаются. Это стандартное поведение при rsyncing файла между двумя машинами для экономии пропускной способности. Это можно переопределить с помощью --whole-file(или -W), чтобы принудительно rsyncпередать весь файл.

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

Майк Т.
источник
2

Со страницы руководства:

This  option  changes  how  rsync transfers a file when its data
needs to be updated: instead of the default method of creating a
new  copy  of  the file and moving it into place when it is com-
plete, rsync instead writes the updated  data  directly  to  the
destination file.

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

Laxsnor
источник
2
Определив, какие части нужно обновить, он может просто искать эти части и обновлять их, а не записывать весь файл.
Петр Пудлак
0

Теоретическая работа по rsync на месте описана в этой статье .

Ссылка на документ: Д. Раш и Р. Бернс. Rsync на месте: синхронизация файлов для мобильных и беспроводных устройств. Ежегодная техническая конференция USENIX, трек FREENIX, 91-100, USENIX, 2003.

По ссылке:

... Мы изменили существующую реализацию rsync для поддержки реконструкции на месте.

Аннотация: [...] Мы изменили rsync так, чтобы он работал на устройствах с ограниченным пространством. Файлы на целевом хосте обновляются в том же хранилище, которое занимает текущая версия файла. Устройства с ограниченным пространством не могут использовать традиционный rsync, поскольку для этого требуется память или хранилище как для старой, так и для новой версии файла. Примеры включают синхронизацию файлов на сотовых телефонах и портативных ПК, которые имеют небольшую память. Алгоритм rsync на месте кодирует сжатое представление файла в графе, который затем топологически сортируется для получения свойства на месте. [...]

Так что это технические детали того, что делает rsync --inplace. Согласно началу статьи:

Мы изменили rsync, чтобы он выполнял задачи синхронизации файлов с восстановлением на месте. [...] Вместо использования временного пространства, изменения в целевом файле происходят в пространстве, уже занятом текущей версией. Этот инструмент можно использовать для синхронизации устройств с ограниченным пространством.

Как становится ясно из ответа @ dataless , это означает, что --inplaceиспользуется то же пространство памяти, но оно все равно может копировать весь файл в это пространство. В частности, когда копии делаются из / в локальные файловые системы, rsync принимает эту --whole-fileопцию. Но с другой стороны, когда он подключен к сетевым системам, он принимает такую --no-whole-fileвозможность.

user92979
источник
1
Ну, каков ответ?
Xen2050
Мои извенения. Я не уделял достаточного внимания. С ответом @ dataless это должно прояснить ситуацию.
Косой