Czy rsync --inplace zapisuje w całym pliku, czy tylko w częściach wymagających aktualizacji? (dla kopii zapasowych btrfs + rsync)

21

Czytałem kilka przewodników, jak połączyć migawki btrfs z rsync, aby stworzyć wydajne rozwiązanie do tworzenia kopii zapasowych z historią. Wszystko zależy jednak rsync --inplaceod tego, czy zmodyfikuje tylko te fragmenty plików, które faktycznie się zmieniły, czy też nadpisuje cały plik sekwencyjnie. Jeśli zapisuje cały plik, wydaje się, że btrfs zawsze utworzy nową kopię pliku, co znacznie zmniejszy wydajność tego pomysłu.

Petr Pudlák
źródło
Skąd miałby wiedzieć, czy może uniknąć zapisu do całego pliku? Czy nie trzeba najpierw przeczytać całego pliku, aby dowiedzieć się, co się zmieniło?
Mehrdad
2
@ Mehrdad tak, tak, ale czytanie całości nie stanowi problemu. Jeśli rsyncczyta cały plik, a następnie szuka i aktualizuje tylko te potrzebne części, btrfs skopiuje tylko te zaktualizowane bloki. Ale jeśli rsyncczyta i zapisuje cały plik, to będzie problem.
Petr Pudlák
1
@ Mehrdad rsyncnie tylko wie, że może uniknąć zapisania całego pliku, ale udaje mu się to bez kopiowania go całkowicie przez sieć. Sprytny mały program.
Gunther Piez

Odpowiedzi:

31

Jeśli przekażesz rsync dwie ścieżki lokalne, domyślnie użyje „--hole-file”, a nie przeniesienia delta. To, czego szukasz, to „--no-cały plik”. Otrzymasz również transfer delta, jeśli poprosiłeś o „-c”.

Oto jak możesz zweryfikować:

$ 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

Następnie dotknij pliku i ponownie zsynchronizuj

$ 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

Możesz sprawdzić, czy ponownie użył i-węzła z „ls -li”, ale zauważ, że wysłał całe 64 KB. Spróbuj ponownie z --no-cały plik

$ 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

Teraz wysłałeś tylko 494 bajty. Możesz użyć strace do dalszej weryfikacji, czy któryś z plików został zapisany, ale pokazuje to przynajmniej użycie transferu delta.

Uwaga (patrz komentarze), że dla lokalnych systemów plików, --whole-filezakłada się (zobacz stronę podręcznika rsync). Z drugiej strony --no-whole-filezakłada się, że przez sieć , więc --inplacesama będzie się zachowywać jak --inplace --no-whole-file.

bez danych
źródło
Dlaczego to nie --inplacesugeruje --no-whole-file?
Geremia
Czy i tak nie jest --no-whole-filedomyślne?
Geremia
2
@ Geremia nie, jeśli obie ścieżki są lokalne. Mój przykład pokazuje, że --inplacenie oznacza --no-whole-fileto wersji rsync, z której korzystałem w 2013 roku, ale możesz powtórzyć ten eksperyment z własną wersją rsync.
danych
Cóż, inplacenie chodzi o „skanowanie w poszukiwaniu tych samych / różnych bloków”, chodzi o natychmiastowe zastąpienie istniejącego pliku od przesunięcia 0. (w przeciwnym razie tworzona jest kopia tymczasowa, a dopiero potem usuwany jest stary plik docelowy i nazwa tymczasowej kopii jest zmieniana) Prawdopodobnie uważa się za „bezpieczniejsze” przechowywanie starego pliku tak długo, jak to możliwe, jeśli proces zostanie przerwany. Oczywiście jest to gorsze ze względu na wydajność, szczytowe zużycie pamięci (pomyśl o dużych plikach), być może fragmentację ...) ...
Frank Nocke
1
Zakładałbym, że jest odwrotnie, --no-whole-filezawsze implikuje --inplace, w przeciwnym razie większość jego przyrostu wydajności zniknie. Nie udało się znaleźć tego udokumentowanego ...
Frank Nocke
15

Oto pewna ostateczna odpowiedź, podając poprawną część instrukcji:

   --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
źródło
4

--inplacezastępuje tylko zmienione regiony. Zawsze używaj go podczas pisania na Btrfs.

Gabriel
źródło
A czy masz dowody, które pokazują, że nie zastępuje innych części plików?
Petr Pudlák
Czy to samo dotyczy ZFS?
ewwhite
@ewwhite: Ponieważ ZFS jest COW (kopiowanie przy zapisie) jak BTRFS, więc tak.
Geremia
@ PetrPudlák -vvvpokazuje, że pomija dopasowane bloki
Tom Hale
3

Algorytm transferu delta rsync zajmuje się tym, czy przesyłany jest cały plik, czy tylko różne części. Jest to domyślne zachowanie podczas synchronizacji pliku między dwoma komputerami w celu zaoszczędzenia przepustowości. Można to zastąpić przyciskiem --whole-file(lub -W), aby wymusić rsyncprzesłanie całego pliku.

--inplacezajmuje się tym, czy rsyncpodczas przesyłania utworzy plik tymczasowy, czy nie. Domyślnym zachowaniem jest utworzenie pliku tymczasowego. Daje to pewien poziom bezpieczeństwa, ponieważ w przypadku przerwania przesyłania istniejący plik na komputerze docelowym pozostaje nienaruszony / nietknięty. --inplacezastępuje to zachowanie i nakazuje rsyncbezpośrednią aktualizację istniejącego pliku. Dzięki temu istnieje ryzyko, że plik na komputerze docelowym będzie niespójny, jeśli transfer zostanie przerwany.

Mike T.
źródło
2

Ze strony podręcznika:

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.

To prowadzi mnie do przekonania, że ​​zapisuje on plik w całości - wyobrażam sobie, że rsync działałby w inny sposób.

Laxsnor
źródło
2
Po ustaleniu, które części wymagają aktualizacji, może po prostu wyszukać te części i zaktualizować je zamiast pisać cały plik.
Petr Pudlák
0

Teoretyczna praca na miejscu rsync jest opisana w tym artykule .

Odniesienie do papieru: D. Rasch i R. Burns. In-Place Rsync: Synchronizacja plików dla urządzeń mobilnych i bezprzewodowych. Doroczna konferencja techniczna USENIX, tor FREENIX, 91-100, USENIX, 2003.

Z linku:

... Zmodyfikowaliśmy istniejącą implementację rsync w celu obsługi rekonstrukcji w miejscu.

Streszczenie: [...] Zmodyfikowaliśmy rsync, aby działał na urządzeniach o ograniczonej przestrzeni. Pliki na hoście docelowym są aktualizowane w tym samym magazynie, w którym znajduje się bieżąca wersja pliku. Urządzenia o ograniczonej przestrzeni nie mogą używać tradycyjnego rsync, ponieważ wymaga pamięci lub pamięci zarówno dla starej, jak i nowej wersji pliku. Przykłady obejmują synchronizację plików w telefonach komórkowych i komputerach przenośnych, które mają małe wspomnienia. Algorytm rsync w miejscu koduje skompresowaną reprezentację pliku na wykresie, który jest następnie sortowany topologicznie w celu uzyskania właściwości in-place. [...]

Wygląda to na szczegóły techniczne tego, co robi rsync --inplace. Według początku pracy:

Zmodyfikowaliśmy rsync, aby wykonywał zadania synchronizacji plików z rekonstrukcją na miejscu. [...] Zamiast używać przestrzeni tymczasowej, zmiany w pliku docelowym mają miejsce w przestrzeni już zajmowanej przez bieżącą wersję. Tego narzędzia można użyć do synchronizacji urządzeń o ograniczonej przestrzeni.

Jak wynika z odpowiedzi @ bez danych , oznacza to, że --inplaceużywa tej samej przestrzeni dyskowej, ale może nadal kopiować cały plik do tej przestrzeni. W szczególności, gdy kopie są tworzone z / do lokalnych systemów plików, rsync zakłada tę --whole-fileopcję. Z drugiej strony, gdy znajduje się w systemach sieciowych, przyjmuje taką --no-whole-fileopcję.

użytkownik92979
źródło
1
Um, więc jaka jest odpowiedź?
Xen2050
Przepraszam. Nie zwracałem wystarczającej uwagi. Z odpowiedzią @ bez danych powinno to wyjaśnić sprawę.
Przekątna