Automatyczne backupy w stylu snapshot z rsync’iem

Można znaleźć wiele tutoriali jakimi narzędziami wykonywać backupy. W większości przypadków absolutnie wystarczający okaże się flexbackup. Bardziej wymagający wykorzystają BackupPC, Baculę lub Amandę. Narzędzia te pozwalają wykonać kopie pełne, różnicowe, przyrostowe – kompresując je dla zaoszczędzenia miejsca.

Wszystko fajnie – ale problemy pojawiają się przy dostępie do tych danych. Żeby odzyskać plik zmodyfikowany dzisiaj trzeba rozpakować najpierw kopię pełną, potem różnicową, przyrostową by wreszcie wyciągnąć plik z wczoraj… hmm ten też jest skopany. No to lecimy jeszcze raz…

Dodatkowo jeżeli danych jest kilkadziesiąt GB to cały proces wielokrotnej dekompresji może trwać nawet kilka godzin. Zacząłem szukać alternatywnej metody backupowania i trafiłem na ciekawy artykuł na podstawie, którego opracowałem własny skrypt do backupu: http://www.mikerubel.org/computers/rsync_snapshots/

#!/bin/bash

# zdalny serwer z którego chcemy wykonać backup
RHOST="server.test.pl"

# zasoby rsync ze zdalnego serwera które zostaną zsynchronizowane
BACKUPDIRS=("backup" "home" "mails")

# lokalny katalog do którego trafi backup
DSTDIR="/srv/backup/server"

# maksymalny czas przechowywania backupów wyrażony w dniach
MAXAGE=33

# dodatkowe opcje dla rsynca (--verbose można zastąpić --quiet
# łatwiej zauważyć wtedy błędy), można włączyć kompresje
# w przypadku synchronizacji ze zdalnej lokalizacji
OPTIONS="--del --verbose"

# plik z hasłem dla rsync'a - zabezpieczenie marne ale w izolowanej
# sieci dopuszczalne
PASS="/root/.rsync-passwd"

DATE=`date +'%Y.%m.%d'`
YESTERDAY=`ls -1 $DSTDIR | sort | tail -n1`
LINKDEST=$DSTDIR/$YESTERDAY

# prosty mechanizm lock'a by uniemożliwić wielokrotne uruchomienie
# skryptu, np. w sytuacji gdy nie zdąży wykonać się pełny backup
# przed kolejnym wywołaniem
if [ -f "/tmp/server_sync" -o -f "/tmp/server_sync_block" ]; then
        echo "Another sync is still running!"
        exit 1
fi
touch /tmp/server_sync

# wykonujemy kolejno kopie
for DIR in ${BACKUPDIRS[@]}; do
    mkdir -p $DSTDIR/$DATE/$DIR

    # sprawdzenie czy mamy wcześniejszy backup,
    # jak mamy to robimy snapshot
    if [ -d "$DSTDIR/$YESTERDAY/$DIR" ]; then
        rsync -a --link-dest=$LINKDEST/$DIR \
            backup@$RHOST::archive/$DIR/ \
            $DSTDIR/$DATE/$DIR/ \
            --password-file=$PASS $OPTIONS
    else # jak nie mamy to robimy nowy
        rsync -a backup@$RHOST::archive/$DIR/ \
            $DSTDIR/$DATE/$DIR/ \
            --password-file=$PASS $OPTIONS
    fi

    # sprawdzenie czy synchronizacja się udała
    # jeśli się nie udała to możemy chcieć skasować niedokończony
    # backup by kolejny nie musiał być "prawie pełnym"
    # plik /tmp/server_sync_block trzeba skasować ręcznie
    if [ $? -ne 0 -a $? -ne 24 ]; then
        echo "Something was wrong becase rsync return $?"
            touch /tmp/server_sync_block
            exit 2
    fi
done

# zwalnianie lock'a
rm -f /tmp/server_sync

# kasowanie najstarszych backupów
find $DSTDIR -maxdepth 1 -type d -mtime +$MAXAGE \
    -print0 | xargs -0 -r rm -r

Leave a Reply

Your email address will not be published. Required fields are marked *