Man könnte denken, dass --link-dest
die 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/file
es wie die Quelle existiert und z/file
veraltet ist,
rsync -a --del -link-dest=y source:/file z
Dies führt dazu, dass ZWEI Inodes (und der doppelte Speicherplatz) verwendet werden y/file
und z/file
dieselben 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 newdir
wü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:
a
ist unsere Quelle, 1
durch 4
sind 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 -n
wechseln, 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 $today
auf 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.
--delete-after
in diesem Verwendungsszenario, was ist daran falsch?--delete-after
ist 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.rsnapshot
? Schreiben Sie auch ein kleines Skript, um "identische" Dateien erneut zu verknüpfen. Ich mache beides auf meinen Systemen.hardlink(1)
ist langsam (15x langsamer als der Metadaten-Scan von rsync);pax
ist schneller, schlägt aber HDD-Köpfe zusammen, wenn alte Backups mit neuen verglichen werden.rsync -n
Um 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.Antworten:
(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-dest
Verzeichnis durch eine fest verknüpfte Datei. Spart viel Platz.quelle