Automatische Sicherung (Beispiel)

Aus wiki.archlinux.de
Version vom 30. März 2017, 03:45 Uhr von Tuxnix (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „{{inuse|Tuxnix (Diskussion)}} Kategorie:Systemverwaltung Kategorie:Services {{righttoc}} Dies ist B…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Construction.png „Automatische Sicherung (Beispiel)“ wurde von Tuxnix (Diskussion) als in Bearbeitung markiert. Um Bearbeitungskonflikte zu vermeiden, kontaktiere Tuxnix (Diskussion) bitte, bevor du den Artikel bearbeitest.



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. Systemd/Timers werden genutzt um das Backup täglich, wöchentlich und monatlich automatisch vorzunehmen.

Hinweis: Da die Sicherung lediglich auf eine zweite lokale Festplatte stattfindet, kann diese Sicherung bei Feuer oder Diebstahl nicht vor Datenverlust schützen. Auch wenn Schädlinge mit Administrationsrechten auf Linux sehr unwahrscheinlich sind, muss hier auf diese Gefahr hingewiesen werden.

Als Backup im privaten Bereich leistet es aber durchaus gute Dienste. 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.

Anleitung

Die Sicherungs-Festplatte

Eine Festplatte an den Rechner anschließen.

rsync

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

sudo pacman -S rsync

Das Backup Skript

Das folgende Skript wird kopiert und als backup.sh z.B. in ~/scripts/ abgespeichert und mit chmod a+rx ~/scripts/backup.sh ausführbar gemacht. Die CUSTOMIZING SECTION im Skript sollte auf die eigenen Wünsche und Gegebenheiten angepasst werden.

Die Datei backup_exclude.txt wird ebenfalls kopiert und nach ~/scripts/ abgespeichert. Die hier gelisteten Dateien werden von der Sicherung ausgeschlossen.

Danach kann mit folgendem Befehl die Funktion überprüft werden. Das Argument -d erstellt ein tägliches Backup. Das Backup wird mit Rootrechten ausgeführt.

sudo ~/scripts/backup.sh -d

Das backup.sh Script

#!/bin/bash
##
##      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/sdb1;                  # Your Mount device - Ziel
MOUNT_RO=false;                          # For write protection set to true
SNAPSHOT_RW=/SICHERUNG/;                 # where to store the backups - Ziel-Ordner
EXCLUDES=/home/scripts/backup_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;


backup_exclude.txt

/home/<user>/.cache
/home/<user>/.tvbrowser
/home/<user>/.mozilla/firefox
/home/<user>/MEDIEN/

Eine Service-Unit erstellen

Die Timer-Units erstellen

Weblinks

Mike Rubel rsync_snapshots rsync Systemd/Timers