Copie de sauvegarde de base de données MySQL
Voici un script qui exécute chaque jour une copie de votre base de données MySQL.
Il est possible de paramétrer le nombre de jours de sauvegardes à conserver.
Dans notre exemple, le fichier se place ici : /usr/local/bin/backup_database.sh
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#!/bin/bash # Configuration SOURCE_DB="ma_base_de_donnees" BACKUP_LOG_DIR="/var/log/mysql" BACKUP_LOG_FILE="$BACKUP_LOG_DIR/backup.log" DAYS_TO_KEEP=7 MY_CNF="/etc/mysql/mariadb.conf.d/.my.cnf" echo "$(date) - Début de la sauvegarde" >> "$BACKUP_LOG_FILE" # Créer le répertoire de sauvegarde s'il n'existe pas if [ ! -d "$BACKUP_LOG_DIR" ]; then mkdir -p "$BACKUP_LOG_DIR" || { echo "$(date) - Échec de la création du répertoire $BACKUP_LOG_DIR" >> /tmp/backup_error.log exit 1 } fi if [ ! -w "$BACKUP_LOG_DIR" ]; then echo "$(date) - Pas de permissions d'écriture dans $BACKUP_LOG_DIR" >> /tmp/backup_error.log exit 1 fi # Date de la veille (format YYYYMMDD) YESTERDAY=$(date -d "yesterday" +%Y%m%d) BACKUP_DB="backup_${SOURCE_DB}_${YESTERDAY}" # Flush du cache tant qu'on est là mysql --defaults-file="$MY_CNF" -e "FLUSH QUERY CACHE;" # Supprimer la base de sauvegarde précédente (si elle existe) mysql --defaults-file="$MY_CNF" -e "DROP DATABASE IF EXISTS $BACKUP_DB;" # Créer une nouvelle base de sauvegarde mysql --defaults-file="$MY_CNF" -e "CREATE DATABASE $BACKUP_DB;" || { echo "$(date) - Échec de la création de la base $BACKUP_DB" >> "$BACKUP_LOG_FILE" exit 1 } # Détecter les tables corrompues CORRUPT_TABLES=$(mysql --defaults-file="$MY_CNF" -N -e "SHOW TABLES FROM $SOURCE_DB" | \ while read -r table; do if mysql --defaults-file="$MY_CNF" -e "CHECK TABLE $SOURCE_DB.$table" 2>&1 | grep -q "corrupt"; then echo "$table" fi done) if [ -n "$CORRUPT_TABLES" ]; then echo "$(date) - Tables corrompues ignorées : $CORRUPT_TABLES" >> "$BACKUP_LOG_FILE" fi # Optimiser les tables NON corrompues mysql --defaults-file="$MY_CNF" -N -e "SHOW TABLES FROM $SOURCE_DB" | \ while read -r table; do # Vérifier si la table est dans la liste des tables corrompues if [[ ! " $CORRUPT_TABLES " =~ " $table " ]]; then if ! mysql --defaults-file="$MY_CNF" -e "OPTIMIZE TABLE $SOURCE_DB.$table" 2>> "$BACKUP_LOG_FILE"; then echo "$(date) - Échec de l'optimisation de la table $table" >> "$BACKUP_LOG_FILE" fi fi done # Exporter et importer la base source dump_options="" if [ -n "$CORRUPT_TABLES" ]; then for table in $CORRUPT_TABLES; do dump_options="$dump_options --ignore-table=$SOURCE_DB.$table" done fi mysqldump --defaults-file="$MY_CNF" \ --single-transaction \ --quick \ --force \ --skip-lock-tables \ $dump_options \ "$SOURCE_DB" 2>> "$BACKUP_LOG_FILE" | mysql --defaults-file="$MY_CNF" "$BACKUP_DB" || { echo "$(date) - Échec de la sauvegarde de $SOURCE_DB" >> "$BACKUP_LOG_FILE" exit 1 } # Supprimer les bases de données trop anciennes dans MariaDB for db in $(mysql --defaults-file="$MY_CNF" -N -e "SHOW DATABASES LIKE 'backup_${SOURCE_DB}_%';"); do db_date=${db#backup_${SOURCE_DB}_} if [ -n "$db_date" ]; then db_seconds=$(date -d "$db_date" +%s 2>/dev/null) if [ $? -eq 0 ]; then days_old=$(( ( $(date +%s) - db_seconds ) / 86400 )) if [ "$days_old" -gt "$DAYS_TO_KEEP" ]; then mysql --defaults-file="$MY_CNF" -e "DROP DATABASE IF EXISTS $db;" echo "$(date) - Suppression de la base $db (trop ancienne)" >> "$BACKUP_LOG_FILE" fi fi fi done # Log de fin echo "$(date) - Sauvegarde de $SOURCE_DB vers $BACKUP_DB terminée" >> "$BACKUP_LOG_FILE" |
Afin d’éviter d’écrire plusieurs fois en clair l’utilisateur et le mot de passe d’accès à la base de données pour les commandes mysql et mysqldump, vous aurez remarqué l’instruction --defaults-file="$MY_CNF", qui fait appel aux informations stockées dans le fichier /etc/mysql/mariadb.conf.d/.my.cnf sous la forme :
|
1 2 3 |
[client] user = db_user password = db_password |
Cette commande est à exécuter une fois par jour, en faisant un crontab -e et en ajoutant la ligne :
|
1 |
0 0 * * * /usr/local/bin/backup_database.sh |
Après l’exécution de ce script, vous aurez une copie intégrale par jour de votre base de donnée située à côté de votre base principale :
ma_base_de_donneesbackup_ma_base_de_donnees_20250903backup_ma_base_de_donnees_20250904backup_ma_base_de_donnees_20250905- etc.