Als Standardtool zur Datensynchronisation ist rsync hinlänglich bekannt. Doch rsync kann mehr als nur mit täglichen 1:1 Backups den Storage zu belasten. Über das Flag „–link-dest“ kann rsync auch inkrementelle Backups erstellen. Dabei macht es sich die Hardlink-Funktionalität des Dateisystems zu nutze und überträgt ausschließlich die Daten, die sich geändert haben, indem bereits gesicherte Daten nur „verlinkt“ werden.

Bereits auf dem Datenträger existierende Dateien nur zu verlinken, ist dabei keine Funktion von rsync, sondern die Basis dessen wie ein unix-artiges Dateisystem funktioniert. Die Position der Daten werden über so genannten Inodes festgehalten und ein Hardlink ist nichts anderes als der Dateipfad, der auf eine Inode verweist. Und das Schöne ist, dass wir unendlich viele Hardlinks auf eine Inode verweisen lassen können.

Die Basis bildet dabei das erste Vollbackup wie man es auch von der inkrementellen Backup-Software kennt:

backup_timestamp="$(date +%Y%m%d_%H%M%S)"
rsync -av --stats "${source_path}" "${backup_path}/${backup_timestamp}"

Bei allen folgenden Backups nutzen wir aber nun über „–link-dest“ das Backup des Vortages:

rsync -av --stats --delete --link-dest="${backup_path}/${last_backup}" "${source_path}"

Das Besondere ist nun, dass rsync erneut ein 1:1 Vollbackup erstellt, aber bereits existierende Dateien nur verlinkt. Anders als bei einem klassischen Vollbackup brauchen wir also für die Wiederherstellung das Backup vom Vortag gar nicht. Um genau zu sein benötigen wir keines der vorherigen Backups, denn sobald wir Backups löschen, löschen wir keine Inodes, sondern nur Hardlinks. Eine Datei ist also erst gelöscht, wenn ihr letzter Hardlink gelöscht wurde.

Da also jeder Dateipfad einem Hardlink entspricht und es dabei nicht mal wichtig ist ob es der erste oder 4. Link auf einen Inode ist, entspricht die Größe des Backups auch immer 1:1 die der Quelle:

du -h /mnt/backups/documents/20210901_044001
168G /mnt/backups/documents/20210901_044001

Möchte man dagegen mehrfache Hardlinks nicht mitzählen, muss man alle vorherigen Backups mit einbeziehen und damit ergäbe sich ein gänzlich anderes Bild:

du -d1 -h /mnt/backups/documents | sort -k2
168G /mnt/backups/documents/20210701_044001
14.2G /mnt/backups/documents/20210801_044001
3.8M /mnt/backups/documents/20210901_044001
497M /mnt/backups/documents/20211001_044001

Das Backup 20210901_044001 ist demnach nur 3.8MB groß, enthält aber trotzdem ein 1:1 Vollbackup und besitzt wie gesagt keine Abhängigkeiten zu anderen Backups. Hat man dieses Konzept erstmal verinnerlicht, merkt man wie komfortabel es im Vergleich zu anderen inkrementellen, aber auch differentiellen Sicherungen ist, die ohne die vorherigen Backups niemals wiederhergestellt werden können.

Wer Interesse an einem vollständigen Script hat, kann sich gerne meines anschauen, was sowohl auf unRAID als auch auf Synology getestet wurde.

6 Antworten

  1. Hallo,

    kann man das Skript auch für Backup auf einen entfernten Server via SSH nutzen?

    Wenn ich testweise für destination benutzer@:/Pfad/zum/Backupverzeichnis angebe, erhalte ich nach Passworteingabe

    rsync: mkdir „/Pfad/zum/Backupverzeichnis/link_dest“ failed: No such file or directory (2)
    rsync error: error in file IO (code 11) at main.c(875) [Receiver=3.0.7]
    rsync: connection unexpectedly closed (168 bytes received so far) [sender]
    rsync error: error in rsync protocol data stream (code 12) at io.c(231) [sender=3.2.7]

  2. Entschuldigung. Da war ein Schreibfehler den ich übersehen habe.
    Allerdings muss ich für den Durchlauf des Backups an schier unendlich vielen Stellen immer wieder das Benutzerpasswort eingeben.

    # user-defined rsync command
    #alias rsync=’sshpass -p „password“ rsync -e „ssh -o StrictHostKeyChecking=no“‚

    # user-defined ssh command
    #alias ssh=’sshpass -p „password“ ssh -o „StrictHostKeyChecking no“‚

    wenn ich hier # entferne und das Passwort eingebe, kommt „sshpass command not found!“

    Wie kann ich die vielfache Passworteingabe umgehen?

    1. Recherchiere mal wie man eine Authentifizierung per SSH Schlüssel einrichtet. Dann benötigst du kein Passwort. Ich empfehle außerdem, dass mein Skript von der Quelle rein lesend abholt. Dadurch erhöhst du die Sicherheit gegen Ransomware-Attacken, da niemals auf beiden Systemen Schreibrechte existieren.

  3. Vielen Dank.
    SSH-Key-Authentication nutze ich auf allen externen Servern, aber nicht auf dem NAS hier lokal. Da gab es bislang keine Notwendigkeit. Aber das wäre sicher ein Ansatz.
    Arbeitet dein Skript nicht immer nur in die Richtung, je nachdem, was man als Quelle und Ziel angibt? Oder wie meinst du „dass mein Skript von der Quelle rein lesend abholt“. Außerdem synct man ja im Falle von Ransomware-Befall immer die verschlüsselten Daten ins Backup, egal ob für die Quelle nur lesender Zugriff besteht oder nicht?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert