Windows Backup Teil 4b/4: Workaround zum Datenhandling beim Kopieren.

Mit reichlich Frust, verstörten Entzücken und verwirrter Fassungslosigkeit ging es, nach dem abrupten FAIL im letzten Blogeintrag, an die Lösung. Ich kam auch schnell auf 3 Lösungen – aber eine wollte ich nicht und die andere erwies sich als Fehleranfällig. Aber lest selbst.

In meinem ersten Frust suchte ich erst einmal den Grund des „Fehlverhaltens“. Die erste Vermutung, dass es sich um ein Problem des Filesystems handelte, zerschlug ein Test mit „Rsync für Windows“.
Und um Nörgler zu beruhigen: Die Power Shell zeigte bei den Lösungsversuchen ebenfalls ihr komplettes Potential – aber es sollte ja in der Konsole laufen. Also wurde die Power Shell erstmal auf Eis gelegt.

Lösungswege:

Lösung Nr. 1: „Rsync für Windows“
„Rsync für Windows“ funktioniert wie erwartet. Es löscht tatsächlich die zu ersetzende Datei im Ziel-Laufwerk und löst somit alle Hardlink-Bezüge auf und kopiert dann die Datei als eingeständen Datenbestand.
Das Problem – es ist eine Zusatzinstallation und die wollte ich ja vermeiden.
Also – DROP.

Lösung Nr. 2 (war der Grundstock für Lösung Nr. 3): Dateien löschen und neu kopieren (robocopy)
Lösung Nr. 2 begann mit der Erstellung einer Differenz-Datei-Liste und dem Löschen der Dateien aus dieser Liste im Ziellaufwerk.
Dadurch werden auch die Abhängigkeiten der Hardlinks aufgebrochen.
Danach sollte mit robocopy eine erneute Synchronisation ausgeführt werden.
Klingt einfach, hat aber auch schon gleich wieder ein neues Problem (und etliche weitere Nagespuren in der Tischplatte) .
Da das Erstellen der Differenz-Dateiliste und die Synchronisation zu unterschiedlichen Zeitpunkten ausgeführt werden, kann auch der Datenbestand der beiden Aktionen unterschiedlich sein. Somit könnten bei der Synchronisierung wiederum, zwischenzeitlich geänderte, Dateien aktualisiert werden – mit samt den dazugehörigen Hardlinks. (ARRRGGGHHHH!!)

Lösung Nr. 3: robocopyfindstringdeletexcopy-Combo
Im Grunde ist der Ablauf analog zur Lösung Nr. 2, jedoch wird hier die erzeugt Differenz-Datei-Liste auch zum Kopieren der Dateien benutzt. Und somit wird für das Löschen und Kopieren der Dateien der gleiche Bestand herangezogen und es sollte keine unerwarteten Probleme geben.

Also auf geht’s.

Umsetzung

Ausgangssituation:
Die erste Synchronisation und die Hardlinks dafür wurden bereits ausgeführt.
winback4b-01
Jetzt haben sich Dateien im Quell-Laufwerk geändert und eine neue Synchronisation und das Erstellen von Hardlinks steht an.

Schritt 1: Erzeugen der Differenz-Datei-Liste
Zum Erstellen der Differenz-Datei-Liste nutze ich Robocopy ohne Aktion

Wichtig sind hier die Parameter zum Formatieren der Ausgabe. Ich unterbinde alle Ausgaben, bis auf die Ausgabe der Dateinamen (Ausgabe erfolgt mit absolutem Pfad). Auf den Parameter –V verzichte ich, damit sich die Ausgabe nur auf die geänderten Dateien bezieht. Wichtig ist hier auch der Parameter /L (List only), wodurch keine Aktion ausgeführt wird. Die Ausgabe erfolgt in die Datei robo.txt im Temp-Verzeichnis (Umgebungsvariable %tmp%)
Wichtig ist jetzt auch zu wissen, dass in diesem Log-File alle geänderten Dateien vorhanden sind, auch die Neuen(!!) Dateien im Quellverzeichnis. Deshalb kann man diese Liste nicht einfach Zeile für Zeile abarbeiten, denn sonst würden auch alle Dateien im Quell-Laufwerk gelöscht werden, bevor man sie sichert.

Schritt 2: Dateien löschen
Deshalb ersetze ich in meinem Skript in jeder Zeile den String „C:\Quell-LW\“ durch „D:\Ziel-LW\orig“.
Beim Löschen überprüfe ich dann mit „if exist“, ob die Datei auch im Ziel-LW vorhanden ist und erst dann lösche ich diese.
Der del –Befehl löscht die Dateien, der rd-Befehl die Verzeichnisse. Eigentlich sollte es auch nur mit rd funktionieren, da hatte ich aber das „Das Verzeichnis ist nicht leer“-Problem, weshalb ich hier die Holzhammermethode im Doppelpack nutze.

Schritt 3: Kopieren der Dateien
Jetzt überarbeite ich das Log-File ein weiteres Mal, in dem ich alle Zeilen, in denen das Quell-Laufwerk vorkommt, in ein weiteres File übertrage, welches dann die Grundlage für das Kopieren der Dateien wird.

Zum Kopieren in das Ziel-Laufwerk\orig nutze ich xcopy, da ich hier als Ziel Pfade angeben kann, welche evtl. gar nicht existieren. Diese werden dann von xcopy einfach angelegt.

Schritt 4: Erzeugen der Hardlinks
Jetzt sind die Dateien zwischen Quell- und Ziel-Laufwerk synchron und ich erzeuge im Ziel-Laufwerk, unter „archiv\“, die aktuelle Verzeichnisstruktur für die Hardlinks.
Zum Einsatz kommt wieder Robocopy mit den Parameter /MIR und /XF (exclude File) *.* (es werden nur die Ordner kopiert und keine Dateien.

Und jetzt kommt wieder das Skript zum Erzeugen der Hardlinks

Schritt 5: Bereinigen des Archiv-Verzeichnisses
Am Ende nutze ich eine kleine Routine, um die Anzahl der Backups im Archivordner auf eine bestimmte Menge zu begrenzen (in diesem Beispiel sollen 5 Versionen erhalten bleiben)

Erstaunlich, es funktioniert.
Ergebnis:
winback4b-03
Und der Beweis:
winback4b-04

Das fertige Skript

Also das Ganze in ein zusammenhängendes Skript (und die Pfadangaben in Variablen) packen:

Fertig:
Und es funktioniert sogar.

Das Skript ist natürlich sehr rudimentär und es fehlen vorwiegend Sicherheitsabfragen.
So sollte z.B.: nach dem Erstellen der Verzeichnisstruktur diese auch mit „if exist“ überprüft werden.
Da ich bei der Erstellung der Differenzliste mit der Holzhammermethode vorgehe, erzeugen die Delete-Befehle Fehler, wodurch ein abfragen auf eine positive Ausführung nicht möglich ist.
Hier könnte man in die Ausgabe der Differenz-Datei-Liste auch Pfade mit aufnehmen (weglassen des Parameters /NDL). Diese könnten dann ebenfalls über eine „if exist“ Abfrage aussortiert werden, in dem man den String z.B.: nach einer Extension (%%~xi) durchsucht und bei Vorhandensein den „del“-Befehl, bei nicht Vorhandensein den „rd“-Befehl ausführt.

Ihr seht, das Skript bietet noch viel Potential zur Weiterentwicklung.
Grundsätzlich habe ich aber das erreicht was ich wollte. Ich habe Befehle, Abläufe und das Verhalten von Windows wieder ein ganzes Stück besser kennen gelernt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

17 − vierzehn =