jak zmusić rsync do łączenia identycznych plików z opcją --link-dest, jeśli stary plik już istnieje?


11

Można by pomyśleć, że --link-destznalezienie identycznego pliku zadziałałoby we wszystkich przypadkach. Ale nie dzieje się tak, gdy plik istnieje, nawet jeśli plik jest nieaktualny / ma inną zawartość.

To z tego powodu ze strony podręcznika rsync na --link-dest:

„Ta opcja działa najlepiej podczas kopiowania do pustej hierarchii docelowej, ponieważ rsync traktuje istniejące pliki jako ostateczne (więc rsync nigdy nie szuka w katalogach link-dest, gdy plik docelowy już istnieje )”

Oznacza to, że jeśli y/fileistnieje to samo co źródło i z/filejest nieaktualne,

rsync -a --del -link-dest=y source:/file z

spowoduje użycie DWÓCH i-węzłów (i dwa razy więcej miejsca na dysku) y/filei z/file, które będą miały tę samą zawartość i znaczniki danych.

Natknąłem się na to, ponieważ wykonuję codzienne kopie zapasowe w zasadzie z tym skryptem uruchamianym raz dziennie:

mv $somedaysago $today; 
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today

Ponieważ moje kopie zapasowe obejmują do 10 milionów plików, robienie rm -rf $olddir; rsync source:$dir newdirtego zajęłoby o wiele za dużo czasu (szczególnie, gdy zmienia się tylko 0,5% plików dziennie, powodując usunięcie i utworzenie wpisów 10 milionów katalogów tylko do obsługi 50 tysięcy nowych lub zmienionych plików, co spowodowałoby, że moje kopie zapasowe nie zostały ukończone na następny dzień).

Oto demo sytuacji:

ajest naszym źródłem, 1poprzez 4nasze numerowane kopie zapasowe:

$ mkdir -p 1 2; echo foo > 1/foobar; cp -lrv 1/* 2
`1/foobar' -> `2/foobar'
$ ls -i1 */foobar
1053003 1/foobar
1053003 2/foobar

$ mkdir a; echo quux > a/foobar
$ mv 1 3; rsync -avPhyH --del --link-dest=../2 a/ 3
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04

$ ls -i1 */foobar
1053003 2/foobar
1053007 3/foobar
1053006 a/foobar

$ mv 2 4; rsync -avPhyH --del --link-dest=../3 a/ 4
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04


$ ls -il1 */foobar
1053007 -rw-r--r-- 1 math math 5 Mar 30 00:57 3/foobar
1053008 -rw-r--r-- 1 math math 5 Mar 30 00:57 4/foobar
1053006 -rw-r--r-- 1 math math 5 Mar 30 00:57 a/foobar

$ md5sum [34a]/foobar
d3b07a382ec010c01889250fce66fb13  3/foobar
d3b07a382ec010c01889250fce66fb13  4/foobar
d3b07a382ec010c01889250fce66fb13  a/foobar

Teraz mamy 2 kopie zapasowe, a/foobarktóre są identyczne pod każdym względem, w tym znacznik czasu, ale zajmują różne i-węzły.

Można by pomyśleć, że byłoby rozwiązanie --delete-before, które zabija korzyść ze skanowania przyrostowego, ale to też nie pomaga, ponieważ plik nie zostanie usunięty, ale zostanie użyty jako podstawa w przypadku, gdy możliwe jest kopiowanie przyrostowe.

Można jeszcze przypuszczać, że możemy wyłączyć ten żywopłot z kopią przyrostową --whole-file, ale to nie pomaga algorytmowi, nie ma sposobu na uzyskanie tego, czego chcemy.

Uważam to zachowanie za kolejny błąd w rsync, w którym korzystne zachowanie można interpretować na podstawie starannego wyboru różnych argumentów poleceń, ale pożądany wynik nie jest dostępny.

Rozwiązaniem byłoby niestety być w ruchu z jednego rsync jako operacja atomowa na sucho z -n, zalogowaniu się, że przetwarzanie dziennika jako wkład do wstępnie ręcznie usunąć wszystkie zmienione pliki, a następnie uruchomiony rsync --link-dest, aby dostać to, co chcemy - duży kludge w porównaniu do pojedynczego czystego rsync.

Dodatek: próbowano wstępnie połączyć $yesterdayi $todayna serwerze kopii zapasowej przed utworzeniem kopii zapasowej w skrzynkach produkcyjnych z rsync --link-dest=../$yesterday $yesterday/ $today- ale z takim samym rezultatem - każdy plik, który istnieje w jakikolwiek sposób, nawet o długości 0, nigdy nie zostanie usunięty i przeznaczony dla łącza, zamiast całego nowa kopia zostanie utworzona z sourcedir z nowym i-węzłem i zajmuje więcej miejsca na dysku.

Patrząc na pax(1)możliwe rozwiązanie poprzedzające tworzenie kopii zapasowych.


Używam --delete-afterw tym scenariuszu użytkowania, co jest z tym nie tak?
gogoud

1
--delete-afterjest w porządku, ale nie ma związku z danym problemem. Pliki brakujące w źródle zostaną usunięte po zakończeniu kopiowania. Problem, który wyjaśniam, dotyczy tworzenia kopii zapasowej dzisiaj, która jest identyczna z wczorajszą, ale w stosunku do starego istniejącego nieaktualnego pliku, który nie jest połączony z wczorajszym i-węzłem, ale jest przechowywany jako nowy plik o łącznej powierzchni dwa razy większej niż wczoraj rozważana jest identyczna kopia.
matematyka

Nie do końca pewne, o co pytasz. Czy zastanawiałeś się rsnapshot? Rozważ też napisanie małego skryptu, aby ponownie połączyć „identyczne” pliki. Robię oba na moich systemach.
roaima,

1
Jeśli nie znajdziesz tutaj potrzebnej odpowiedzi, możesz opublikować post na liście rsync. Programiści rsync regularnie odpowiadają tam na pytania wraz z wieloma zaawansowanymi użytkownikami. Można je znaleźć na lists.samba.org/mailman/listinfo/rsync . Przeważnie czaję się tam i dużo się uczę.
Joe

rsnapshot nie przetworzy starych kopii zapasowych - i muszę: jeśli mam kopie zapasowe 2 miesiące i 2 miesiące + 1 dzień, mogę włączyć jedną z nich jako nowy cel. Ponieważ ~ 5% plików zmienia się dziennie, tworzę twarde linki 50 000 zamiast 10 mln. Ta różnica prędkości pozwala wykonać kopię zapasową 5 serwerów / noc vs nie. hardlink(1)jest wolny (15x wolniejszy niż skanowanie metadanych rsync); paxjest szybszy, ale przebija głowice dysków twardych, porównując starą kopię zapasową z nową. rsync -nuzyskanie listy delta oznacza dwukrotne uderzenie w serwery produkcyjne (skanowanie plików 10M ma o wiele większy wpływ niż kopiowanie zmian 50K). Zle wyslam list o opcji w rsync, zezwalajac na to.
matematyka

Odpowiedzi:


12

(Przekonwertowane z edycji pytania)

Rozwiązano to poprzez aktualizację rsync. Wersja 3.1.1 lub nowsza zastąpi teraz identyczne pliki w katalogu docelowym i --link-destkatalogu jednym plikiem z dowiązaniem twardym. Oszczędza dużo miejsca.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.