Blog Tool Box

Faire un script de sauvegarde de la base de données de son blog

Comme certains lecteurs l’avaient suggéré, je vous propose un tutoriel un peu plus « code » que d’habitude : réaliser son propre script de sauvegarde de sa base de données (les sources commentées sont disponibles à la fin de l’article). Ce script, très simple mais pouvant être amélioré sans problèmes, réalisera plusieurs fonctions :

  1. Sauvegarde de la base de données au format SQL
  2. Compression de la sauvegarde au format gzip (la totalité des logiciels de compression/décompression gèrent le gzip)
  3. Envoi de la sauvegarde par email

Quel est l’intérêt de faire ce script alors qu’il existe des plugins capables de faire la même chose ? Premièrement, avec ce script vous êtes totalement indépendant de la plateforme de blog que vous utilisez ; c’est-à-dire que vous pourrez l’utiliser pour sauvegarder un blog, un forum, etc, n’importe quoi qui utilise une base de données MySQL.
Cette indépendance apporte également plus de sécurité car si votre blog ne fonctionne plus, qu’est-ce qui vous garantit que les plugins rattachés à celui-ci fonctionneront toujours et que le plugin de sauvegarde fera correctement sa sauvegarde ?
Deuxièmement, vous aurez la grande joie d’avoir fait un script vous-même ! :)

Objectif

Notre objectif est donc de recevoir ce type d’email tous les jours (ou semaines, etc) :

Mail Sauvegarde BDD

Pré-requis

Pré-requis pour le bon déroulement du tutoriel et faire en sorte qu’il fonctionne :

  • Avoir un minimum de notions en PHP
  • Télécharger PHP Mailer-Lite et extraire le fichier class.phpmailer-lite.php qui nous permettera de simplifier la procédure d’envoi d’email avec la sauvegarde en pièce jointe
  • Avoir un hébergeur qui propose des tâches CRON/planifiées, qui permettera de lancer notre script tout les X heures, X jours, etc, pour entièrement automatiser la sauvegarde. Aujourd’hui, la plupart des hébergeurs proposent cette fonctionnalité, dans mon cas se sera un simple hébergement mutualisé chez OVH

C’est parti !

Commençons par créer un nouveau fichier nommé backup.php et ajouter le code suivant :

<?php
require_once("class.phpmailer-lite.php");
$from_mail = "email-expediteur@mail.com";
$from_name = "Nom de l'expediteur";
$to_mail = "email-destinataire@mail.com";
$to_name = "Nom du destinataire";
$blog = "Nom de votre blog";
$db_host = "Serveur_base_de_donnees";
$db_user = "Utilisateur_base_de_donnees";
$db_pass = "Password_base_de_donnees";
$db_name = "Nom_base_de_donnees";
$backup_name = "backup_".$db_name."_".date("d-m-y").".sql";

La première ligne sert à charger le fichier class.phpmailer-lite.php qui nous permettera d’envoyer l’email. Adaptez ensuite les différents paramètres : email du destinataire de la sauvegarde, l’expéditeur, etc, ainsi que les différents paramètres d’accès à la base de données.
La variable $backup_name définit la structure du nom du fichier de la sauvegarde. Ici, elle sera de la forme backup_NOMDELABASE_JOUR-MOIS-ANNEE.sql.

Complétez ensuite le code précédent par cette fonction que je ne vais pas détailler mais qui permet de transformer une taille de fichier en octets en une valeur en Mo ou Ko qui sera beaucoup plus lisible :

function taille($n){
if($n>1024){ return round(round($n/1024,1)/1024,1)." Mo"; }
else{ return round(round($n/1024,1),1)." Ko"; }
}

Viens ensuite la sauvegarde de la base :

system("mysqldump --host=\"".$db_host."\" --user=\"".$db_user."\" --password=\"".$db_pass."\" ".$db_name." > ".$backup_name);
system("gzip ".$backup_name);
$backup_name = $backup_name.".gz";

Nous allons ici exécuter le programme mysqldump avec les différents paramètres spécifiés tout à l’heure qui fera une sauvegarde de la base et l’enregistrera dans un fichier (avec la structure de nom de $backup_name).
Ensuite, ce même fichier tout juste créé sera compressé à l’aide de « gzip ».
Nous pouvons arrêter ce script dès maintenant car il fonctionne déjà. Si nous le lançons dès maintenant (en pensant à fermer la balise ?> en fin de script), celui-ci nous créera un fichier de sauvegarde dans le même répertoire où vous avez mis votre fichier backup.php et class.phpmailer-lite.php sur votre FTP.

Viens enfin l’envoi de l’email :

$mail = new PHPMailerLite();
$mail->IsMail();
$body = "Date : ".date("d/m/y")." ".date("H:i")."<br />";
$body .= "Sauvegarde de la base de données : ".$db_name."<br />";
$body .= "Fichier : ".$backup_name."<br />";
$body .= "Taille : ".taille(filesize($backup_name));
$mail->SetFrom($from_mail, $from_name);
$mail->AddAddress($to_mail, $to_name);
$mail->Subject = $blog." Sauvegarde BDD ".$db_name." - ".date("d/m/y");
$mail->MsgHTML($body);
$mail->AddAttachment($backup_name);
if($mail->Send()) { unlink($backup_name); }
?>

La variable $body contient le corps de notre message (voir l’image au début de l’article) : la date de la sauvegarde, le nom de la base de données qui vient d’être sauvegardée, le nom du fichier et enfin la taille du fichier de sauvegarde.
La ligne « Subject » sera le sujet de notre email : « Le nom de votre blog Sauvegarde BDD Nom de la base – Date de la sauvegarde ». On y ajoute ensuite notre pièce jointe (AddAttachement).
Et pour finir, on envoi l’email avec $mail->Send() et si le mail a bien été envoyé, on supprime le fichier de sauvegarde du serveur(unlink()). Si vous souhaitez laisser le fichier sur le serveur, il suffit simplement de changer la ligne en : $mail->Send();.

C’est fini ! Si vous ne l’avez pas encore fait, envoyez maintenant ce fichier backup.php accompagné du fichier class.phpmailer-lite.php sur votre FTP. Si vous souhaitez laisser les sauvegardes sur votre FTP, je vous conseille de mettre ces deux fichiers dans un nouveau répertoire vide.

Planification de la sauvegarde

Rendez-vous maintenant dans votre administration client chez votre hébergeur et accédez à la section Tâches CRON/Planifiées ». Rien de bien compliqué ici, il suffit simplement de spécifier l’adresse du script à exécuter et de choisir les dates/jours/heures auxquelles vous voulez lancer votre sauvegarde : tous les jours à 23h, tous les mardis à midi, etc.

CRON

Vous enregistrez votre tâche et c’est terminé ! Vous devriez maintenant recevoir vos sauvegardes de votre base de données par email.

Pour sécuriser le script, il suffit de le déposer dans un dossier créé à la racine de l’hébergement et non dans le dossier « www ». Si l’on passe par le CRON de l’hébergeur, celui-ci peut en effet accéder à n’importe quel dossier, y compris ceux qui ne sont pas visibles depuis le web – Olivier C dans les commentaire

• Télécharger les sources commentées : [download id= »2″]

  • Crunch

    Merci bien ;)

    Testé et approuvé !
    Cela va me permettre de désactiver les plugins wordpress pour mes backup ;)

    Reste plus qu’à activer la tâche via Cpannel.

  • Olivier C

    Merci pour ce code, désormais en place sur mon site :)

    Pour ma part j’ai juste rajouté dans le mail le temps d’exécution (à l’aide de l’instruction microtime), ainsi que l’optimisation de la base, qui peut s’effectuer de la même façon avec la commande « mysqlcheck –optimize » (le reste se paramétrant comme la commande mysqldump).

    Attention à ne pas oublier de protéger l’accès au dossier backup, afin d’éviter qu’un inconnu puisse récupérer les sauvegardes, ou exécuter le script sans autorisation (gênant pour la boîte mail :) ).

  • Olivier C

    Juste pour compléter mon post précédent : Pour sécuriser le script il suffit en fait de créer un dossier sous la racine de l’hébergement et non sous le dossier « www », si l’on passe par le CRON de l’hébergeur. Celui-ci peut accéder en fait à n’importe quel dossier, y compris ceux qui ne sont pas visibles depuis le web.

    http://forum.ovh.com/showthread.php?t=41310

  • miner

    Merci beaucoup pour ce script qui fonctionne parfaitement pour sauvegarder la BDD de Prestashop!

  • Isa Graphik

    Bonjour,

    Merci pour ce script qui comme la dit ‘miner’ fonctionne parfaitement sous ovh mutualisé et sauvegarde ma BDD de Prestashop.

    Toutefois pourriez vous me valider ces quelques ligne que je m’apprete a rajouter pour optimiser ma BDD :

    sous la ligne $backup_name >
    $check_name = "optimisation_".$db_name."_".date("d-m-y").".log";

    et au dessus de la ligne system(« mysqldump……… >
    system("mysqlcheck --host=\"".$db_host."\" --analyze --check-only-changed --optimize --user=\"".$db_user."\" --password=\"".$db_pass."\" ".$db_name." > ".$check_name);

    Mercipar avance de votre avis et éventuelle correction si necessaire.

  • Guillaume

    Bonjour,

    Merci pour ce code. n’étant pas un codeur pro, y a-il un moyen pour envoyer la sauvegarde de la base vers un compte DropBox.

    @pluche

  • Christophe

    Bonjour,
    Merci pour ce code. Par contre je n’arrive pas à le faire fonctionner. le script me crée bien le fichier mais j’ai ensuite le message : Could not access file: backup_**********.sql.gz
    Pourriez vous m’aidez svp
    D’avance merci
    ps : je suis sûr que mes paramètres sont bons.

  • Lokiiy

    Bonjour,
    Lors de l’envoie de l’émail je ne reçois pas la BDD
    Taille : 0 Ko
    J’ai même essayé d’appeler la page backup.php seul le résultat est le même
    Taille : 0 Ko

    Avez vous une piste pour m’aider a résoudre le problème car ce système de sauvegarde m’intéresse vraiment ..

    Merci d’avance pour vos réponses

  • Lokiiy

    Bon j’ai réussi finalement le code marche bien …
    Cependant pour y sécuriser j’ai pas compris comment m’y prendre pour mettre un dossier en dehors de mon www
    Comment je dois écrire le lien pour appeler la tache cron ??

    Dans le www = http://www.monsite.com/backup/backup.php

    Mais si je met le dossier backup en extérieur du www comment je dois écrire le lien s’il vous plait ??

    Hors www = ……………….??

    Merci de votre soutien

  • A-snowboard

    Ne marche pas pour moi. :(

    Quand je suis dans mon dossier www, je reçois bien le fichier (a part que sur le web il me marque une erreur avec le fichier de mail. (ligne 1234 et 1236)

    Et quand je met dans un dssier sauvegarde (a coté du www donc), il ne marche pas.
    Je lance tout de même l’automatisation des tache sous le manager ovh, ne marche pas. :/