Ein Backup-Konzept mit Hardlinks und rsync

Da es für mich keine passende Backup-Lösung gab, habe ich mir diese selber geschrieben. Meine Daten werden jetzt per rsync auf meinen Backup-Server synchronisiert. Für meine Backup-Lösung braucht man nicht zwingend einen Backup-Server. Mit rsync kann man auch auf dem lokalen Rechner Dateien und Verzeichnisse synchronisieren.

Das tolle an meinem Skript ist, dass ich verschiedene Versionen von meinen Daten habe. Wenn ich eine Datei lösche und dann mein Backup starte, wird diese Datei auf dem Backup-Server nicht gelöscht! Dies geschieht mit Hardlinks. Das geniale daran ist, dass nur die neuen Daten neuen Platz auf der Harddisk beanspruchen. Obwohl ich über 10 mal die selbe Datei gesichert habe, wird deren Speicherplatz nur einmal belegt.

Voraussetzung

Meine Backuplösung basiert auf diversen Bash-Skripten. Diese müssen mit den nötigen Rechten ausgeführt werden können. Will man die Daten auf einen Server sichern, benötigt man dort ein SSH-Login. Am einfachsten geht dies mit Public-/Private-Keys, damit man nicht jedes mal ein Passwort eingeben muss.
Als Client benutze ich mein Lenovo Thinkpad T61 Notebook und mein Asus EEEPC 1000H Netbook, welche beide mit Arch Linux laufen. Bei meinem Backup-Server handelt es sich um eine Asus EEEBOX, welche mit Debian 5.0 läuft. Das Backup-Skript sollte jedoch auf jedem Linux lauffähig sein.

Übersicht
Hier eine kleine übersicht über mein Backup-Konzept:

Backup-Konzept
Backup-Konzept

Komponenten

Mein Backup-Script benötigt folgende Komponenten:

  • install: Installiert die Verzeichnisstruktur für die Backups auf dem Server/Computer
  • crontab: Die Einträge in der Crontab rufen das Backup-Script auf dem Server auf. Dies kann aber auch manuell gemacht werden.
  • backup: Dieses Skript kopiert die Backup Ordner und ermöglicht so eine Versionierung
  • syncup: Mit diesem Skript werden meine Daten auf den Server synchronisiert
  • syncup.conf: Wird syncup ohne Parameter aufgerufen, werden die in dieser Datei angegebenen Dateien und Verzeichnisse gesichert.

Installation

Das Installationsskript install erstellt folgende Ordner:

  • backupdata: Hier werden die zu sichernden Daten abgespeichert
  • daily_1 bis daily_7: Eine Version der Daten von den letzten sieben Tagen
  • weekly_1 bis weekly_4: Eine Version der Daten von den letzten vier Wochen
  • monthly_1 bis monthly_12: Eine Version der Daten von den letzten zwölf Monaten
  • yearly_1 bis yearly_5: Eine Version der Daten von den letzten fünf Halbjahren

Folgendes Skript erstellt mir die Ordnerstruktur:

#!/bin/bash
################################################################
#
# install
# Erstellt die Verzeichnisse fuer backup
#
# Copyright 2010 Emanuel Duss
# Licensed under GNU General Public License
#
# 2009-12-05; Emanuel Duss; Erste Version
#
################################################################

################################################################
# Main
cd /media/backup/backup/

# Ordner fuer die Synchronisation
mkdir backupdata

# Ordner fuer taegliche Backups
for i in `seq 1 7`
do
  mkdir daily_$i
done

# Ordner fuer woechentliche Backups
for i in `seq 1 4`
do
  mkdir weekly_$i
done

# Ordner fuer monatliche Backups
for i in `seq 1 12`
do
  mkdir monthly_$i
done

# Ordner fuer halbjaehrliche Backups
for i in `seq 1 5`
do
  mkdir yearly_$i
done

# EOF

Synchronisation

Das Skript syncup synchronisiert die als Parameter angegebene Verzeichnisse und Dateien auf meinen Backup-Server. Werden keine Parameter angegeben, werden die Dateien und Verzeichnisse aus dem Konfigurationsfile syncup.conf gesichert. Will man keinen Backup-Server nutzen, sondern eine lokale Sicherung durchführen (z. B. auf eine externe Festplatte), lässt man bei der Variable BACKUPPATH den Hostnamen weg.

#!/bin/bash
################################################################
#
# syncup
# Synrchonisiert die Backup-Daten
#
# Copyright 2009 Emanuel Duss
# Licensed under GNU General Public License
#
# 2009-12-07; Emanuel Duss; Erster Entwurf
# 2009-12-15; Emanuel Duss; Erste produktive Version
# 2010-01-17; Emanuel Duss; rsync --progress
# 2010-09-14; Emanuel Duss; $BACKUPSRV, prepare () für mount
# 2010-10-06; Emanuel Duss; rycnc -h (Human)
# 2010-11-25; Emanuel Duss; Nutze Parameter als Quellverzeichnis
# 2010-11-27; Emanuel Duss; Mehrere Verzeichnisse und Konfigfile
#
################################################################

################################################################
# Variabeln
TIMESTAMP="`date +%Y-%m-%d_%H-%M-%S`"
HOSTNAME="`uname -n`"

RSYNC="/usr/bin/rsync"
RSYNC_PARAMETER="-avhz --progress --delete"

BACKUPSRV="emanuel@eeebox"
BACKUPPATH="$BACKUPSRV:/media/backup/backup/backupdata/$HOSTNAME/"

CONFIGFILE="`dirname $0`/syncup.conf"

################################################################
# Main

# Lege die zu sichernden Files fest
if [ -n "$*" ]
then
  SOURCE=`echo $* | awk '{ gsub("/ "," "); gsub("/$",""); print }'`
elif [ -e "$CONFIGFILE" ]
then
  echo "Konfigurationsfile: $CONFIGFILE"
  SOURCE=`grep -E "^[^#]" $CONFIGFILE | tr "\n" " " | awk '{ gsub("/ "," "); gsub("/$",""); print }'`
else
  echo "Usage:"
  echo "syncup [ Verzeichnisse und Dateien ]"
  echo ""
  echo "Wird kein Parameter angegeben, wird das Konfigfile $CONFIGFILE verwendet."
  exit 1
fi

# Info ausgeben
echo
echo "Source: $SOURCE"
echo "Target: $BACKUPPATH"
echo

# Backup-HD mounten
ssh $BACKUPSRV "sudo mount /media/backup"

# Dateien synchronisieren
$RSYNC $RSYNC_PARAMETER $SOURCE $BACKUPPATH

# Backup-HD umounten
ssh $BACKUPSRV "sudo umount /media/backup"

# EOF

Entweder wird das Skript direkt mit ./syncup im aktuellen Verzeichnis aufgerufen, oder man platziert es in einen Ordner, der in der $PATH-Variable eingetragen ist (z. B. /usr/local/bin). Jetzt kann dieses Skript in der Konsole aufgerufen werden:

emanuel@discordia:~
$ sudo syncup Daten/ /etc/ /var/www
Source: /etc
Target: emanuel@eeebox:/media/backup/backup/backupdata/discordia/

sending incremental file list
etc/openvpn/client.conf
         880 100%  175.78kB/s    0:00:00 (xfer#1, to-check=539/1389)

sent 47.16K bytes  received 219 bytes  31.59K bytes/sec
total size is 6.02M  speedup is 127.00

Ich muss das Skript mit den nötigen Rechten aufrufen. Das Verzeichnis /etc ist nur durch den User root vollständig lesbar. Deshalb rief ich das Skript mit sudo auf. Für eigene Verzeichnisse ist dies nicht nötig.
Die Daten befinden sich jetzt im Ordner backupdata auf dem Backup-Server.

Das File syncup.conf sieht folgendermassen aus:

################################################################
#
# syncup.conf
# Konfigurationsdatei fuer syncup
#
# Copyright 2010 Emanuel Duss
# Licensed under GNU General Public License
#
# 2010-11-27; Emanuel Duss; Erste Version
#
################################################################

# Verzeichnisse
/home/emanuel/Daten
/home/emanuel/.config
/home/emanuel/.filezilla
/home/emanuel/.ssh
/home/emanuel/.vim

# Files
/home/emanuel/.conkyrc
/home/emanuel/.bashrc
/home/emanuel/.exrc
/home/emanuel/.fehrc
/home/emanuel/.history
/home/emanuel/.muttrc
/home/emanuel/.screenrc
/home/emanuel/.vimrc
/home/emanuel/.vimperatorrc
/home/emanuel/.xinitrc
/home/emanuel/.Xdefaults
/home/emanuel/.smbcredentials*

# Systemdaten
/etc

#EOF

Wenn syncup ohne Parameter aufgerufen wird, werden alle Dateien und Verzeichnisse aus diesem Konfigurationsfile gesichert:

emanuel@discordia:~
$ sudo syncup
Konfigurationsfile: /home/emanuel/Daten/Scripts/syncup.conf

Source: /home/emanuel/Daten /home/emanuel/.config /home/emanuel/.filezilla
/home/emanuel/.ssh /home/emanuel/.vim /home/emanuel/.conkyrc /home/emanuel/.bashrc
/home/emanuel/.exrc /home/emanuel/.fehrc /home/emanuel/.history /home/emanuel/.muttrc
/home/emanuel/.screenrc /home/emanuel/.vimrc /home/emanuel/.vimperatorrc
/home/emanuel/.xinitrc /home/emanuel/.Xdefaults /home/emanuel/.smbcredentials* /etc
Target: emanuel@eeebox:/media/backup/backup/backupdata/discordia/

sending incremental file list
etc/openvpn/up.sh
         453 100%    0.00kB/s    0:00:00 (xfer#1, to-check=540/393538)

sent 6.34M bytes  received 32.75K bytes  296.59K bytes/sec
total size is 73.20G  speedup is 11479.75

Backup
Die Daten wurden erst auf den Server synchronisiert. Wenn man eine Datei auf der Workstation löschen würde, dann wäre diese bei der nächsten Synchronisation ebenfalls gelöscht. Darum erstelle ich pro Tag, Woche, Monat und Halbjahr eine Kopie aller Daten. Dies erledigt mein Backup-Server. Da ich hierfür Hardlinks verwende, wird bei jeder Kopie kein weiterer Speicherplatz beansprucht. Lediglich neue Daten beanspruchen neuen Speicherplatz. Das ist genial!

Das Backup-Skript sieht folgendermassen aus:

#!/bin/bash
################################################################
#
# backup
# Backup mit Hardlinks
#
# Copyright 2009 Emanuel Duss
# Licensed under GNU General Public License
#
# 2009-10-22; Emanuel Duss; Erster Entwurf
# 2009-12-05; Emanuel Duss; Erste produktive Version
# 2010-04-27; Emanuel Duss; Logfile in /var/log
#
################################################################

################################################################
# Variabeln
BACKUPDIR=/media/backup/backup
LOGFILE=/var/log/backup.log
TIMESTAMP=`date +%Y-%m-%d_%H-%M-%S`

################################################################
# Funktionen
usage ()
{
        echo "Usage:
        backup ( daily | weekly | monthly | yearly )"

}

################################################################
# Backup-Funktionen
daily ()
{
        rm -r $BACKUPDIR/daily_7
        mv $BACKUPDIR/daily_6 $BACKUPDIR/daily_7
        mv $BACKUPDIR/daily_5 $BACKUPDIR/daily_6
        mv $BACKUPDIR/daily_4 $BACKUPDIR/daily_5
        mv $BACKUPDIR/daily_3 $BACKUPDIR/daily_4
        mv $BACKUPDIR/daily_2 $BACKUPDIR/daily_3
        mv $BACKUPDIR/daily_1 $BACKUPDIR/daily_2
        mkdir $BACKUPDIR/daily_1
        cp -al $BACKUPDIR/backupdata/* $BACKUPDIR/daily_1
}

weekly ()
{
        rm -r $BACKUPDIR/weekly_4
        mv $BACKUPDIR/weekly_3 $BACKUPDIR/weekly_4
        mv $BACKUPDIR/weekly_2 $BACKUPDIR/weekly_3
        mv $BACKUPDIR/weekly_1 $BACKUPDIR/weekly_2
        mkdir $BACKUPDIR/weekly_1
        cp -al $BACKUPDIR/backupdata/* $BACKUPDIR/weekly_1
}

monthly ()
{
        rm -r $BACKUPDIR/monthly_12
        mv $BACKUPDIR/monthly_11 $BACKUPDIR/monthly_12
        mv $BACKUPDIR/monthly_10 $BACKUPDIR/monthly_11
        mv $BACKUPDIR/monthly_9 $BACKUPDIR/monthly_10
        mv $BACKUPDIR/monthly_8 $BACKUPDIR/monthly_9
        mv $BACKUPDIR/monthly_7 $BACKUPDIR/monthly_8
        mv $BACKUPDIR/monthly_6 $BACKUPDIR/monthly_7
        mv $BACKUPDIR/monthly_5 $BACKUPDIR/monthly_6
        mv $BACKUPDIR/monthly_4 $BACKUPDIR/monthly_5
        mv $BACKUPDIR/monthly_3 $BACKUPDIR/monthly_4
        mv $BACKUPDIR/monthly_2 $BACKUPDIR/monthly_3
        mv $BACKUPDIR/monthly_1 $BACKUPDIR/monthly_2
        mkdir $BACKUPDIR/monthly_1
        cp -al $BACKUPDIR/backupdata/* $BACKUPDIR/monthly_1
}

yearly ()
{
        rm -r $BACKUPDIR/yearly_5
        mv $BACKUPDIR/yearly_4 $BACKUPDIR/yearly_5
        mv $BACKUPDIR/yearly_3 $BACKUPDIR/yearly_4
        mv $BACKUPDIR/yearly_2 $BACKUPDIR/yearly_3
        mv $BACKUPDIR/yearly_1 $BACKUPDIR/yearly_2
        mkdir $BACKUPDIR/yearly_1
        cp -al $BACKUPDIR/backupdata/* $BACKUPDIR/yearly_1
}

################################################################
# Main
echo "$TIMESTAMP Backup $1 start" >> $LOGFILE 2>&1
case $1 in
  daily|weekly|monthly|yearly)
    mount /media/backup
    $1 >> $LOGFILE 2>&1
    umount /media/backup
    ;;
  *)
    usage
    exit 1
    ;;
esac
echo "$TIMESTAMP Backup $1 done" >> $LOGFILE 2>&1

# EOF

Kurze Erklärung: Der älteste Ordner wird gelöscht. Dann werden alle um eins verschoben. Das Herzstück vom ganzen Backup verbirgt sich hinter der Option -l von cp. Diese Option erstellt lediglich einen Hardlink von allen Dateien. Dies ist das tolle daran. Bei der Kopie mit cp -al src dst wird kein weiterer Speicherplatz auf dem Speichermedium belegt!

Backups erstellen
In der Crontab, welche mit sudo crontab -e aufgerufen wird, erstelle ich folgende Einträge:

# Backup
# Backup daily; 1:30h
30 1   *   *   *       /usr/local/bin/backup daily
# Backup weekly; Montag, 2:00h
0  2   *   *   1       /usr/local/bin/backup weekly
# Backup monthly; 1. Tag 4:00h
0  4   1   *   *       /usr/local/bin/backup monthly
# Backup yearly; 31. Dezember 3:00h
0  3  31  12   *       /usr/local/bin/backup yearly

Jetzt werden zu bestimmten Zeiten die vberschiedenen Backups durchgeführt. Natürlich kann man die Befehle auch von Hand ausführen. Jedoch vereinfachen die Cronjobs diese Aufgabe erheblich!

Überwachung
Im Logfile können wir uns über den Status informieren:

emanuel@eeebox:~
$ tail /var/log/backup.log
2010-11-25_23-31-55 Backup daily start
2010-11-25_23-31-55 Backup daily done

Ich sehe keine Fehlermeldung. Das Backup hat funktioniert!

Restore
Ein Backup ist ohne erfolgreichen Restore gar nichts wert! Das restoren ist sehr einfach. Man kann einfach den gewünschten Ordner oder die gewünschte Datei zurückkopieren. Man muss gar nichts beachten!

emanuel@eeebox:/media/backup/backup/weekly_2/discordia
$ scp -r Daten/ discordia:/tmp/

Download
Hier könnt ihr alle Dateien als Archiv herunterladen: backup_emanuelduss.tar

Schluss
Wenn man das Backup einmal eingerichtet hat, hat man eine sehr zuverlässige Lösung um seine Daten zu sichern. Ich rate jedem an, seine Daten regelmässig zu sichern und auch den Restore durchzuspielen! Das Logfile sollte regelmässig nach Fehlern durchsucht werden, um die integrität aller Backup-Daten festzustellen.

Für Anmerkungen, Kritik und Verbesserungsvorschläge bin ich jederzeit dankbar und offen! Man lernt schliesslich nie aus!

Viel Spass mit euren Backups.

34 thoughts on “Ein Backup-Konzept mit Hardlinks und rsync”

  1. Yeah, cool! Vorallem bei daily, weekly usw. Sicherungen kommen die Hardlinks sehr gut zum tragen!

    Reply
  2. In der Tat, sehr cooles Konzept. Für meine Zwecke bräuchte ich ggf. noch einen De-Duplikator zwischen den Backups der einzelnen Backups der Hosts; auf jeden Fall aber inspirierend und sehr cool zusammengefasst hier im Blog.

    PS: Auf meinem Rechner sieht das Kommentar-Formular hier etwas seltsam aus, die Textfelder und Labels sind irgendwie verschoben.

    Reply
    • Danke, danke euch zwei. 🙂

      Wie meinst Du das mit dem De-Duplikator? Verstehe ich nicht ganz…

      Das mit dem Kommentarfeld kann ich nur nachproduzieren, wenn ich es von Hand an der unteren rechten Ecke vergrössere. Ist etwas unschön. In der Default-Ansicht sollte es jedoch stimmen. Oder?

      Grz

      Reply
    • Hallo Thomas

      Dagegen sprach nichts. Ich wollte das mal selber machen und eine eigene Lösung kann man besser anpassen. Zum Beispiel gefällt mir das Configfile “syncup.conf” besser, als alles in der “rsnapshot.conf” anzugeben.

      Mitlerweilen nutze ich für das Backup vom Notebook rsnapshot, da ich das nach einer Neuinstallation ausprobieren wollte. Und es passt mir.

      Gruss
      Emanuel

      Reply
  3. Vielen Dank für die Arbeit, ich denke ich kann das Skript ganz gut gebrauchen. Aber wofür wird denn im Skript backup.sh im Teil Main “mount /media/backup” und später umount gemacht? Habe das bisher noch nicht verstanden.

    Reply
    • Hallo Patrick

      Bitte 🙂

      Da ich das Backup auf eine externe Festplatte mache, welche normalerweise nicht im Dateisystembaum eingehängt ist (damit man auf die Daten während dem regulären Betrieb nicht zugreifen kann), hänge ich diese zuerst mit `mount` ein. Dann geschieht das Backup. Nach dem Backup wird die Platte dann wieder ausgehängt.

      Wenn man sicher sein kann, dass die Platte immer eingehängt ist, kannn man das natürlich auch weglassen, aber mir gefällt es so besser.

      Gruss
      Emanuel

      Reply
  4. Vielen Dank

    Das hat mir genau den richtigen Anreiz gegeben auch für mich ein ähnliches Backup Konzept zu relasisieren.
    Mein Problem war dass ich mein Vserver im Internet auf mein NAS in meinem privaten Netz sichern wollte. Das NAS hängt an einer dynamischen IP. Somit war ein rsych daemon auf dem Vserver keine Option da ich ihn nicht auf die IP vom NAS eingrenzen kann. Da ist mir dein Konzept gerade recht gekommen. Ich muss sagen ich bin ja blutiger Anfänger in der Linux Welt. Ich habe es aber geschafft deine Scripts für meine Bedürfnisse etwas anzupassen. Ich habe das Backup script jetzt auf dem NAS installiert und das syncup script läut auf dem Vserver. Das syncup hab ich dann so angepasst dass es zwar kein Config file mehr liest denn ich mache immer eine volle sicherung. Die ganze daily/weeky etc. logik vom Backup script stekt jetzt auch im syncup script und macht nur einen rsynch aufs NAS. Anschliessend wird der backup auf dem NAS per SSH mit den entsprechenden parametern angestossen. Dafür hast Du mir die zündende Idee gegeben mit dem SSH im Script für die Mounts. Das konnte ich dann gut anpassen um das Backup script im NAS anzustossen.
    Also vielen Dank nochmals! Das hat mir echt weiter geholfen.

    Reply
    • Hallo Thomas

      Freut mich, dass ich dich inspiriert habe 🙂 Vielleicht auch noch für dich interessant: Die Option --link-dest=DIR in rsync zeigt auf ein Verzeichnis welches für gleiche Dateien hardlinks erstellt (sollte den cp Befehl überflüssig machen im Skript, habs aber selber noch nicht ausprobiert).

      Gruss und viel Spass damit
      Emanuel

      Reply
  5. Wenn ich das ganze Backup auf einem iSCSI Target legen will, worauf kann ich dann verzichten? Die Hardlinks bräuchte ich dann ja theoretisch nicht mehr. und man könnte alles mit dem Backupskript lösen.

    Reply
    • Das Skript ist eigentlich dafür gedacht, dass man das Backup mit Hardlinks macht. Ruft man cp ohne die Option -l auf, werden keine Hardlinks erstellt und es wird der gesamte Speicherplatz erneut belegt, was bei grossen Backups a) sehr lange und b) viel Speicherplatz braucht. Möglich ist es aber schon. Ein aktuelles Backup (nur eine Version, ohne Hardlinks), kann man auch gut mit rsync alleine machen, indem man einfach in ein Verzeichnis (nur eine Version) synchronisiert.

      Reply
      • Ich wollte mich nochmal melden:
        Klar, du hast völlig Recht und es läuft ganz hervorragend. zusätzlich nutze ich noch Borg Backup

        Dein Skript ist trotzdem Klasse weil übersichtlich und leicht zu modifizieren. Ich mag es als Basissicherung!

        Reply
  6. Hallo,
    Ich habe noch eine Frage bzl. den Hardlinks (oder ggf. nur einen Denkfehler)
    Laut Ubuntu Wiki (https://wiki.ubuntuusers.de/cp/ ) bewirkt der -l Parameter bei cp folgendes:
    -l oder –link kopiert nicht, sondern erstellt harten Link
    Wenn jetzt jedoch beim täglichen, wöchentlichen, monatlichen oder halbjährlichen Kopieren nicht die Dateien kopiert sondern nur Links erzeugt werden, habe ich doch keine Historisierung, oder?

    Oder wird beim Ändern einer Datei eine neue Datei angelegt?

    Hintergrund: Ich möchte ein Backup meines Samba Shares machen und die Dateien dort versionieren,
    damit bei einem Virenbefall / Verschlüsselungstrojaner die Daten nicht verloren sind.

    Reply
    • Hallo

      Das hast du richtig verstanden. Über cp -l werden nur links erstellt. Folgende Schritte sollten es dir erklären:

      1) Mittels rsync werden die Daten in das Verzeichnis backupdir gesichert
      2) Danach (wenn alle Daten in diesem Verzeichnis liegen), wird mit cp -l backupdir daily_1 das Verzeichnis kopiert, aber wie du gesagt hast, lediglich Links angelegt. Sprich, im Verzeichnis daily_1 befinden sich exakt die selben Daten wie im Verzeichnis backupdir.
      3) Einen Tag später mache ich erneut rsync in das backupdir Verzeichnis. Wenn sich Daten ändern, werden diese im backupdir Verzeichnis überschrieben, aber im daily_1 Verzeichnis bleiben diese unverändert.
      4) Vom aktuellen backupdir kann jetzt wieder eine Kopie mittels Hardlinks gemacht werden, damit diese Version “historisiert” abgelegt wird.
      5) So geht es weiter.

      Also: cp -l wird nur verwendet, um ein Verzeichnis 1:1 mit Hardlinks zu kopieren. Es kommen keine weiteren Daten hinzu. Mit rsync werden die neuen Daten in das Verzeichnis backupdata gesichert.

      Konnte ich das so irgendwie verständlich beschreiben?

      Gruss,
      Emanueöl

      Reply
      • Hallo Emanuel,
        vielen Dank für die Erläuterung.
        Das hat meinen Knoten im Kopf gelöst.

        Ich werde – wie du bereits weiter oben angeführt hat – rsync mit dem Parameter –link-dest=DIR testen und Dir Rückmeldung geben, ob dadurch das cp -l überflüssig wird.

        Gruß Alex

        Reply
        • Hallo Alex

          Ja genau, diese Option hab ich auch schon mal gesehen. Ist auch interessant. Schlussendlich ist das Prinzip aber dasselbe.

          Merci und Gruss,

          Emanuel

          Reply
      • Hallo,

        kurze Ergänzung, da ich auch über die Frage gestolpert war.
        Entscheidung ist, dass rsync die Dateien in backupdir beim Überschreiben technisch gesehen nicht ändert (und damit auch alle Hardlinks), sondern als neue Dateien (wenn auch mit gleichem Namen) neu anlegt.
        Nur dadurch bleiben die alten Versionen erhalten und werden nicht mit geändert.

        Viele Grüße!

        Reply
  7. Danke für den Beitrag.
    Bin kürzlich von Synology auf FreeNAS (hauptsächlich wegen ZFS) umgestiegen und auf der Suche nach einer neuen Bestimmung für das alte (aber immer noch gut brauchbare) NAS von Synology. Geplant ist nun das alte NAS weiter als offsite Backup zu nutzen, aber nur falls eine inkrementelle Absicherung möglich ist, da die Daten mehrere TiB Platz brauchen und ein Komplettbackup das ganze Netz nicht bloß stunden- sondern tagelang beanspruchen würde.
    Auf der Suche nach einer brauchbaren und effizienten Backup-Lösung bin ich unter anderem auf den (sehr aufschlussreichen) Beitrag von Mike Rubel bzgl. inkrementeller Backups mit Rsync[1] gestoßen. Er bezieht sich dort auch auf die hardlink-Methode mittels des “–link-dest”-Parameters.
    Die Möglichkeit inkrementelle Backups mit Rsync und Hardlinks anzulegen ist auf jeden Fall sehr praktisch.

    [1]: http://www.mikerubel.org/computers/rsync_snapshots/

    Reply
      • Darf man fragen, warum; d.h. gibt es eine grundsätzlich bessere Möglichkeit für ein solides, regelmäßiges Backup (speziell für Linux-Clients und NAS im LAN)?

        Reply
        • Klar 🙂

          Der Grund ist, weil ich das Backup jetzt direkt auf dien Harddisk mache und nicht mehr via rsync auf ein Server.

          Ich nutzte dann eine Zeit lang rsnapshot und jetzt folgendes kleine Script, welche etwa dasselbe tut wie das ursprüungliche (auch rsync mit Hardlinks):

          #!/usr/bin/env bash

          HOST="$1"
          BASEDIR="$(pwd)"
          INCLUDEFILE="$BASEDIR/${HOST}.include"
          DATE="$(date +%Y-%m-%d_%H-%M-%S)"
          BACKUPDIR="$BASEDIR/$HOST"

          if [[ ! -d "$BACKUPDIR" ]]
          then
            mkdir "$BACKUPDIR"
          fi
          if [[ ! -d "$BACKUPDIR/current" ]]
          then
            mkdir "$BACKUPDIR/current"
          fi

          rsync -aP --prune-empty-dirs --rsync-path="sudo rsync" \
            --include-from="$INCLUDEFILE" \
            / "$BACKUPDIR/current"

          cp -al "$BACKUPDIR/current" "$BACKUPDIR/${DATE}"

          Als input gibts dann ein rsync include file wie z. B. folgendes:

          + /home/emanuel/Documents/**
          + /home/emanuel/.*/**
          + /etc/**
          + /usr/local/**
          + */
          - *
          Reply
  8. Ein (fast) schönes Backup-Konzept. rsync ist für mich auch das beste Tool (nach allen anderen kommerziellen “Lösungen”).

    Kleiner Korrekturvorschlag:
    Ich würde der Workstation, deren Daten gesichert werden sollen, grundsätzlich keinerlei Schreibrechte auf dem Backupserver einräumen wollen. Der Hauptgrund liegt in den Ransomware-Gefahren. Ich halte es für daher für besser, wenn sich der Backup-Server die Daten von der Workstation holt, das für rsync kein Problem darstellt.
    Auf diese Weise lassen sich auch auf dem Backupserver ganz andere User und entsprechende Rechte einrichten.
    Der normale Workstation-User kann auf dem Backupserver lediglich die Backupdaten lesen und natürlich im Verlustfall entsprechend zurückholen.

    Reply
  9. Hallo Emanuel,
    ich benutze Deine Scripte, etwas angepasst auf meine Bedürfnisse, seit Jahren sehr
    erfolgreich. Vielen Dank dafür.
    Nun wird es an der Zeit die Backups auch mal etwas aufzuräumen. Es sind Daten im Bestand
    die mit Sicherheit nie wieder gebraucht werden, die will ich nun löschen.
    Gibt es einen einfachen Weg eine Datei die z.B. seit 2 Jahren unverändert ist mit “einem Klick”
    zu löschen ? Oder müssen diese in allen Verzeichnissen einzeln gelöscht werden ?
    Vielen Dank für Deine Hilfe.
    Gruß
    Micha

    Reply
    • Hoi Micha

      Bitte, schön dass dir das was bringt.

      Mit find kann man solche Abfragen nach letztem Dateizugriff oder nach der letzten Änderung machen.

      Beispiel: Alle Dateien welche seit mehr als 720 Tagen (2 Jahre) geändert wurden:

      find / -ctime +720

      Mit der Option -atime kann man den letzten Zugriff abfragen. Beispiel: Alle Dateien, welche seit über 2 Jahren nicht mehr zugegriffen wurden:
      Beispiel: Alle Dateien welche seit mehr als 720 Tagen (2 Jahre) geändert wurden:

      find / -atime +720

      Diese könnte man dann so löschen (wie immer: Vorsicht mit solchen Befehlen):

      find / -atime +720 -exec rm {}\;

      Du könntest aber auch einfach alle alten Backup Verzeichnisse löschen, das aktuellste würde dann nur noch die Dateien vom jetzigen Zeitpunkt beinhalten und Daten, welche du auf dem Gerät gelöscht hast, sind dann auch entfernt.

      Gruss,
      Emanuel

      Reply
  10. Ich bin durch Zufall auf dieses (alte aber gute) Script gestoßen.

    Mit ein wenig Anpassung hat es auf Anhieb funktioniert. Da ich keinerlei Erfahrung mit Hardlinks habe, werde ich das jetzt mal ein paar Tage laufen lassen und dann schauen, wie das Ergebnis ausschaut. Vielleicht verstehe ich es dann besser.

    Eine Frage habe ich aber:
    Wie kann man Unterverzeichnisse ausschließen?
    Hintergrund: In meinem Dokumentenordner gibt es zwei Unterverzeichnisse, die nicht mitgesichert werden sollen.

    Viele Grüße
    Peter

    Reply
  11. Kleiner Nachtrag:
    Ich glaube es selbst gefunden zu haben. Es muss ein “–exclude” + Verzeichnis in die Variabel für den Parameter.

    Reply

Leave a Reply to jzilla Cancel reply