Réalisé par Neorom : - Dernière mise à jour : 29/01/09 à 15h18.
Fonctionnement
Ce script de sauvegarde, permet le backup de divers serveurs de données pures et de bases de données. Il est développé en Bash et est compatible avec Linux Debian 4.0 testing. La philosophie du programme de sauvegarde expliqué ici est de synchroniser les repertoires distants avec le serveur de sauvegardes. Ceci tout en gardant une copie complète de chaque donnée copiée et cela pour chaque jour. Nous allons voir en détail chaque fonction du programme afin que tout soit plus clair pour l'intégration de ce programme dans votre architecture.
Pré-requis
Plan
1. Introduction et architecture du disque de sauvegarde
Nous nous plaçons dans le cas ou nous avons créé un répertoire /backups et que le disque qui assurera le stockage des sauvegardes est monté sur ce repertoire.
L'architecture générale :
Répertoire qui contient tous les backups de l'architecture backupée
Répertoire qui contient tous les backups de la machine machine1
Répertoire qui contient tous les backups de la machine machine1 sur le nombre de jours définits (si on définit 3 jours de backups, les 3 erniers jours de backups seonrt dans ce répertoire).
Répertoire qui contient la copie courante synchronisée avec la machine distante. Ce repertoire n'est pas compréssé car il est utilisé à chaque backup. C'est lui qui récupère le différentiel chaque nuit avant d'archiver le tout.
Répertoire qui contient les backups de la journée du 21 Janvier 1009 de la machine 1
Répertoire qui contient les backups des semaines précédentes, en effet on va pouvoir paramétrer le fait d'archiver une journée par semaine sur 3 semaines par exemple. Tout dépend de la taille de votre disque.
Répertoire qui contient les logs liés aux backups.
Tous les répertoires vu précédement sont à créér manuellement pour chacune de vos machines à sauvegarder, sauf pour les répertoires des dates qui sont créés de façon hebdomadaire.
2. Fichiers de configuration
Nous allons voir le fichier de configuration général localisé en /backups/bashups.conf :
############################################################### #################VARIABLES GENERALES######################### ############################################################### #commande de compression des archives TAR="tar cfvz" #extension des archives BACKUP_EXTENSION="tar.gz" #date du jour DATE=`date "+%d-%m-%Y"` #jour JOUR=`date "+%d"` #archivage le 1er jour de la semaine (lundi) JOUR_ARCHIVES="1" #numero du jour actuel dans la semaine JOUR=`date "+%w"` # nombre de jours ou l'on conserve les backups journaliers DATE_J3=`date --date "3 days ago" "+%d-%m-%Y"` # nombre de semaine ou l'on conserve les backups des semaines precedentes DATE_M2=`date --date "3 weeks ago" "+%d-%m-%Y"` # commande de synchronisation des repertoires RSYNC="rsync -avz -e ssh --delete" # fichiers logs BACKUP_FILE="/backups/logs/backups.log" ############################################################### ######VARIABLES SPECIFIQUES A L ARCHITECTURE BACKUPEE####### ############################################################### # serveurs server_1="machine1.domaine.fr" server_2="machine2.domaine.fr" server_2="machine3.domaine.fr" # utilisateurs de backup ssh user_serveur1="sav" user_serveur2="sav" user_serveur3="sav" #fichiers listant les repertoires a backuper file_machine1="/backups/machine1.txt" file_machine2="/backups/machine2.txt" file_machine3="/backups/machine3.txt" # repertoires locaux pour les backups journaliers rep_machine1="/backups/machine1/jours" rep_machine2="/backups/machine2/jours" rep_machine3="/backups/machine3/jours" # repertoires locaux pour les backups hebdomadaires rep_machine1_archive="/backups/machine1/semaine-precedente" rep_machine2_archive="/backups/machine2/semaine-precedente" rep_machine3_archive="/backups/machine3/semaine-precedente" ############################################################### ######VARIABLES SPECIFIQUES AU MYSQL######################### ############################################################### # Requete SQL listant toutes les bases SQL_LIST_DB="SHOW DATABASES;" #User SQL qui va effectuer le backup MYSQL_USER="root" #Pass de machines backupees mysql_root_password_machine1="" mysql_root_password_machine2=""
Maintenant que nous avons définit les variables générales nécessaires au bon fonctionnement des backups, nous allons voir la structures des fichiers qui décrivents quels répertoires sauvegarder sur vos serveurs.
Nous aurons donc :
/backups/machine1.txt
/backups/machine2.txt
/backups/machine3.txt
Exemple d'un fichier à avoir pour la machine 1 : /backups/machine1.txt
/etc /root /home/toto /home/titi /var/log /home/particulier
3. Clefs partagées
Il faut donc que l'utilisateur qui va executer le programme de backups sur la machine ai des clefs partagées sur les machines distantes. Comme vu dans le fichier de configuration, on peut créer un utilisateur sur chacune des machines sauvegardées qui sera utilisé pour les sauvegardes.
Un tutoriel pour créer des clefs partagées existe déjà, et il est ici : Lien vers le tutoriel des clefs partagées
4. Fonction : f_rsync
Nous allons maintenant voir les differentes fonctions qui composent le script bashups.sh. La première est la fonction f_rsync. Celle-ci permet de synchroniser les répertoires listés dans un fichier. On va synchroniser les repertoires distants en local. A savoir que chaque fonction sera éxécutée pour chaque machine sauvegardée.
f_rsync
#
##Fonction de rsync des repertoires distant en local
#
#$1 = user
#$2 = server
#$3 = repertoire de backup
#$4 = fichier listant les repertoires a backuper
function f_rsync {
echo "`date` debut fonction rsync $2" >> $BACKUP_FILE
while read ligne
do
$RSYNC $1@$2:$ligne $3/rsync`sed -e 's/\/home//g' $ligne`
done < $4
echo "`date` fin fonction rsync $2" >> $BACKUP_FILE
}
# Fin fonction rsync
5. Fonction : f_copie_date
Cette fonction a pour but de faire une copie simple du répertoire rsync vers un dossier identique nommé par la date du jour.
f_copie_date
#
##Copie des fichiers du rsync dans un repertoire nomme a la date courante
#
#$1 = repertoire de backup
#$2 = server
function f_copie_date {
echo "`date` debut fonction copie_date $2" >> $BACKUP_FILE
cd $1
mkdir $1/$DATE
cp -rf $1/rsync/* $1/$DATE
echo "`date` fin fonction copie_date $2" >> $BACKUP_FILE
}
# Fin fonction copie_date
6. Fonctions : f_compress et f_compress_particulier
Ces deux fonctions sont là pour assurer la compression des répertoires inclus dans le répertoire nommé par la date du jour.
La première assure la compression de tous les répertoires présents dans le dossier de la date du jour. Il va tout compresser sauf un répertoire qui est particulier.
La situation que je vais exposer ci-après est assez particulière et si vous n'êtes pas dans ce cas vous pouvez remplacer dans la fonction f_compress la ligne :
for rep in `ls | sed -e \'/particulier/d\'`
par la ligne :
for rep in `ls `
et oublier la fonction f_compress_particulier.
Cas particulier
Ici le répertoire particulier qui ne sera pas compréssé par la fonction f_compress doit subir une routine légèrement différente. En effet la fonction f_compress_particulier va compresser chacun des sous-dossiers de ce repertoire. Ceci peut être justifié si on veut sauvegarder le home d'une machine avec tous les utilisateurs qui sont dedans sans compresser le home lui même mais en compressant le repertoire de chaque utilisateur. En effet si on a besoin d'accéder à un fichier d'un utilisateur, nous n'vons pas besoin de décompresser tout le home sauvegardé ce jour là mais uniquement son répertoire personnel.
Dans la fonction f_compress_particulier vue ci-dessous le répertoire sauvegardé est appelé : "particulier", on peut bien sur remplacer cette valeur par : "home", comme expliqué dans l'exemple précédent.
f_compress et f_compress_particulier
#
## Fonction qui compresse les repertoires du repertoire date
#
#$1 = repertoire de backup
#$2 = server
function f_compress {
echo "`date` debut fonction compress $2" >> $BACKUP_FILE
cd $1/$DATE
for rep in `ls | sed -e '/particulier/d'`
do
$TAR $rep-$DATE.$BACKUP_EXTENSION $rep
rm -rf $rep
done
echo "`date` fin fonction compress $2" >> $BACKUP_FILE
}
# Fin fonction compress
#
## Fonction qui compresse les repertoires d'un repertoire particulier
#
#$1 = repertoire de backup
#$2 = server
function f_compress_particulier {
echo "`date` debut fonction compress_particulier $2" >> $BACKUP_FILE
cd $1/$DATE/particulier
for rep in `ls`
do
$TAR $rep-$DATE.$BACKUP_EXTENSION $rep
rm -rf $rep
done
echo "`date` fin fonction compress_particulier $2" >> $BACKUP_FILE
}
# Fin fonction compress_particulier
7. Fonction : f_dump_sql
Cette fonction fait un dump sql d'un serveur. D'abord un dump compressé du serveur complet, puis un dump base par base chacune d'entre elles étant compressée également.
f_dump_sql
#
## Fonction de dump sql (un dump complet, ainsi qu'un dump base par base)
#
#$1 = repertoire de backups
#$2 = server
#$3 = sql root passqword
function f_dump_sql {
echo "`date` debut fonction dump_sql $2" >> $BACKUP_FILE
cd $1/$DATE
mkdir $1/$DATE/sql
cd sql
echo "`date` debut fonction dump all_databases $2" >> $BACKUP_FILE
mysqldump -u $MYSQL_USER -p"$3" -h $2 --all-databases > all-databases.$DATE.sql
$TAR all-databases-$DATE.sql.$BACKUP_EXTENSION all-databases.$DATE.sql
rm -f all-databases.$DATE.sql
echo "`date` fin fonction dump all_databases $2" >> $BACKUP_FILE
echo "`date` debut fonction dump base par base $2" >> $BACKUP_FILE
for database in `echo $SQL_LIST_DB | mysql -u $MYSQL_USER -p"$3" -h $2 | sed 1d`
do
mysqldump -p"$3" -u $MYSQL_USER -h $2 --databases $database > $database-$DATE.sql
$TAR $database-$DATE.sql.$BACKUP_EXTENSION $database-$DATE.sql
rm -f $database-$DATE.sql
done
echo "`date` fin fonction dump base par base $2" >> $BACKUP_FILE
echo "`date` fin fonction dump_sql $2" >> $BACKUP_FILE
}
# Fin fonction dump_sql
8. Fonction : f_archive
Cette fonction va s'assurer du rangement de l'architecture de backups. Elle va effacer donc les répertoires qui sont trop vieux dans /jours et dans /semaine-precedente en fonction des variables mises dans le fichier de configuration. Mais elle va également s'assurer de la bonne copie des répertoires /jours dans /semaine-precedente au jour de la semaine indiqué dans le fichier de configuration par la variable JOUR_ARCHIVES.
f_archive
#
# Fonction qui range les repertoires (efface les vieux) et met dans semaine-precedente les backups a garder
#
#$1 = repertoire de backups
#$2 = repertoire d'archives
#$3 = server
function f_archive {
echo "`date` debut fonction archive $3" >> $BACKUP_FILE
if [ $JOUR_ARCHIVES -eq $JOUR ]
then
cp -rf $1/$DATE /$2/
fi
rm -rf $1/$DATE_J3
rm -rf $2/$DATE_M2
echo "`date` fin fonction archive $3" >> $BACKUP_FILE
}
# Fin fonction archive
9. Main du programme
C'est ici que toutes les fonctions expliquées précédement sont exécutées. Comme on peut le voir chaque fonction est exécutée pour chaque machine sauvegardée. Sans oublier d'inclure nos variables du fichier de configuration au début.
Main
################################################################## ##########################MAIN################################### ################################################################## #include du fichier de conf . "/backups/backups.conf" f_rsync $user_machine1 $server_machine1 $rep_machine1 $file_machine1 f_rsync $user_machine2 $server_machine2 $rep_machine2 $file_machine2 f_rsync $user_machine3 $server_machine3 $rep_machine3 $file_machine3 f_copie_date $rep_machine1 $server_machine1 f_copie_date $rep_machine2 $server_machine2 f_copie_date $rep_machine3 $server_machine3 f_compress $rep_machine1 $server_machine1 f_compress $rep_machine2 $server_machine2 f_compress $rep_machine3 $server_machine3 f_compress_hebergements $rep_machine1 $server_machine1 f_compress_hebergements $rep_machine2 $server_machine2 f_dump_sql $rep_machine1 $server_machine1 $mysql_root_password_machine1 f_dump_sql $rep_machine2 $server_machine2 $mysql_root_password_machine2 f_archive $rep_machine1 $rep_machine1_archive $server_machine1 f_archive $rep_machine2 $rep_machine2_archive $server_machine2 f_archive $rep_machine3 $rep_machine3_archive $server_machine3
10. Lancement
Pour lancer notre programme il suffit de le rendre exécutable et de le mettre en cron sur la machine qui fera le backup. Le premier backup sera surement très long, mais une fois celui-ci fait après, uniquement le différentiel transitera sur le réseau. Ce programme prend donc tout son intéret lorsque l'on doit sauvedarger beaucoup de données depuis une petite connexion internet.
Lancement en cron (/etc/crontab)
00 2 * * * sav sh /backups/bachups.sh > /backups/logs/cron.log
11. Conclusion
Nous venons de voir pas à pas un système de sauvegarde, celui ci est assez standard mais sera quand même ammené à évoluer. Une chose qui serait intéressante de faire évoluer serait de pouvoir avoir plusieurs répertoires "particulier" pouvant être spécifiés dans le fichier de configuration. N'hésitez pas à nous envoyez un mail pour toute question.
12. Téléchargement
Cliquez ici pour lancer le téléchargement