Arrêt des services avant sauvegarde

Bonjour à tous,

J’ai développé ce script :

[code]#!/bin/bash
##============================================================================

Fichier : backup.sh

Description : Script de sauvegarde synchronisee du disque dur du serveur

vers le disque dur externe.

##============================================================================

Parametres d’entree : aucun

Code de retour : 0

##============================================================================

##= PRELIMINAIRES ============================================================

log=$(tempfile)
:>$log

##= OUVERTURE DU VOLUME DE SAUVEGARDE ========================================

echo “Utilisation de /mnt/backup comme point de montage.” >>$log
mkdir /mnt/backup 2>>$log

echo “Ouverture du volume cryptsetup.” >>$log
cryptsetup luksOpen /dev/backup backup -d /etc/keys/luks-keyfile

echo “Montage de la partition de sauvegarde.” >>$log
mount -t ext4 /dev/mapper/backup /mnt/backup 2>>$log

On patiente pour laisser le temps au mount d’etre effectif.

sleep 5

echo >>$log

##= SAUVEGARDE ===============================================================

function sauvegarde {
# $1 nom du service
# $2 type de service
# 0 - pas de service
# 1 - demon ordinaire
# 2 - gere par inetd
# $3 repertoire source

# Arret du service
if [ $2 -eq 1 ]
then
    service $1 stop >/dev/null 2>>$log
elif [ $2 -eq 2 ]
then
    update-inetd --disable --multi $1 >/dev/null 2>>$log
fi

# Sauvegarde
echo "-- Sauvegarde de $3" >>$log
rsync \
    --exclude='*~' --delete-before --delete-excluded --stats --partial \
    -roglpthH $3 /mnt/backup/ >>$log
echo >>$log

# Reprise du service
if [ $2 -eq 1 ]
then
    service $1 start >/dev/null 2>>$log
elif [ $2 -eq 2 ]
then
    update-inetd --enable $1 >/dev/null 2>>$log
fi

}

#sauvegarde data 0 /srv/data
sauvegarde git 2 /srv/git
sauvegarde mail 0 /srv/mail
sauvegarde mpd 1 /srv/mpd
sauvegarde partimaged 1 /srv/partimage
sauvegarde prosody 1 /srv/prosody
sauvegarde git 2 /srv/reseau
#sauvegarde rsync 0 /srv/rsync
sauvegarde sauvegardes 0 /srv/sauvegardes
sauvegarde scripts 0 /srv/scripts
sauvegarde svn 2 /srv/svn
#sauvegarde transmission-daemon 1 /srv/transmission
sauvegarde apache2 1 /srv/www

##= DEMONTAGE DU VOLUME ======================================================

On patiente pour ne pas demonter un disque encore utilise.

sleep 5

echo “Retrait de la partition de sauvegarde.” >>$log
umount /mnt/backup 2>>$log

On attend que le disque soit demonte pour fermer le volume et retirer le

point de montage.

sleep 5

Fermeture du volume cryptsetup

cryptsetup luksClose backup

echo “Suppression du point de montage.” >>$log
rmdir /mnt/backup 2>>$log

##= ENVOI DU LOG PAR E-MAIL ET SUPPRESSION DU LOG ============================

#echo “Envoi du log par e-mail.” >>$log
mail -s “Sauvegarde sur le disque dur externe” monprenom@monnom.fr < $log

On supprime le log

rm $log

exit 0[/code]

Qui produit ce genre de log :

[code]Utilisation de /mnt/backup comme point de montage.
Ouverture du volume cryptsetup.
Montage de la partition de sauvegarde.

– Sauvegarde de /srv/git

Number of files: 3400
Number of files transferred: 0
Total file size: 7.97M bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 138.52K
File list generation time: 0.073 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 138.53K
Total bytes received: 12

sent 138.53K bytes received 12 bytes 30.79K bytes/sec
total size is 7.97M speedup is 57.52

– Sauvegarde de /srv/mail

Number of files: 6024
Number of files transferred: 0
Total file size: 218.03M bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 294.36K
File list generation time: 0.118 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 294.36K
Total bytes received: 12

sent 294.36K bytes received 12 bytes 84.11K bytes/sec
total size is 218.03M speedup is 740.64

– Sauvegarde de /srv/mpd

Number of files: 8
Number of files transferred: 0
Total file size: 6.35M bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 207
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 217
Total bytes received: 15

sent 217 bytes received 15 bytes 464.00 bytes/sec
total size is 6.35M speedup is 27366.55

– Sauvegarde de /srv/partimage

Number of files: 1
Number of files transferred: 0
Total file size: 0 bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 47
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 54
Total bytes received: 12

sent 54 bytes received 12 bytes 132.00 bytes/sec
total size is 0 speedup is 0.00

– Sauvegarde de /srv/prosody

Number of files: 11
Number of files transferred: 0
Total file size: 41.80K bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 277
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 284
Total bytes received: 12

sent 284 bytes received 12 bytes 592.00 bytes/sec
total size is 41.80K speedup is 141.21

– Sauvegarde de /srv/reseau

Number of files: 1878
Number of files transferred: 0
Total file size: 2.81M bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 72.64K
File list generation time: 0.038 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 72.64K
Total bytes received: 12

sent 72.64K bytes received 12 bytes 16.14K bytes/sec
total size is 2.81M speedup is 38.64

– Sauvegarde de /srv/sauvegardes

Number of files: 13851
Number of files transferred: 0
Total file size: 1.09G bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 520.14K
File list generation time: 0.306 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 520.15K
Total bytes received: 12

sent 520.15K bytes received 12 bytes 33.56K bytes/sec
total size is 1.09G speedup is 2091.76

– Sauvegarde de /srv/scripts

Number of files: 94
Number of files transferred: 0
Total file size: 785.47K bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 2.05K
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 2.05K
Total bytes received: 12

sent 2.05K bytes received 12 bytes 4.13K bytes/sec
total size is 785.47K speedup is 380.19

– Sauvegarde de /srv/svn

Number of files: 1374
Number of files transferred: 0
Total file size: 5.85M bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 17.89K
File list generation time: 0.020 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 17.90K
Total bytes received: 12

sent 17.90K bytes received 12 bytes 11.94K bytes/sec
total size is 5.85M speedup is 326.66

– Sauvegarde de /srv/www

Number of files: 4249
Number of files transferred: 20
Total file size: 29.29M bytes
Total transferred file size: 376.31K bytes
Literal data: 376.31K bytes
Matched data: 0 bytes
File list size: 82.58K
File list generation time: 0.076 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 459.76K
Total bytes received: 392

sent 459.76K bytes received 392 bytes 61.35K bytes/sec
total size is 29.29M speedup is 63.65

Retrait de la partition de sauvegarde.
Suppression du point de montage.
Envoi du log par e-mail.[/code]

Puis, en en discutant avec des amis, on s’est aperçu qu’il était inutile d’arrêter les services pour effectuer les sauvegardes. Du moins, on a pas trouvé de bonne raison de le faire. J’ai pas envie de supprimer mon script et de le regretter plus tard donc je suis venu vous poser cette question : vous semble-t-il utile, d’une quelconque façon, de procéder à des arrêts des services le temps de la sauvegarde ? Est-ce que cela pourrait éviter de corrompre une sauvegarde dans un cas précis ?

Merci beaucoup pour votre aide.

Je me suis posé la question un temps mais étant donné que je n’ai jamais eu de problèmes en effectuant mes sauvegardes sans ne rien faire préalablement, je ne me la pose plus.
Au début, je les faisais à partir d’un système tiers, justement dans cette idée mais depuis longtemps, je les fais “à chaud”.

Merci ricardo !

Tu dis que tu n’as jamais eu de problème mais as-tu déjà dû restaurer une sauvegarde réalisée à chaud alors que des services étaient en train d’écrire des données ?

Par exemple, je me demande ce qui se passe si je lance une sauvegarde et que mon démon transmission continue des téléchargements ou que mon démon prosody alimente un historique car quelqu’un discute via mon serveur jabber ou encore que quelqu’un fait un commit sur SVN ? Il manquera une partie de l’information sur la sauvegarde non ? Pire, elle pourrait être corrompue ? C’est-à-dire que des fichiers d’un service pourraient être changés mais pas tous, rendant la sauvegarde inutile…

Qu’en dites-vous ?

Je n’ai jamais eu d eproblèmes mais il faut dire que quand je sauvegarde, je ne fais que sayvegarder, ou, à la rigueur, je fais une réusite pour patienter mais je ne m’amuse pas à TC des fichiers.
Mes sauvegardes sont et resteront commandées manuellement, elle ne connaissent pas ‘cron’.

En théorie il peut y avoir des problèmes de corruption de données si la sauvegarde lit un fichier juste au moment où un autre programme le modifie. Tu risques de te retrouver dans ta sauvegarde avec un bout du fichier qui correspond à son ancien état (avant que l’autre programme ne le modifie) et un autre bout dans son nouvel état.

Selon le type de services que tu fais tourner ça peut être un plus ou moins gros problème. De manière générale ça reste une assez mauvaise idée de faire des sauvegardes à chaud si le service en face n’est pas explicitement prévu pour. Bien entendu dans le cas d’une machine “de bureau” entièrement contrôlée par son utilisateur ça n’est que rarement un problème, mais pour un serveur ça peut l’être.

Si le but est, comme je l’imagine, de minimiser le downtime de tes services, il y a des solutions un peu tarabiscotées. Ça se base sur des “snapshots” à chaud de ton filesystem (je ne connais que LVM qui le fasse, mais il doit y avoir d’autre produits équivalents) : à un moment donné tu lui dis de faire une image, qu’il va ensuite mettre soit dans un point de montage ou dans une nouvelle partition (je me rappelle plus). Ça prend une fraction de seconde, et le filesystem normal peut recommencer à être modifié tout en ayant la garantie que l’image ne changera pas.
Une fois que tu as fini de sauvegarder l’image, tu la supprimes tout simplement.
Du coup au lieu d’avoir une procédure de sauvegarde arrêt des services -> sauvegarde (longue !) -> redémarrage des services avec un downtime important, tu te retrouves avec arrêt des services -> snapshot (quasi instantané) -> redémarrage des services -> sauvegarde du snapshot -> suppression du snapshot et ton downtime se retrouve réduit à peau de chagrin (juste le temps de stopper / redémarrer les services quoi).

Bon, l’inconvénient c’est que tous tes disques doivent être déjà gérés par LVM et que celui-ci doit être configuré correctement pour autoriser ce genre de choses.
Note bien que je ne maîtrise pas du tout ce concept de snapshots à chaud, j’ai juste une (vague) idée de comment ça fonctionne donc il se peut que je me sois laissé aller à quelques imprécisions. :smiley:

Bonjour et merci pour vos commentaires.

ricardo, cette sauvegarde est lancée par udev lorsqu’il reconnaît mon disque dur externe :slight_smile: Mais je fais d’autres sauvegardes par le cron quand même, mais c’est un autre sujet :stuck_out_tongue:

syam, merci beaucoup pour tes infos sur LVM, je ne connaissais pas ça et ça me motive à me documenter là-dessus. Merci aussi pour ton opinion sur l’arrêt des services : ça me rassure d’ailleurs de voir que je ne suis pas le seul à trouver cela plus prudent.

À ce propos, je ne pense pas trop sortir du sujet en vous parlant de ce problème : j’obtiens une erreur en lançant le script qui précède par udev car ce dernier ne connaît pas la variable d’environnement $TERM. Cela gêne les commandes update-inetd et donc, à chaque fois que le script utilise update-inetd, cela affiche ceci dans les logs :

debconf: unable to initialize frontend: Dialog debconf: (TERM is not set, so the dialog frontend is not usable.) debconf: falling back to frontend: Readline

Cela ressemble à ce bug sous Ubuntu mais le ticket ne nous apprend pas grand chose : bugs.launchpad.net/ubuntu/+sour … +bug/53049

Merci pour votre aide.