Wie kann rsync identische Dateien mit der Option --link-dest verknüpfen, wenn bereits eine alte Datei vorhanden ist?

11

Man könnte denken, dass --link-destdie Verwendung einer identischen Datei in allen Fällen funktionieren würde. Dies ist jedoch nicht der Fall, wenn die Datei vorhanden ist, auch wenn die Datei veraltet ist / einen anderen Inhalt hat.

Aus diesem Grund finden Sie auf der rsync-Manpage Folgendes --link-dest:

"Diese Option funktioniert am besten beim Kopieren in eine leere Zielhierarchie, da rsync vorhandene Dateien als endgültig behandelt ( rsync sucht also nie in den Link-Ziel-Verzeichnissen, wenn bereits eine Zieldatei vorhanden ist )."

Dies bedeutet, dass, wenn y/filees wie die Quelle existiert und z/fileveraltet ist,

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

Dies führt dazu, dass ZWEI Inodes (und der doppelte Speicherplatz) verwendet werden y/fileund z/filedieselben Inhalte und Datenstempel haben.

Ich bin darauf gestoßen, weil ich im Grunde genommen tägliche Backups mit diesem Skript mache, das einmal pro Tag ausgeführt wird:

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

Da meine Backups bis zu 10 Millionen Dateien umfassen, rm -rf $olddir; rsync source:$dir newdirwürde das Ausführen viel zu lange dauern (insbesondere wenn sich nur 0,5% der Dateien pro Tag ändern und 10 Millionen Verzeichniseinträge gelöscht und erstellt werden, nur um 50.000 neue oder geänderte Dateien zu verarbeiten, was meine Backups nicht rechtzeitig für den nächsten Tag abgeschlossen).

Hier ist eine Demo der Situation:

aist unsere Quelle, 1durch 4sind unsere nummerierten Backups:

$ 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

Jetzt haben wir 2 Backups a/foobar, die in jeder Hinsicht identisch sind, einschließlich Zeitstempel, aber unterschiedliche Inodes belegen.

Man könnte denken, eine Lösung wäre --delete-before, die den Vorteil des inkrementellen Scans zunichte macht, aber dies hilft auch nicht, da die Datei nicht gelöscht wird, sondern als Grundlage für den Fall verwendet wird, dass eine inkrementelle Kopie möglich ist.

Man könnte weiter vermuten, dass wir diese Absicherung gegen inkrementelle Kopien deaktivieren können --whole-file, aber dies hilft dem Algorithmus nicht weiter, es gibt keine Möglichkeit, das zu bekommen, was wir wollen.

Ich betrachte dieses Verhalten als einen weiteren Fehler in rsync, bei dem ein nützliches Verhalten durch sorgfältige Auswahl verschiedener Befehlsargumente konstruiert werden könnte, das gewünschte Ergebnis jedoch nicht verfügbar ist.

Eine Lösung wäre leider, von einem einzelnen rsync als atomare Operation zu einem Trockenlauf mit zu -nwechseln, ihn zu protokollieren, dieses Protokoll als Eingabe zu verarbeiten, um alle geänderten Dateien manuell vorab zu löschen, und dann auszuführen rsync --link-dest, um das zu erhalten, was wir wollen - ein großer Kludge im Vergleich zu einem einzelnen sauberen rsync.

Nachtrag: Es wurde versucht, vor dem Backup gegen Produktionsboxen eine Vorverknüpfung$yesterday und $todayauf dem Sicherungsserver durchzuführen, wobei rsync --link-dest=../$yesterday $yesterday/ $today- aber das gleiche Ergebnis - jede Datei, die in irgendeiner Weise vorhanden ist, auch keine Länge von 0, niemals entfernt und verknüpft wird, sondern als Ganzes Eine neue Kopie wird aus dem Sourcing-Verzeichnis mit einem neuen Inode erstellt und verbraucht mehr Speicherplatz.

Betrachtet pax(1)als mögliche Lösung für das Vorverknüpfen vor dem Sichern.

Mathematik
quelle
Ich verwende --delete-afterin diesem Verwendungsszenario, was ist daran falsch?
Gogoud
1
--delete-afterist in Ordnung, hat aber nichts mit dem vorliegenden Problem zu tun. In der Quelle fehlende Dateien werden nach dem Kopieren gelöscht. Das Problem, das ich erläutere, bezieht sich auf eine Sicherung, die heute durchgeführt wird und mit der von gestern identisch ist, jedoch mit einer alten vorhandenen veralteten Datei, die nicht mit dem gestrigen Inode verknüpft ist, sondern als neue Datei mit dem doppelten Speicherplatz von gestern gespeichert wird identische Kopie wird berücksichtigt.
Mathe
Ich bin mir nicht ganz sicher, was Sie fragen. Hast du darüber nachgedacht rsnapshot? Schreiben Sie auch ein kleines Skript, um "identische" Dateien erneut zu verknüpfen. Ich mache beides auf meinen Systemen.
Roaima
1
Wenn Sie hier nicht die Antwort erhalten, die Sie benötigen, können Sie auf der rsync-Liste posten. Die rsync-Entwickler beantworten dort regelmäßig Fragen zusammen mit vielen fortgeschrittenen Benutzern. Sie finden sie unter lists.samba.org/mailman/listinfo/rsync . Ich lauere meistens dort und lerne viel.
Joe
rsnapshot recycelt keine alten Backups - und ich muss: Wenn ich 2 Monate und 2 Monate + 1 Tag alte Backups habe, kann ich eines als neues Ziel einschalten. Da sich ~ 5% der Dateien pro Tag ändern, erstelle ich 50.000 Hardlinks anstelle von 10 Millionen. Dieser Geschwindigkeitsunterschied ermöglicht das Sichern von 5 Servern / Nacht gegenüber nicht. hardlink(1)ist langsam (15x langsamer als der Metadaten-Scan von rsync); paxist schneller, schlägt aber HDD-Köpfe zusammen, wenn alte Backups mit neuen verglichen werden. rsync -nUm die Delta-Liste zu erhalten, müssen die Produktionsserver zweimal aufgerufen werden (das Scannen von 10 Millionen Dateien ist weitaus wirkungsvoller als das Kopieren der 50.000 Änderungen). Ich sende die Liste über eine Option in rsync, um dies zu ermöglichen.
Mathe

Antworten:

12

(Konvertiert von Frage bearbeiten)

Dies wird durch ein Upgrade von rsync behoben. Version 3.1.1 oder höher ersetzt jetzt identische Dateien im Ziel und im --link-destVerzeichnis durch eine fest verknüpfte Datei. Spart viel Platz.

Michael Mrozek
quelle