• Faire un backup incrémental avec un simple bash

    Faire un backup incrémental avec un simple bash

    J'ai bricolé un bash pour faire des sauvegardes incrémentales quotidiennes de l'ensemble des blogs d'EklaBlog, et j'ai décidé de vous en faire cadeau Il n'y a rien d'exceptionnel, mais l'astuce n'est pas toujours facile à trouver sur le net, et cela évite d'installer des logiciels comme backup-manager.

    J'avais déjà écrit un article au sujet des backups, qui est un peu plus complet sur la description de rsync et de cron, mais il ne traitait pas des sauvegardes incrémentales.

    L'avantage de ce script par rapport à certains autres que l'ont peut trouver sur l'intraweb, c'est que ce script crée un dossier par jour, et que chaque dossier de sauvegarde est totalement utilisable seul. Je dis ça car généralement, on utilise la fonction --backup de rsync qui se contente de garder les fichiers modifiés dans un autre dossier, ce qui ne permet pas de récupérer facilement la sauvegarde totale d'un jour. Au contraire, ce script crée une copie totale de chaque jour, tout en minimisant l'espace disque utilisé (Un même fichier présent dans plusieurs sauvegardes ne sera écrit qu'une seule fois sur le disque).

    Ce script peut fonctionner aussi bien pour la sauvegarde des sites que pour la sauvegarde de fichiers personnels situés sur un ordinateur. Le principal, c'est que le serveur (ordinateur qui contient les données à sauvegarder) ait un serveur ssh, et que le client (ordinateur sur lequel vont être stockées les données) ait la commande rsync. Ca fonctionne sous Linux, et normalement ça devrait être pareil sur Mac.

    Pour installer ssh sur le serveur (s'il n'est pas installé) :

    sudo apt-get install openssh-server
    [code=bash]sudo apt-get install openssh-server[/code]

    Note : "sudo apt-get" fonctionne sur les machines utilisant le gestionnaire de paquets apt. Il se peut que vous ayez à en utiliser un autre, comme "yum". La commande "sudo" n'est pas nécessaire si vous êtes déjà en mode administrateur.

    Pour installer rsync sur le client :

    sudo apt-get install rsync
    [code=bash]sudo apt-get install rsync[/code]


    Passons maintenant au script en lui même :

    # Source du backup
    SRC=root@server:/home/dossier/a/sauvegarder
    # Destination du backup
    DST=/home/dossier/contenant/les/sauvegardes
    # Date de la forme année-mois-jour-timestamp
    # (le timestamp %s sert si on veut faire plusieurs sauvegardes dans la même journée)
    DATE=`date +%Y-%m-%d-%s`

    # Création du répertoire temporaire
    mkdir $DST/tmp

    echo "Backup commencé le "`date "+%d/%m/%Y à %T"`
    echo "Starting : "`date "+%Y-%m-%d %T"` >> $DST/log
    echo "Copie de la dernière sauvegarde..."

    # Si une sauvegarde a déjà été faite précédemment
    if test -d $DST/today ; then
        # Et si le fichier contenant la date de la dernière sauvegarde existe
        if test -f $DST/last_date ; then
       
            LASTDATE=`cat $DST/last_date`
            # Alors on fait un copie en hardlinks de la sauvegarde d'hier
            cp -al $DST/today $DST/tmp/
            # Puis on renomme la copie pour qu'elle devienne la sauvegarde d'hier
            mv $DST/tmp/today $DST/$LASTDATE
           
        fi
       
    # Sinon, on crée le premier dossier
    else
        mkdir $DST/today
    fi

    rm -rf $DST/tmp
    # On sauvegarde la date actuelle pour le prochain backup
    echo $DATE > $DST/last_date

    echo "Synchronisation de la sauvegarde du jour..."

    # Synchronisation de la source avec le dossier du jour
    rsync -az --delete --size-only $SRC/ $DST/today/

    echo "Backup terminé le "`date "+%d/%m/%Y à %T"`
    echo "Done : "`date "+%Y-%m-%d %T"` >> $DST/log
    [code=bash]# Source du backup
    SRC=root@server:/home/dossier/a/sauvegarder
    # Destination du backup
    DST=/home/dossier/contenant/les/sauvegardes
    # Date de la forme année-mois-jour-timestamp
    # (le timestamp %s sert si on veut faire plusieurs sauvegardes dans la même journée)
    DATE=`date +%Y-%m-%d-%s`

    # Création du répertoire temporaire
    mkdir $DST/tmp

    echo "Backup commencé le "`date "+%d/%m/%Y à %T"`
    echo "Starting : "`date "+%Y-%m-%d %T"` >> $DST/log
    echo "Copie de la dernière sauvegarde..."

    # Si une sauvegarde a déjà été faite précédemment
    if test -d $DST/today ; then
        # Et si le fichier contenant la date de la dernière sauvegarde existe
        if test -f $DST/last_date ; then
       
            LASTDATE=`cat $DST/last_date`
            # Alors on fait un copie en hardlinks de la sauvegarde d'hier
            cp -al $DST/today $DST/tmp/
            # Puis on renomme la copie pour qu'elle devienne la sauvegarde d'hier
            mv $DST/tmp/today $DST/$LASTDATE
           
        fi
       
    # Sinon, on crée le premier dossier
    else
        mkdir $DST/today
    fi

    rm -rf $DST/tmp
    # On sauvegarde la date actuelle pour le prochain backup
    echo $DATE > $DST/last_date

    echo "Synchronisation de la sauvegarde du jour..."

    # Synchronisation de la source avec le dossier du jour
    rsync -az --delete --size-only $SRC/ $DST/today/

    echo "Backup terminé le "`date "+%d/%m/%Y à %T"`
    echo "Done : "`date "+%Y-%m-%d %T"` >> $DST/log[/code]


    Et voilà, avec un fichier log en prime !
    Pour ceux qui ne comprennent pas trop le fonctionnement du script, c'est en fait assez simple :
    "cp -al ..." permet de faire une copie conforme d'un dossier mais en hardlinks, c'est-à-dire en dupliquant juste les noms des fichiers sur le disque dur. Un même fichier devient alors accessible depuis deux endroits différents (ou plus si on a plus d'une sauvegarde du fichier). Ensuite le rsync synchronise la source en ajoutant les nouveaux fichiers dans le dossier du jour, et en supprimant et modifiant les fichiers supprimés ou modifiés depuis la dernière sauvegarde. L'astuce, c'est que lorsque rsync modifie un fichier, il est d'abord supprimé puis réécrit, ce qui a pour effet de ne pas modifier les fichiers du même nom dans les sauvegardes antérieures.

    Le flag --size-only permet de ne synchroniser que les fichiers dont la taille a changé. Vous pouvez utilisez le flag -c (ou --checksum) pour vérifier plutôt la signature de chaque fichier, ce qui est plus sûr mais beaucoup plus long si votre dossier à sauvegarder est très volumineux.

    Il ne reste plus qu'à automatiser l'exécution du script sur votre pc (ça se passe côté client). Nous allons ajouter une ligne d'instruction dans les tâches cron. Pour faire simple, tapez la commande :

    sudo crontab -e
    [code=bash]sudo crontab -e[/code]

    Puis rajoutez la ligne :

    0 20 * * * /bin/bash /chemin/absolu/du/bash/qu/on/vient/de/creer.sh >/dev/null 2>&1
    [code=bash]0 20 * * * /bin/bash /chemin/absolu/du/bash/qu/on/vient/de/creer.sh >/dev/null 2>&1[/code]

    Pour plus de détails sur le cron, et surtout sur la manière de configurer ssh pour que le script puisse s'exécuter sans votre intervention qui est normlament nécessaire pour entrer le mot de passe ssh, vous pouvez consulter mon précédent article au sujet des backups.

    J'espère que ce petit script pourra vous être utile. J'attends vos retours et remarques


    Tags Tags : , , ,
  • Commentaires

    1
    Dimanche 1er Février 2009 à 21:49
    Salut Godefroy, tu vas recevoir ma contribution pour que vive Eklablog^^! Passe le bonjour à Divarvel et à très bientôt je l'espère!!
    2
    Dimanche 1er Février 2009 à 22:15
    Merci foxxy1, c'est très sympa
    3
    xiloa
    Mercredi 4 Février 2009 à 15:59
    Heuuuuu, en gros, c'est une time machine en bash ???? C'est super bon, pile ce que je cherchais. Merci
    4
    Lundi 16 Février 2009 à 21:57
    J'ai pas tenté (mon disque va exploser si je me mets à faire des backup... je dois vraiment acheter un DD externe), mais ça a bien une tête à rentrer dans Terminal. Quand je me serai agrandie, j'essaierai et je te dis ^^.
    5
    amance Profil de amance
    Jeudi 26 Février 2009 à 23:39
    L'est beau le chat.


    ...



    C'était un commentaire constructif.
    6
    Lundi 16 Mars 2009 à 16:54
    C'est super la sauvegarde des blogs!
    C'est ton chat sur la photo? En tout cas, il est mignon!^^
    7
    tenten2000 Profil de tenten2000
    Mercredi 6 Mai 2009 à 11:29
    c'est vrai
    8
    Lundi 28 Septembre 2009 à 20:34
    Juste un petit message pour te remercier, Skreo :)
    J'ai codé un script similaire (avec la gestion du temps en plus) il y a quelques temps, mais le script etait horrible et mal codé (genre 300 lignes, quand le tiens en fais 40). Merci ! :)
    9
    NicoLarve
    Mardi 13 Octobre 2009 à 14:32
    As-tu autre chose à proposer que les options rsync --size-only (peu fiable à mon goût car la sauvegarde d'un fichier modifié mais de même taille que dans la précédente sauvegarde va échouer) et --checksum ("lent")?
    Merci par avance pour cet article et ta réponse!
    10
    Jeudi 15 Octobre 2009 à 16:28
    @NicoLarve: il y a aussi l'option --update (-u en abrégé) qui ne met à jour que les fichiers plus récents. Mais le plus fiable reste bien sûr --checksum, qui par définition fait un checksum (création d'un hash identifiant le contenu) pour vérifier les différences entre les fichiers.
    11
    Guenael
    Mardi 22 Mars 2011 à 18:18

    Salut,

     

    Super article il conviens parfaitement a ce que je veux faire (une sauvegarde par 30 minutes avec timestamp !).

     

    Par contre j'ai peut etre mal compris mais comment faire pour que ,par exemple, il ne garde que les 20 dernieres sauvegardes /dossiers ?

     

    Merci

    12
    Jeudi 24 Mars 2011 à 23:15

    Pour supprimer les backups, je fais ça :

    INTERVAL=9
    for ((i=30; i >= 4; i--)) ; do
            if test $i -eq 17 ; then
                    INTERVAL=6
            fi
            if test $i -eq 7 ; then
                    INTERVAL=3
            fi
         if test $((`date -d "-$i days" "+%s"` / 86400 % $INTERVAL)) -ne 0 ; then
                    rm -rf $DST/`date -d "-$i days" "+%Y-%m-%d-"`*
            fi
    done

     

    Ça me permet de garder les 3 derniers jours, puis d'espacer de plus en plus les anciennes sauvegardes.

    13
    Guenael
    Vendredi 25 Mars 2011 à 01:42

    Parfait ,j'ai ajouté à la fin de mon script de sauvegarde cette partie.

    Par contre je trouve le posix timestamp pas évident à lire, j'imagine que c'est la seule possibilité ?

     

    Merci encore.

    14
    Mardi 29 Mars 2011 à 19:08

    Non ce n'est pas la seule possibilité. Vous pouvez donner le format que vous voulez aux noms de vos dossiers. Là j'ai choisi de prendre le format +%Y-%m-%d-%s car ça permet de classer facilement les dossiers par date et ça évite les doublons grâce au nombre de secondes (au cas où on ferait plusieurs backups dans la même journée).

    15
    Lundi 21 Novembre 2011 à 09:38

    Bonjour,

    Votre script est très efficace ! Cependant j'aimerai rajouter une petite fonctionnalité, mais j'ai beaucoup de mal avec les scripts shell !

    Ce que j'aimerai faire :

    En entrée au lieu d'avoir un repertoire SRC,  j'aimerai avoir un fichier avec un repertoire par ligne. Une boucle permettrait un backup de plusieurs repertoires indépendants. L'utilisateur pourrait ainsi modifier le contenu du backup très facilement sans avoir à modifier le script ou le cron.

    Merci pour votre aide.

    Frederic

    16
    Lundi 21 Novembre 2011 à 11:10

    Bonjour fred0306,

    En mettant un chemin de répertoire par ligne dans un fichier "backup_dirs", vous pouvez faire un script dans le genre :

    DIRS=$(cat backup_dirs | tr "\n" " ")
    for DIR in $DIRS ; do
        echo "backup $DIR"
        # Code du backup...
    done

    17
    Manoula
    Vendredi 30 Décembre 2011 à 14:51

    Bonjour, Je suis débutante en développement. La tache qui m'a été accordée est d'automatiser l'import des données de Whois ou register. SVP aidez moi à trouver un script qui traite ce travail.

    Merci d'avance. :)

    Suivre le flux RSS des commentaires de cet article


    Ajouter un commentaire

    Nom / Pseudo :

    E-mail (facultatif) :

    Site Web (facultatif) :

    Commentaire :