Automatische Sicherung (Beispiel): Unterschied zwischen den Versionen

Aus wiki.archlinux.de
Tuxnix (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Tuxnix (Diskussion | Beiträge)
typo
 
(40 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{inuse|[[Benutzer:Tuxnix|Tuxnix]] ([[Benutzer Diskussion:Tuxnix|Diskussion]])}}
[[Kategorie:Systemverwaltung]]
[[Kategorie:Services]]
[[Kategorie:Tipps und Tricks]]
{{righttoc}}
Dieser Wiki Eintrag befindet sich gegenwärtig unter Bearbeitung.
Dies ist Beispiel und Anleitung für ein automatisches, rotierendes und inkrementelles Backup.
Dies ist Beispiel und Anleitung für ein automatisches, rotierendes und inkrementelles Backup.
Das hier verwendete Skript von Mike Rubbel baut auf dem [[rsync]] Befehl auf und sichert die Daten auf /home.
Das hier verwendete Skript (Original von Mike Rubel im Anhang) baut auf dem [[rsync]] Befehl auf und sichert die Daten  
[[Systemd/Timers]] werden genutzt um das Backup täglich, wöchentlich und monatlich automatisch vorzunehmen.
täglich, wöchentlich und monatlich. Hierzu wird ein [[Systemd/Timers | Systemd-Timer]] genutzt.
 
Das original Skript entstand 2004 und fand so viel Anklang, dass es in Perl übersetzt wurde und als [[rsnapshot]] Einzug in den Befehlspool von Linux hielt.
Das Skript fand so viel Anklang, dass es in Perl übersetzt und Einzug in den Befehlspool von Linux gehalten hat.
Wer den Befehl diesem Skript vorzieht, kann auch diesen benutzen. Das Endergebnis dürfte jedoch gleich sein da beide rsync zum Speichern der Dateien einsetzen.
Wer den Befehl dem Skript vorzieht kann auch diesen benutzen. Das Endergebnis dürfte jedoch gleich sein da beide rsync zum Speichern der Dateien einsetzen.


{{Hinweis|Da die Sicherung auf einer lokalen Festplatte stattfindet, kann sie weder bei Feuer noch bei einem Einbruch vor Datenverlust schützen.
{{Hinweis|Da die Sicherung auf einer lokalen Festplatte stattfindet, kann sie weder bei Feuer noch bei einem Einbruch vor Datenverlust schützen.}}
Auch wenn bislang Schädlinge mit Administrationsrechten auf Linux sehr unwahrscheinlich sind, muss hier auf diese Gefahr hingewiesen werden.}}


Als Backup im privaten Bereich leistet es aber gute Dienste.
Durch das automatische Sichern stellen Festplattendefekte und versehentliches Löschen keine Gefahr mehr da.
Durch das automatische Sichern stellen Festplattendefekte und versehentliches Löschen keine Gefahr mehr da.
Durch das rotierende Verfahren hat man die Möglichkeit, auf mehrere gesicherte Dateiversionen zuzugreifen.
Durch das rotierende Verfahren hat man die Möglichkeit, auf mehrere gesicherte Dateiversionen zuzugreifen.
Trotzdem bleibt die Datenmenge gering. Rsync speichert die Daten jeweils nur einmal physisch ab und erstellt die einzelnen Schichten mittels Hardlinks.
Trotzdem bleibt die Datenmenge gering. Rsync speichert die Daten jeweils nur einmal physisch ab und erstellt die einzelnen Schichten mittels Hardlinks.
Da die Daten nur ein mal kopiert werden, ist die Geschwindigkeit des backups hervorragend.
Da immer nur die jeweils veränderten Daten neu gesichert werden, ist die Geschwindigkeit des backups hervorragend.


== Anleitung ==
== Anleitung ==


=== Die Sicherungs-Festplatte ===
=== Die Sicherungs-Festplatte ===
Einen Datenträger fest in den Rechner einbauen. Bei externen Datenträger sollte die Sicherung besser manuell ausgelöst werden.  
Der Sicherungs-Datenträger sollte fest in den Rechner verbaut werden.
Der Datenträger sollte ausreicht groß sein. Als Format eignet sich ext4. Fat Systeme unterstützen keine Hardlinks.
Der Datenträger muss ausreichend groß sein. Die folgenden Schritte sind als Beispiel zu verstehen:


==== Partitionieren ====
====Partitionieren====
$ sudo fdisk -l #listet die Datenträger auf
Der Datenträger wird wie in [[fdisk]] bzw. [[gdisk]] beschrieben mit 1. Partition versehen.


Bei den folgenden Befehlen muss das X durch den Laufwerksbuchstaben der Sicherung-Festplatte ersetzt werden.
$ sudo fdisk /dev/sdX
g #Erstellt provisorisch eine neue Partitionstabelle
n #Erstellt provisorisch die neue Partition
w #Schreibt alle Änderungen. Ab hier gibt es keinen Weg mehr zurück.
==== Formatieren ====
==== Formatieren ====
Als Format eignet sich ext4. Fat Systeme unterstützen keine Hardlinks.
mkfs.ext4 /dev/sdx1


  mkfs.ext4 -n SICHERUNG /dev/sdX1
====Datenträger Benennen ====
Die erste Partition auf sdX wird mit ext4 formatiert und bekommt den Namen SICHERUNG.
Der Datenträger erhält das Label SICHERUNG
  e2label /dev/sdx1 SICHERUNG
=== rsync ===
 
Falls auf dem System noch nicht vorhanden, wird rsync installiert.
==== Festplatte Einhängen ====
  sudo pacman -S rsync
Ein Verzeichnis SICHERUNG auf root (/) anlegen
mkdir /SICHERUNG
 
====/etc/fstab====
öffnen mit
nano /etc/fstab
 
und hier folgendes einfügen:
/dev/sdx1 /SICHERUNG ext4 defaults 0 2
 
====mounten====
Das System Neustarten oder die Festplatte SICHERUNG auf /SICHERUNG ins Dateisystem einbinden.
  mount /dev/sdx1 /SICHERUNG


=== Das Backup Skript ===
=== Das Backup Skript ===
Das folgende Skript wird kopiert und als {{ic|snapshot.sh}} z.B. in {{ic|~/scripts/}} abgespeichert und mit {{ic|chmod a+rx ~/scripts/snapshot.sh}} ausführbar gemacht.
Falls auf dem System noch nicht vorhanden, wird jetzt rsync installiert.
Die ''CUSTOMIZING SECTION'' im Skript sollte auf die eigenen Wünsche und Gegebenheiten angepasst werden. Im diesem Beispiel ist das konkret noch der der Laufwerksbuchstabe der Sicherungs Festplatte anzupassen.
pacman -S rsync


Die Datei {{ic|snapshot_exclude.txt}} wird ebenfalls kopiert und nach {{ic|~/scripts/}} abgespeichert.
Das folgende Skript wird kopiert und als {{ic|snapshot.sh}} in {{ic|/usr/local/bin/}} abgespeichert. Mit einem {{ic|chmod a+rx /usr/local/bin/snapshot.sh}} wird es ausführbar gemacht.
Die in der snapshot_exclude.txt gelisteten Dateien werden von der Sicherung ausgeschlossen.


Danach kann mit folgendem Befehl die Funktion überprüft werden. Das Argument {{ic|-d}} erstellt ein tägliches Backup. Das Backup wird mit Rootrechten ausgeführt.
Die ''CUSTOMIZING SECTION'' im Skript sollte auf die eigenen Gegebenheiten angepasst werden.
sudo ~/scripts/snapshot.sh -d


Bei einem erneuten Aufruf des Befehls erhöht sich der Zähler der jeweils vorangegangenen Sicherungen um 1. Eine dayly-0 Sicherung wird z.B.: in dayly-1 umbenannt, und eine neue dayly-0 Sicherung angelegt. Bei der Angabe von DAYS=6; wird dann jeweils die 7. Sicherung gelöscht, bevor eine neue dayly-0 angelegt wird.
Die Datei {{ic|snapshot_exclude.txt}} wird ebenfalls kopiert und nach {{ic|/usr/local/bin/}} gespeichert.
Die wöchentlichen Snapshots werden mit sudo ~/scripts/snapshot.sh -w bzw sudo ~/scripts/snapshot.sh -m ausgelößt.
Alle in der snapshot_exclude.txt gelisteten Dateien und Verzeichnisse werden von einer Sicherung ausgeschlossen.
Dabei wird keine neue Sicherung veranlasst, sondern lediglich, und auch nur dann wenn die Anzahl der täglichen Sicherungen komplettiert ist, die älteste der dayly Sicherungen in weekly-0 umbenannt, und auf diese Weise archiviert. Auf diese Weise rotieren die Backups.


Das snapshot.sh Script
Danach kann mit folgendem Befehl die Funktion überprüft werden. Das Backup wird mit Rootrechten ausgeführt.
snapshot.sh
 
Bein ersten Durchlauf werden alle Daten nach daily.0 kopiert. Bei einem erneuten Aufruf des Befehls wird daily.0 nach daily.1 kopiert. Danach wird die daily.0 mit dem aktuellen Stand aktualisiert. Bei der Angabe von DAYS=6 in der ''CUSTOMIZING SECTION''; wird die spätere 7. Sicherung entweder als erste wöchentliche Sicherung umbenannt oder gelöscht, bevor die Sicherungen daily.5 bis daily.1 jeweils einen Zähler aufrücken.
 
Das Skript
  <nowiki>#!/bin/bash
  <nowiki>#!/bin/bash
##
##      Script: snapshot.sh
##
##      Creates daily, weekly and montly hardlink backupslices with rsync.
##
##      Version: 0.4
##
##      Original from:  Mike Rubel (http://www.mikerubel.org/computers/rsync_snapshots/)
##
##      License:  LGPL
##
##      Disclaimer: Use this software on your own risk, it works for me but there are no guaranties at all.
##
##      Changes from tuxnix:        *Only one systemd timer needed
##                                  *rsync.log
##                                  *Source directory choosable
##                                 
##                                             
##
## ======================= CUSTOMIZING SECTION ========================
SOURCE='/NAS/  /home/tuxnix/'                        # Source needs a / at the end. More then only one SOURCE-Directories are possible (set ' ' marks).
EXCLUDES=/usr/local/bin/snapshot_exclude.txt        # full path of exludefile is needed
MOUNT_RO=true                                        # For remount with write protection set to true
MOUNT_DEVICE=/dev/disk/by-label/SICHERUNG            # Taget device
MOUNT_POINT=/SICHERUNG                              # Mount point of target device
TARGET=/SICHERUNG                                    # Target directory - full directory path of mounted device is needed
CHECK_HDMINFREE=true;        # Check free space
HDMINFREE=98;                # Make a backup up to this percentage
DAYS=6;                      # Number of daily backups -1
WEEKS=3;                      # Number of weekly backups -1
MONTHS=11;                    # Number of monthly backups -1
# ---------------------- Check -----------------------------------------------------------------------------------------
# Make sure we're running as root
if (( `id -u` != 0 )); then { echo "Sorry, must be root.  Exiting..."; exit; } fi
# Check exludefile exists
if ! [ -f $EXCLUDES ] ; then { echo "Error: Exclude File $EXCLUDES missing"; exit; } fi
# Remount Device rw
if $MOUNT_RO ; then
        mount -o remount,rw $MOUNT_DEVICE $MOUNT_POINT
        if (( $? )) ; then
            echo "Error: could not remount $MOUNT_DEVICE readwriteable"
            exit
        fi
fi
# Check free space on disk
GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/'
if $CHECK_HDMINFREE ; then
        KBISFREE=`df /$TARGET | tail -n1 | sed -e "$GETPERCENTAGE"`
        if [ $KBISFREE -ge $HDMINFREE ] ; then
                echo "Error: Not enough space left for rotating backups!"
                logger "Error: Not enough space left for rotating backups!"
                exit
        fi
fi
# Give Source some time to wake up if needed.
ls $SOURCE > /dev/null
if (( $? )) ; then
    echo "Wait 10 seconds till $SOURCE device is arrivable."
    sleep 10
    ls $SOURCE > /dev/null
    if (( $? )); then
    echo "Can't read $SOURCE"
    exit
    fi
fi
# ---------------Rotate Monthly Snapshots------------------------------------------------------------------------------
if [ -d $TARGET/weekly.$WEEKS ] && ! [ -d $TARGET/monthly.0 ] ; then
    echo "mv $TARGET/weekly.$WEEKS $TARGET/monthly.0"
    mv $TARGET/weekly.$WEEKS $TARGET/monthly.0
elif [ -d $TARGET/weekly.$WEEKS ] && [ -d $TARGET/monthly.0 ] ; then
    STAMP_0=`stat -c %Y $TARGET/weekly.$WEEKS`
    STAMP_1=`stat -c %Y $TARGET/monthly.0`
    if [ $(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) -ge 30 ] ; then
          echo ""
          echo "Rotate Monthly Snapshots:"
# Step 1: Delete the oldest monthly snapshot, if it exists
          if [ -d $TARGET/monthly.$MONTHS ] ; then
                echo "rm -rf $TARGET/monthly.$MONTHS"
                rm -rf $TARGET/monthly.$MONTHS
          fi
# Step 2: Shift the middle snapshots by one
          OLD=$MONTHS
          while [ $OLD -ge 1 ] ; do
                OLD=$[$OLD-1]
                if [ -d $TARGET/monthly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/monthly.$OLD $TARGET/monthly.$NEW"
                        mv $TARGET/monthly.$OLD $TARGET/monthly.$NEW
                fi
          done
# Step 3: move oldest weekly to monthly.0
            echo "mv $TARGET/weekly.$WEEKS $TARGET/monthly.0"
            mv $TARGET/weekly.$WEEKS $TARGET/monthly.0
         
    fi
fi
# ---------------Rotate Weekly Snapshots------------------------------------------------------------------------------
if [ -d $TARGET/daily.$DAYS ] && ! [ -d $TARGET/weekly.0 ] ; then
    echo "mv $TARGET/daily.$DAYS $TARGET/weekly.0"
    mv $TARGET/daily.$DAYS $TARGET/weekly.0
elif  [ -d $TARGET/daily.$DAYS ] && [ -d $TARGET/weekly.0 ] ; then
    STAMP_0=`stat -c %Y $TARGET/daily.$DAYS`
    STAMP_1=`stat -c %Y $TARGET/weekly.0`
    #echo "$(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) days difference between $TARGET/daily.$DAYS and $TARGET/weekly.0"
    if [ $(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) -ge 7 ] ; then
          echo ""
          echo "Rotate Weekly Snapshots:"
# Step 1: Delete the oldest weekly snapshot, if it exists
        if [ -d $TARGET/weekly.$WEEKS ] ; then
            echo "rm -rf $TARGET/weekly.$WEEKS"
            rm -rf $TARGET/weekly.$WEEKS
        fi
# Step 2: shift the middle snapshots by one.
        OLD=$WEEKS
        while [ $OLD -ge 1 ] ; do
                OLD=$[ $OLD - 1 ]
                if [ -d $TARGET/weekly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/weekly.$OLD $TARGET/weekly.$NEW"
                        mv $TARGET/weekly.$OLD $TARGET/weekly.$NEW
                fi
        done
# Step 3: move oldest daily to weekly.0
        echo "mv $TARGET/daily.$DAYS $TARGET/weekly.0"
        mv $TARGET/daily.$DAYS $TARGET/weekly.0
    fi
fi
# -----------------Rotate Daily Snapshots---------------------------------------------
          echo ""
          echo "Rotate Daily Snapshots:"
          if [ -d $TARGET/daily.$DAYS ] ; then
          echo "rm -rf $TARGET/daily.$DAYS"
                rm -rf $TARGET/daily.$DAYS
          fi
          OLD=$DAYS
          while [ $OLD -ge 2 ] ; do
                OLD=$[$OLD-1]
                if [ -d $TARGET/daily.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/daily.$OLD $TARGET/daily.$NEW"
                        mv $TARGET/daily.$OLD $TARGET/daily.$NEW
                fi
          done
          echo ""
          echo "Copy Hardlinks:"
          if ! [ -d $TARGET/daily.0 ] ; then
                $MKDIR -p $TARGET/daily.0
          else
                echo "cp -al $TARGET/daily.0 $TARGET/daily.1"
                cp -al $TARGET/daily.0 $TARGET/daily.1 ;
                touch $TARGET/daily.1 --reference=$TARGET/daily.1/.timestamp
          fi
          echo ""
          echo "Starting Backup:"
          rsync -va --delete --delete-excluded --exclude-from="$EXCLUDES" --log-file=$TARGET/.rsync.log $SOURCE $TARGET/daily.0
          if ! [ $? = 24 -o $? = 0 ] ; then
                echo "rsync ended with ERRORS!"
                logger "rsync ended with ERRORS!"
                touch $TARGET/daily.0/.rsync_error
                touch $TARGET/daily.0/.timestamp
                exit
            else
                touch $TARGET/daily.0/.timestamp
                touch $TARGET/daily.0
                echo "Finished backup: $SOURCE to $TARGET with SUCCSESS"
                logger "Finished backup: $SOURCE to $TARGET with SUCCSESS"
          fi
if $MOUNT_RO ; then
        #echo "mount -o remount,ro $MOUNT_DEVICE $TARGET"
        mount -o remount,ro $MOUNT_DEVICE $TARGET
        if (( $? )); then
                echo "Error: Could not remount $TARGET readonly"
                exit
        fi
fi
</nowiki>
<nowiki>
## Datei: /[path]/snapshot_exclude.txt
Videos
tuxnix/.cache
</nowiki>
=== Die  Service-Unit erstellen ===
Folgende Datei erstellen und abspeichern.
<nowiki>#file /etc/systemd/system/snapshot.service
[Unit]
Description=snapshot.service
[Service]
ExecStart=/usr/local/bin/snapshot.sh
</nowiki>
=== Die Timer-Unit erstellen ===
Folgende Datei erstellen und abspeichern.
<nowiki>#file /etc/systemd/system/snapshot.timer
[Unit]
Description=snapshot.timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=basic.target
</nowiki>
=== Den Timer aktivieren ===
systemctl enable snapshot.timer
Nach einem Neustart sorgt nun systemd für das regelmäßige Erstellen der gewünschten Backups.
===Anhang===
Beim original script werden 3 verschiedene Optionen genutzt:
* Option {{ic|-d}} erstellt ein tägliches Backup.
* Option {{ic|-w}} erstellt ein wöchentliches Backup.
* Option {{ic|-m}} erstellt ein monatliches Backup.
Dem entsprechend sind auch 3 systemd-timer und 3 systemd-services mit den entsprechenden ExecStart Befehlen anzulegen.
Das original Skript
<nowiki>#!/bin/bash
## Datei ~/.scripts/snapshot.sh
##
##
##
##      Mike Rubel 2004.01.04 (http://www.mikerubel.org/computers/rsync_snapshots/)
##      Mike Rubel 2004.01.04 (http://www.mikerubel.org/computers/rsync_snapshots/)
Zeile 134: Zeile 406:
MOUNT_RO=true;                          # For write protection set to true
MOUNT_RO=true;                          # For write protection set to true
SNAPSHOT_RW=/SICHERUNG/;                # where to store the backups - Ziel-Ordner
SNAPSHOT_RW=/SICHERUNG/;                # where to store the backups - Ziel-Ordner
EXCLUDES=/home/scripts/snapshot_exclude.txt;    # Create the backup_exclude file first!
EXCLUDES=/home/<user>.scripts/snapshot_exclude.txt;    # Create the backup_exclude file first!
CHECK_HDMINFREE=true;                  # Check free space
CHECK_HDMINFREE=true;                  # Check free space
HDMINFREE=90;                          # Make a backup up to this percentage
HDMINFREE=90;                          # Make a backup up to this percentage
Zeile 311: Zeile 583:
</nowiki>
</nowiki>


snapshot_exclude.txt
  <nowiki>
  <nowiki>
/home/<user>/.cache/
## Datei ~/.scripts/snapshot_exclude.txt
/home/<user>/.kodi/
##
/home/<user>/.local/share/
<user>/.cache
/home/<user>/.mediathek3/
<user>/.kodi
/home/<user>/.mozilla/
<user>/.local/share
/home/<user>/.tor-browser-de/
<user>/.mediathek3
/home/<user>/.tvbrowser/
<user>/.mozilla
/home/<user>/Videos/
<user>/.tor-browser-de
<user>/.tvbrowser
<user>/Videos
</nowiki>
</nowiki>


=== Die  Service-Units erstellen ===
== Siehe auch ==
<nowiki># Datei /etc/systemd/system/snapshot-d.service
*[[rsync]]
 
*[[Rdiff-backup]]
[Unit]
*[[Rsnapshot]]
Description=snapshot dayly.service
*[[Backups]]
 
*[[sudoedit]]
[Service]
*[[Systemd/Timers]]
ExecStart=/home/<user>/scripts/snapshot -d
*[[Beispiel_eines_vollautomatisierten_Backups]]
</nowiki>
 
Für die wöchentliche und monatliche Sicherung brauchen wir noch entsprechende snapshot-w.service und snapshot-m.service Dateien.
Das d im der ExecStart= Option ist durch ein w bzw. m zu ersetzen. Bei Description= ist weekly bzw. monthly enzusetzen.
 
 
=== Die Timer-Units erstellen ===
 
<nowiki># Datei /etc/systemd/system/snapshot-d.timer
 
[Unit]
Description=snapshot dayly.timer
 
[Timer]
OnBootSec=20min
OnUnitInactiveSec=1d
 
[Install]
WantedBy=basic.target
</nowiki>
Auch hier bedarf es einer weiteren Datei für den wöchentlich und auch einer weitern Datei für den monatlichen Timer.
Das OnUnitInactiveSec= erhält dann den Wert 1w bwz. 1m zugewiesen.
 
=== Die Timer aktivieren ===
systemctl enable --now snapshot-d.timer
systemctl enable --now snapshot-w.timer
systemctl enable --now snapshot-m.timer
 


=== Weblinks ===
=== Weblinks ===
*[http://www.mikerubel.org/computers/rsync_snapshots/ Mike Rubel rsync_snapshots] {{sprache|en}}
*[http://www.mikerubel.org/computers/rsync_snapshots/ Mike Rubel rsync_snapshots] {{sprache|en}}
*[http://rsnapshot.org/ rsnapshot.org] {{sprache|en}}
*[http://rsnapshot.org/ rsnapshot.org] {{sprache|en}}
*[[rsync]] ArchWiki {{sprache|de}}
*[[Systemd/Timers]]  ArchWiki {{sprache|de}}
*[[Backups]] ArchWiki {{sprache|de}}
*[https://wiki.ubuntuusers.de/rsnapshot/ rsnapshot Ubuntuuser] {{sprache|de}}
*[https://wiki.ubuntuusers.de/rsnapshot/ rsnapshot Ubuntuuser] {{sprache|de}}
*[[Rsnapshot]] ArchWiki {{sprache|de}}
*[https://wiki.archlinux.org/index.php/Synchronization_and_backup_programs Backup Programs] ArchWiki {{sprache|en}}
*[[en:Backup Programs]]
 
[[Kategorie:Systemverwaltung]]
[[Kategorie:Services]]
[[Kategorie:Tipps und Tricks]]
[[Kategorie:Scripte]]

Aktuelle Version vom 17. August 2024, 12:53 Uhr

Dies ist Beispiel und Anleitung für ein automatisches, rotierendes und inkrementelles Backup. Das hier verwendete Skript (Original von Mike Rubel im Anhang) baut auf dem rsync Befehl auf und sichert die Daten täglich, wöchentlich und monatlich. Hierzu wird ein Systemd-Timer genutzt. Das original Skript entstand 2004 und fand so viel Anklang, dass es in Perl übersetzt wurde und als rsnapshot Einzug in den Befehlspool von Linux hielt. Wer den Befehl diesem Skript vorzieht, kann auch diesen benutzen. Das Endergebnis dürfte jedoch gleich sein da beide rsync zum Speichern der Dateien einsetzen.

Hinweis: Da die Sicherung auf einer lokalen Festplatte stattfindet, kann sie weder bei Feuer noch bei einem Einbruch vor Datenverlust schützen.

Durch das automatische Sichern stellen Festplattendefekte und versehentliches Löschen keine Gefahr mehr da. Durch das rotierende Verfahren hat man die Möglichkeit, auf mehrere gesicherte Dateiversionen zuzugreifen. Trotzdem bleibt die Datenmenge gering. Rsync speichert die Daten jeweils nur einmal physisch ab und erstellt die einzelnen Schichten mittels Hardlinks. Da immer nur die jeweils veränderten Daten neu gesichert werden, ist die Geschwindigkeit des backups hervorragend.

Anleitung

Die Sicherungs-Festplatte

Der Sicherungs-Datenträger sollte fest in den Rechner verbaut werden. Der Datenträger muss ausreichend groß sein. Die folgenden Schritte sind als Beispiel zu verstehen:

Partitionieren

Der Datenträger wird wie in fdisk bzw. gdisk beschrieben mit 1. Partition versehen.

Formatieren

Als Format eignet sich ext4. Fat Systeme unterstützen keine Hardlinks.

mkfs.ext4 /dev/sdx1

Datenträger Benennen

Der Datenträger erhält das Label SICHERUNG

e2label /dev/sdx1 SICHERUNG

Festplatte Einhängen

Ein Verzeichnis SICHERUNG auf root (/) anlegen

mkdir /SICHERUNG

/etc/fstab

öffnen mit

nano /etc/fstab

und hier folgendes einfügen:

/dev/sdx1	/SICHERUNG	ext4	defaults	0	2

mounten

Das System Neustarten oder die Festplatte SICHERUNG auf /SICHERUNG ins Dateisystem einbinden.

mount /dev/sdx1 /SICHERUNG

Das Backup Skript

Falls auf dem System noch nicht vorhanden, wird jetzt rsync installiert.

pacman -S rsync

Das folgende Skript wird kopiert und als snapshot.sh in /usr/local/bin/ abgespeichert. Mit einem chmod a+rx /usr/local/bin/snapshot.sh wird es ausführbar gemacht.

Die CUSTOMIZING SECTION im Skript sollte auf die eigenen Gegebenheiten angepasst werden.

Die Datei snapshot_exclude.txt wird ebenfalls kopiert und nach /usr/local/bin/ gespeichert. Alle in der snapshot_exclude.txt gelisteten Dateien und Verzeichnisse werden von einer Sicherung ausgeschlossen.

Danach kann mit folgendem Befehl die Funktion überprüft werden. Das Backup wird mit Rootrechten ausgeführt.

snapshot.sh

Bein ersten Durchlauf werden alle Daten nach daily.0 kopiert. Bei einem erneuten Aufruf des Befehls wird daily.0 nach daily.1 kopiert. Danach wird die daily.0 mit dem aktuellen Stand aktualisiert. Bei der Angabe von DAYS=6 in der CUSTOMIZING SECTION; wird die spätere 7. Sicherung entweder als erste wöchentliche Sicherung umbenannt oder gelöscht, bevor die Sicherungen daily.5 bis daily.1 jeweils einen Zähler aufrücken.

Das Skript

#!/bin/bash
##
##      Script: snapshot.sh
## 
##      Creates daily, weekly and montly hardlink backupslices with rsync.
##
##      Version: 0.4
##
##      Original from:  Mike Rubel (http://www.mikerubel.org/computers/rsync_snapshots/)
## 
##      License:   LGPL
##
##      Disclaimer: Use this software on your own risk, it works for me but there are no guaranties at all.
## 
##      Changes from tuxnix:        *Only one systemd timer needed
##                                  *rsync.log
##                                  *Source directory choosable
##                                  
##                                              
## 
## ======================= CUSTOMIZING SECTION ========================

SOURCE='/NAS/  /home/tuxnix/'                        # Source needs a / at the end. More then only one SOURCE-Directories are possible (set ' ' marks).
EXCLUDES=/usr/local/bin/snapshot_exclude.txt         # full path of exludefile is needed

MOUNT_RO=true                                        # For remount with write protection set to true
MOUNT_DEVICE=/dev/disk/by-label/SICHERUNG            # Taget device
MOUNT_POINT=/SICHERUNG                               # Mount point of target device
TARGET=/SICHERUNG                                    # Target directory - full directory path of mounted device is needed

CHECK_HDMINFREE=true;         # Check free space
HDMINFREE=98;                 # Make a backup up to this percentage

DAYS=6;                       # Number of daily backups -1
WEEKS=3;                      # Number of weekly backups -1
MONTHS=11;                    # Number of monthly backups -1


# ---------------------- Check -----------------------------------------------------------------------------------------

# Make sure we're running as root
if (( `id -u` != 0 )); then { echo "Sorry, must be root.  Exiting..."; exit; } fi

# Check exludefile exists
if ! [ -f $EXCLUDES ] ; then { echo "Error: Exclude File $EXCLUDES missing"; exit; } fi


# Remount Device rw
if $MOUNT_RO ; then
        mount -o remount,rw $MOUNT_DEVICE $MOUNT_POINT
        if (( $? )) ; then
            echo "Error: could not remount $MOUNT_DEVICE readwriteable"
            exit
        fi
fi

# Check free space on disk
GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/'
if $CHECK_HDMINFREE ; then
        KBISFREE=`df /$TARGET | tail -n1 | sed -e "$GETPERCENTAGE"`
        if [ $KBISFREE -ge $HDMINFREE ] ; then
                echo "Error: Not enough space left for rotating backups!"
                logger "Error: Not enough space left for rotating backups!"
                exit
        fi
fi

# Give Source some time to wake up if needed.
ls $SOURCE > /dev/null
if (( $? )) ; then
    echo "Wait 10 seconds till $SOURCE device is arrivable."
    sleep 10
    ls $SOURCE > /dev/null
    if (( $? )); then
    echo "Can't read $SOURCE"
    exit
    fi
fi

# ---------------Rotate Monthly Snapshots------------------------------------------------------------------------------

if [ -d $TARGET/weekly.$WEEKS ] && ! [ -d $TARGET/monthly.0 ] ; then

    echo "mv $TARGET/weekly.$WEEKS $TARGET/monthly.0"
    mv $TARGET/weekly.$WEEKS $TARGET/monthly.0

elif [ -d $TARGET/weekly.$WEEKS ] && [ -d $TARGET/monthly.0 ] ; then

    STAMP_0=`stat -c %Y $TARGET/weekly.$WEEKS`
    STAMP_1=`stat -c %Y $TARGET/monthly.0`

    if [ $(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) -ge 30 ] ; then

           echo ""
           echo "Rotate Monthly Snapshots:"

# Step 1: Delete the oldest monthly snapshot, if it exists
           if [ -d $TARGET/monthly.$MONTHS ] ; then
                echo "rm -rf $TARGET/monthly.$MONTHS"
                rm -rf $TARGET/monthly.$MONTHS 
           fi

# Step 2: Shift the middle snapshots by one
           OLD=$MONTHS
           while [ $OLD -ge 1 ] ; do
                OLD=$[$OLD-1]
                if [ -d $TARGET/monthly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/monthly.$OLD $TARGET/monthly.$NEW"
                        mv $TARGET/monthly.$OLD $TARGET/monthly.$NEW
                fi
           done

# Step 3: move oldest weekly to monthly.0
            echo "mv $TARGET/weekly.$WEEKS $TARGET/monthly.0"
            mv $TARGET/weekly.$WEEKS $TARGET/monthly.0 
           
    fi
fi

# ---------------Rotate Weekly Snapshots------------------------------------------------------------------------------

if [ -d $TARGET/daily.$DAYS ] && ! [ -d $TARGET/weekly.0 ] ; then

    echo "mv $TARGET/daily.$DAYS $TARGET/weekly.0"
    mv $TARGET/daily.$DAYS $TARGET/weekly.0

elif  [ -d $TARGET/daily.$DAYS ] && [ -d $TARGET/weekly.0 ] ; then

    STAMP_0=`stat -c %Y $TARGET/daily.$DAYS`
    STAMP_1=`stat -c %Y $TARGET/weekly.0`

    #echo "$(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) days difference between $TARGET/daily.$DAYS and $TARGET/weekly.0"

    if [ $(( ($STAMP_0 - $STAMP_1)/(60*60*24) )) -ge 7 ] ; then

           echo ""
           echo "Rotate Weekly Snapshots:"

# Step 1: Delete the oldest weekly snapshot, if it exists
        if [ -d $TARGET/weekly.$WEEKS ] ; then
            echo "rm -rf $TARGET/weekly.$WEEKS"
            rm -rf $TARGET/weekly.$WEEKS
        fi

# Step 2: shift the middle snapshots by one.
        OLD=$WEEKS
        while [ $OLD -ge 1 ] ; do
                OLD=$[ $OLD - 1 ]
                if [ -d $TARGET/weekly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/weekly.$OLD $TARGET/weekly.$NEW"
                        mv $TARGET/weekly.$OLD $TARGET/weekly.$NEW
                fi
        done

# Step 3: move oldest daily to weekly.0
        echo "mv $TARGET/daily.$DAYS $TARGET/weekly.0"
        mv $TARGET/daily.$DAYS $TARGET/weekly.0
    fi
fi

# -----------------Rotate Daily Snapshots---------------------------------------------

           echo ""
           echo "Rotate Daily Snapshots:"

           if [ -d $TARGET/daily.$DAYS ] ; then
           echo "rm -rf $TARGET/daily.$DAYS"
                rm -rf $TARGET/daily.$DAYS
           fi

           OLD=$DAYS
           while [ $OLD -ge 2 ] ; do
                OLD=$[$OLD-1]
                if [ -d $TARGET/daily.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        echo "mv $TARGET/daily.$OLD $TARGET/daily.$NEW"
                        mv $TARGET/daily.$OLD $TARGET/daily.$NEW
                fi
           done

           echo ""
           echo "Copy Hardlinks:"
           if ! [ -d $TARGET/daily.0 ] ; then
                $MKDIR -p $TARGET/daily.0
           else
                echo "cp -al $TARGET/daily.0 $TARGET/daily.1"
                cp -al $TARGET/daily.0 $TARGET/daily.1 ;
                touch $TARGET/daily.1 --reference=$TARGET/daily.1/.timestamp
          fi

           echo ""
           echo "Starting Backup:"
           rsync -va --delete --delete-excluded --exclude-from="$EXCLUDES" --log-file=$TARGET/.rsync.log $SOURCE $TARGET/daily.0

           if ! [ $? = 24 -o $? = 0 ] ; then
                echo "rsync ended with ERRORS!"
                logger "rsync ended with ERRORS!"
                touch $TARGET/daily.0/.rsync_error
                touch $TARGET/daily.0/.timestamp
                exit
             else
                touch $TARGET/daily.0/.timestamp
                touch $TARGET/daily.0
                echo "Finished backup: $SOURCE to $TARGET with SUCCSESS"
                logger "Finished backup: $SOURCE to $TARGET with SUCCSESS"
           fi

if $MOUNT_RO ; then
        #echo "mount -o remount,ro $MOUNT_DEVICE $TARGET"
        mount -o remount,ro $MOUNT_DEVICE $TARGET
        if (( $? )); then
                echo "Error: Could not remount $TARGET readonly"
                exit
        fi
fi


## Datei: /[path]/snapshot_exclude.txt


Videos
tuxnix/.cache

Die Service-Unit erstellen

Folgende Datei erstellen und abspeichern.

#file /etc/systemd/system/snapshot.service

[Unit]
Description=snapshot.service

[Service]
ExecStart=/usr/local/bin/snapshot.sh


Die Timer-Unit erstellen

Folgende Datei erstellen und abspeichern.

#file /etc/systemd/system/snapshot.timer

[Unit]
Description=snapshot.timer

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=basic.target


Den Timer aktivieren

systemctl enable snapshot.timer

Nach einem Neustart sorgt nun systemd für das regelmäßige Erstellen der gewünschten Backups.


Anhang

Beim original script werden 3 verschiedene Optionen genutzt:

  • Option -d erstellt ein tägliches Backup.
  • Option -w erstellt ein wöchentliches Backup.
  • Option -m erstellt ein monatliches Backup.

Dem entsprechend sind auch 3 systemd-timer und 3 systemd-services mit den entsprechenden ExecStart Befehlen anzulegen.

Das original Skript

#!/bin/bash
## Datei ~/.scripts/snapshot.sh
##
##
##      Mike Rubel 2004.01.04 (http://www.mikerubel.org/computers/rsync_snapshots/)
##
## License:
##      LGPL  
##
## Disclaimer:
##      Use this software on your own risk, it works for me but there
##      are no guaranties at all
## ----------------------------------------------
##
## make_snapshotLC: 
##      Backup Script based on rsync
##      It creates Generation Backups for the levels daily, weekly and montly
##
## Version:
##      0.3
##
## Synopsis:
##       make_snapshotLC [OPTIONS]
##
## Description:
##      This script was adopted from Mike Rubels documentation from
##      http://www.mikerubel.org/computers/rsync_snapshots/
##      Based on Mikes handy rotating-filesystem-snapshot utility.
##      The basic idea is it makes rotating backup-snapshots of /home whenever called
##      A few elements came from
##      http://www.heinlein-support.de/web/support/wissen/rsync-backup/
##      An exclude list avoids to backup superflous files.
##
## Changes:
##      Instead of hourly, daily and weekly snapshots, daily, weekly and monthly 
##      snapshots are used.
##      Checking the available space on backup media
##      Free configurable number of snapshots for every single level
##      Everything packed into one script
##
## Options:
##      -d make the daily backup plus rotate
##      -w make the weekly backup
##      -m make the monthly backup
##      -h displays a short help text
## 
## Changelog:
##      --------
########################################################################

unset PATH      # suggestion from H. Milz: avoid accidental use of $PATH

# ------------- System Commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;
MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/bin/touch;
RSYNC=/usr/bin/rsync;
DF=/bin/df;
TAIL=/usr/bin/tail;
SED=/bin/sed;
SYNC=/bin/sync;
LOGGER=/usr/bin/logger;
CHMOD=/bin/chmod;
MKDIR=/bin/mkdir;

# ======================= CUSTOMIZING SECTION ==========================
MOUNT_DEVICE=/dev/sdX1;                  # Your Mount device - Ziel
MOUNT_RO=true;                          # For write protection set to true
SNAPSHOT_RW=/SICHERUNG/;                 # where to store the backups - Ziel-Ordner
EXCLUDES=/home/<user>.scripts/snapshot_exclude.txt;    # Create the backup_exclude file first!
CHECK_HDMINFREE=true;                   # Check free space
HDMINFREE=90;                           # Make a backup up to this percentage
DAYS=6;                                 # Number of daily backups -1
WEEKS=3;                                # Number of weekly backups -1
MONTHS=3;                               # Number of monthly backups -1
# ======================================================================

# Make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root.  Exiting..."; exit; } fi

# Check Argument
if [ $# != 1 ] ; then { $ECHO "Error: Wrong number of arguments.  \
#Vaild is one out of -d, -w, -m, -h" ; exit; } fi

# Check Customization
if ! [ -b $MOUNT_DEVICE ] ; then { $ECHO "Error: Mount device $EXCLUDES isn't valid" ; exit; } fi
if ! [ -d $SNAPSHOT_RW ] ; then  $MKDIR -p $SNAPSHOT_RW; fi
if ! [ -f $EXCLUDES ] ; then { $ECHO "Error: Exclude File $EXCLUDES missing" ; exit; } fi

# Check free space on disk
GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/';
if $CHECK_HDMINFREE ; then
        KBISFREE=`$DF /$SNAPSHOT_RW | $TAIL -n1 | $SED -e "$GETPERCENTAGE"`
        if [ $KBISFREE -ge $HDMINFREE ] ; then
                $ECHO "Error: Not enough space left for rotating backups!"
                $LOGGER "Error: Not enough space left for rotating backups!"
                exit
        fi
fi

# ------------- The Script itself --------------------------------------

if $MOUNT_RO ; then
        # Attempt to remount the RW mount point as RW; else abort
        $MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
        if (( $? )); then
                $ECHO "Error: could not remount $SNAPSHOT_RW readwrite";
                exit;
        fi;
fi;


case $1 in
# *********** Daily Backups ********************************************
        -d | -D) $ECHO "Starting Daily Backup..."
           # Rotating daily snapshots of /home  

           # Step 1: Delete the oldest snapshot, if it exists:
           # It is NOT moved to the weekly backups level since you can make hundreds of daily backups
           if [ -d $SNAPSHOT_RW/daily.$DAYS ] ; then
                $RM -rf $SNAPSHOT_RW/daily.$DAYS ;
           fi;

           # Step 2: Shift all other snapshots(s) by one, if they exist (e.g. 6->7...1->2)
           OLD=$DAYS;
           while [ $OLD -ge 2 ] ; do
                OLD=$[$OLD-1]
                if [ -d $SNAPSHOT_RW/daily.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        # Save date
                        $TOUCH $SNAPSHOT_RW/.timestamp -r $SNAPSHOT_RW/daily.$OLD
                        $MV $SNAPSHOT_RW/daily.$OLD $SNAPSHOT_RW/daily.$NEW
                        # Restore date
                        $TOUCH $SNAPSHOT_RW/daily.$NEW/.timestamp \
                                -r $SNAPSHOT_RW/.timestamp
                fi;
           done

           # Step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
           # If that exists 0->1
           if ! [ -d $SNAPSHOT_RW/daily.0 ] ; then
                $MKDIR -p $SNAPSHOT_RW/daily.0
                $TOUCH $SNAPSHOT_RW/daily.0/.timestamp
           else
                $CP -al $SNAPSHOT_RW/daily.0 $SNAPSHOT_RW/daily.1 ;
           fi;

           # Step 4: rsync from the system into the latest snapshot (notice that
           # rsync behaves like cp --remove-destination by default, so the destination
           # is unlinked first.  If it were not so, this would copy over the other
           # snapshot(s) too!
           $RSYNC                                                               \
                -va --delete --delete-excluded                          \
                --exclude-from="$EXCLUDES"                              \
                /home $SNAPSHOT_RW/daily.0 ;

           # Check return code
           # 0 = ok, 
           # 24 is also ok. It appears if files were changed or deleted while this script runs
           # Other return codes are Error -- see man (1) rsync
           if ! [ $? = 24 -o $? = 0 ] ; then
                $ECHO "Error: rsync finished on $MOUNT_DEVICE with errors!"
                $LOGGER "Error: rsync finished on $MOUNT_DEVICE with errors!"
           fi;

           # Step 5: update the mtime of daily.0 to reflect the snapshot time
           $TOUCH $SNAPSHOT_RW/daily.0 ;

           # Finished!
           $ECHO "Finished rsync backup on $MOUNT_DEVICE..."
           $LOGGER "Finished rsync backup on $MOUNT_DEVICE..."

           # For beeing on the secure site...
           $SYNC;;

           # And thats it for home.

# *********** Weekly Backup ********************************************
        -w | -W)$ECHO "Starting Weekly Backup..."
        
           # Step 1: Delete the oldest snapshot, if it exists
           if [ -d $SNAPSHOT_RW/weekly.$WEEKS ] ; then
                $RM -rf $SNAPSHOT_RW/weekly.$WEEKS ;
           fi;
           
           # Step 2: shift the middle snapshots(s) by one, if they exist 3->4 ..0->1
           OLD=$WEEKS;
           while [ $OLD -ge 1 ] ; do
                OLD=$[$OLD-1]
                if [ -d $SNAPSHOT_RW/weekly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        $MV $SNAPSHOT_RW/weekly.$OLD $SNAPSHOT_RW/weekly.$NEW ;
                fi;
           done

           # Step 3: Make a hard-link-only (except for dirs) copy of
           # daily.(max), assuming that exists, into weekly.0
           if [ -d $SNAPSHOT_RW/daily.$DAYS ] ; then
                $CP -al $SNAPSHOT_RW/daily.$DAYS $SNAPSHOT_RW/weekly.0 ;
           fi;;

# *********** Monthly Backup *******************************************
        -m | -M)$ECHO "Starting Monthly Backup..."
        
           # Step 1: Delete the oldest snapshot, if it exists
           if [ -d $SNAPSHOT_RW/monthly.$MONTHS ] ; then
                $RM -rf $SNAPSHOT_RW/monthly.$MONTHS ;
           fi;
           
           # Step 2: Shift the middle snapshots(s) by one, if they exist 6->7 ..0->1
           OLD=$MONTHS;
           while [ $OLD -ge 1 ] ; do
                OLD=$[$OLD-1]
                if [ -d $SNAPSHOT_RW/monthly.$OLD ] ; then
                        NEW=$[ $OLD + 1 ]
                        $MV $SNAPSHOT_RW/monthly.$OLD $SNAPSHOT_RW/monthly.$NEW ;
                fi;
           done

           # Step 3: Make a hard-link-only (except for dirs) copy of
           # weekly.(max), assuming that exists, into monthly.0
           if [ -d $SNAPSHOT_RW/weekly.$WEEKS ] ; then
                $CP -al $SNAPSHOT_RW/weekly.$WEEKS $SNAPSHOT_RW/monthly.0 ;
           fi;;

        -h | -H)$ECHO "Usage:
              make_snapshot -d  Initiates daily backup
              make_snapshot -w  Initiates weekly backup
              make_snapshot -m  Initiates monthly backup
              make_snapshot -h  Displays this text."; exit;;
        
        *) $ECHO "Error: Wrong argument. Vaild is one out of -d, -w, -m, -h" ; exit;;

esac

$ECHO "Backup ended"
if $MOUNT_RO ; then
        # Now remount the RW snapshot mountpoint as readonly
        $MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
        if (( $? )); then 
                $ECHO "Error: Could not remount $SNAPSHOT_RW readonly";
                exit;
        fi;
 fi;

## Datei ~/.scripts/snapshot_exclude.txt
##
<user>/.cache
<user>/.kodi
<user>/.local/share
<user>/.mediathek3
<user>/.mozilla
<user>/.tor-browser-de
<user>/.tvbrowser
<user>/Videos

Siehe auch

Weblinks