web-dev-qa-db-fra.com

Script pour une sauvegarde incrémentielle du système de fichiers

Je voudrais exécuter le script incomplet suivant chaque semaine en tant que tâche cron pour sauvegarder mon répertoire personnel sur un lecteur externe monté en tant que/mnt/backups

#!/bin/bash
#

TIMEDATE=$(date +%b-%d-%Y-%k:%M)

LASTBACKUP=pathToDirWithLastBackup

rsync -avr --numeric-ids --link-dest=$LASTBACKUP /home/myfiles /mnt/backups/myfiles$TIMEDATE

Ma première question est de savoir comment définir correctement LASTBACKUP sur le répertoire dans lequel le dernier répertoire a été créé.

Deuxièmement, j'ai l'impression que l'utilisation de --link-desk signifie que les fichiers des sauvegardes précédentes ne seront pas copiés dans les sauvegardes ultérieures s'ils existent toujours, mais qu'ils renverront plutôt symboliquement vers les fichiers copiés à l'origine. Cependant, je ne veux pas conserver les anciens fichiers pour toujours. Quel serait le meilleur moyen de supprimer toutes les sauvegardes avant une certaine date sans perdre les fichiers pouvant être liés aux sauvegardes actuelles par ces sauvegardes? Fondamentalement, je cherche à fusionner tous les fichiers avant une certaine date à une certaine date si cela est plus logique que la façon dont j'ai initialement formulé la question :). --Link-dest peut-il créer des liens durs, et si c'est le cas, la suppression des répertoires précédents ne supprime pas réellement le fichier lié?

Enfin, j'aimerais ajouter une ligne à mon script qui compresse chaque nouveau dossier de sauvegarde créé (/ mnt/backups/myfiles $ TIMEDATE). Basé sur lisant cette question , je me demandais si je pouvais simplement utiliser cette ligne

gzip --rsyncable /backups/myfiles$TIMEDATE

après avoir exécuté rsync afin que les exécutions séquentielles de rsync --link-dest retrouvent les fichiers déjà copiés et compressés?

Je sais que c'est beaucoup, merci d'avance pour votre aide !!

3
Evan

Vous souhaiterez peut-être utiliser un outil qui automatise l'intégralité du processus, tel que rsnapshot , qui semble implémenter ce que vous essayez de faire.

7
Ryan Thompson

Une question à la fois, je vais seulement répondre à la première question et vous pouvez poster les autres à une autre question:

Pour savoir quel était le dernier répertoire de sauvegarde, vous ajoutez simplement:

echo /mnt/backups/myfiles$TIMEDATE > /mnt/backups/last.dir

À la toute fin du script, puis modifiez votre LASTBACKUP = en:

LASTBACKUP=`cat /mnt/backups/last.dir`

De cette façon, vous savez toujours que vous allez utiliser le dernier répertoire de sauvegarde complet et pas les autres fichiers/dossiers créés dans ce répertoire, ni les dossiers de sauvegarde qui ont échoué (ce qui créerait une masse de duplication).

Vous pouvez utiliser rsync.

Listing one: make_snapshot.sh

#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------

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;


# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;
EXCLUDES=/usr/local/etc/backup_exclude;


# ------------- the script itself --------------------------------------

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

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


# rotating snapshots of /home (fixme: this should be more general)

# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then         \
$RM -rf $SNAPSHOT_RW/home/hourly.3 ;                \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ] ; then         \
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3 ; \
fi;
if [ -d $SNAPSHOT_RW/home/hourly.1 ] ; then         \
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2 ; \
fi;

# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ] ; then         \
$CP -al $SNAPSHOT_RW/home/hourly.0 $SNAPSHOT_RW/home/hourly.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/home/hourly.0 ;

# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0 ;

# and thats it for home.

# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
    exit;
} fi;

et le deuxième:

Listing two: daily_snapshot_rotate.sh

#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility: daily snapshots
# ----------------------------------------------------------------------
# intended to be run daily as a cron job when hourly.3 contains the
# midnight (or whenever you want) snapshot; say, 13:00 for 4-hour snapshots.
# ----------------------------------------------------------------------

unset 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;

# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;

# ------------- the script itself --------------------------------------

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

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


# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/daily.2 ] ; then          \
$RM -rf $SNAPSHOT_RW/home/daily.2 ;             \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/daily.1 ] ; then          \
$MV $SNAPSHOT_RW/home/daily.1 $SNAPSHOT_RW/home/daily.2 ;   \
fi;
if [ -d $SNAPSHOT_RW/home/daily.0 ] ; then          \
$MV $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1;    \
fi;

# step 3: make a hard-link-only (except for dirs) copy of
# hourly.3, assuming that exists, into daily.0
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then         \
$CP -al $SNAPSHOT_RW/home/hourly.3 $SNAPSHOT_RW/home/daily.0 ;  \
fi;

# note: do *not* update the mtime of daily.0; it will reflect
# when hourly.3 was made, which should be correct.

# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
    exit;
} fi;

Après avoir créé le script selon vos besoins, ajoutez-le aux tâches cron.

crontab -e

ajoutez ce qui suit:

0 */4 * * * /usr/local/bin/make_snapshot.sh

0 13 * * * /usr/local/bin/daily_snapshot_rotate.sh

Make_snapshot.sh est exécuté toutes les quatre heures et daily_snapshot_rotate.sh tous les jours à 13h00 (c'est-à-dire à 13h00).

source: http://www.mikerubel.org/computers/rsync_snapshots/

* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Si vous voulez qu'il fonctionne toutes les heures, vous devez ajouter un travail cron pour chaque heure.

Une autre option possible consiste à utiliser rsnapshot

  1. Installez rsnapshot (disponible dans le centre logiciel)

  2. Configurer rsnapshot et spécifier le répertoire source de sauvegarde

Ouvrez le fichier /etc/rsnapshot.conf et décommentez les lignes suivantes.

# nano /etc/rsnapshot.conf

cmd_cp          /bin/cp
cmd_ssh /usr/bin/ssh
cmd_du          /usr/bin/du
cmd_rsnapshot_diff      /usr/local/bin/rsnapshot-diff
logfile /var/log/rsnapshot
  1. Définissez vos répertoires de sauvegarde de destination dans /etc/rsnapshot.conf comme indiqué ci-dessous. Dans cet exemple,

    / home - répertoire source à sauvegarder localhost/- répertoire de destination où la sauvegarde sera stockée. Veuillez noter que ce répertoire sera créé dans le répertoire /.snapshots/{internal.n}/, comme indiqué à la dernière étape.

    nano /etc/rsnapshot.conf

    sauvegarde/home/localhost /

  2. Testez la configuration de rsnapshot

Effectuez un test de configuration pour vous assurer que rsnapshot est correctement configuré et prêt à effectuer une sauvegarde linux rsync.

# rsnapshot configtest
Syntax OK
  1. Vérifier la configuration de sauvegarde horaire de rsnapshot

Vous pouvez sauvegarder des répertoires ou des fichiers linux à différents intervalles. Par défaut, les sauvegardes horaires et quotidiennes sont configurées.

Vérifiez la configuration de sauvegarde horaire.

# rsnapshot -t hourly
echo 6490 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /home \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /etc \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded \
/usr/local /.snapshots/hourly.0/localhost/
touch /.snapshots/hourly.0/
  1. Vérifier la configuration de la sauvegarde quotidienne de rsnapshot

Vérifiez que le processus de sauvegarde quotidien de rsnapshot cwrsync est configuré correctement.

# rsnapshot -t daily
echo 6493 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
/.snapshots/hourly.5 not present (yet), nothing to copy
  1. Ajouter une entrée Crontab pour rsnapshot

Une fois que vous avez vérifié que les configurations de sauvegarde horaire et quotidienne rsync sont correctement configurées dans l'utilitaire rsnapshot cwrsync, il est temps de configurer ce chiot dans la crontab, comme indiqué ci-dessous.

# crontab -e
0 */4 * * * /usr/local/bin/rsnapshot hourly
30 23 * * * /usr/local/bin/rsnapshot daily

source: http://www.thegeekstuff.com/2009/08/tutorial-backup-linux-using-rsnapshot-rsync-utility/

2
cprofitt

Je vais donc essayer de répondre à la deuxième (et troisième) question: --link-dest crée des liens physiques supplémentaires vers des fichiers existants du système de fichiers cible. Le nombre après les autorisations d'accès est le "nombre de liens", il vous indique le nombre de liens (pensez aux noms de fichiers) pointant vers le fichier. Par exemple:

$ touch x
$ ls -l
-rw-rw-r-- 1 frank frank 0 2011-01-07 22:18 x
$ ln x y
$ ls -l
-rw-rw-r-- 2 frank frank 0 2011-01-07 22:18 x

Vous pouvez simplement rm -rf anciennes sauvegardes. rm signifie unlink. Cela diminue le nombre de liens d'un fichier. Un système de fichiers écrasera uniquement les fichiers avec un nombre de liens égal à zéro. Si vous créez des fichiers supplémentaires avec gzip, ils utiliseront simplement davantage d’espace et vous perdrez l’avantage des liens physiques.

1
Frank