[Contribution MySQL] Faire des sauvegardes automatiques !



  • Faire des sauvegardes automatiques et quotidiennes de vos bases MySQL

    • But du tutoriel : Faire une sauvegarde quotidienne automatisée de vos bases MySQL

    • Difficultés : Bah… rien :D (je pense que vous savez tous vous connectez au FTP, visitez un site, etc...) !

    • Connaissances requises : Si vous voulez "customiser" le code, du php (je fourni seulement la base :wink: ) !

    I - Introduction

    Avant de commencer à détailler "la chose" :twisted: (ne vous inquiètez pas, elle mord pas), il faut d'abord savoir le pourquoi du comment.
    Vous êtes nombreux à ne pas faire des sauvegardes de vos bases MySQL quotidiennement : je suis d'accord avec vous, c'est long, il faut se connecter à PhpMyAdmin, se logger, sélectionner ses bases, les exporter, enregistrer le fichier, etc... Enfin bref, vous disez-vous peut-être qu'une fois par mois (semaine pour certains), sa suffit ?
    Il faut clairement dire les chose en face : NON !
    Les bases MySQL sont fortement utilisés par les sites de nos jours (dynamiques), qui possèdent un forum, un t'chat, un livre d'or…
    Et c'est d'autant plus important pour les sites créés avec un CMS !
    En effet, un hack ou une mauvaise manip est si vite arrivé, que vous risquez de le regretter amèrement si vous n'avez pas pris les dispositions nécessaires !

    II - L'explication

    Pour procéder à cette sauvegarde quotidienne, nous allons avoir besoin de 2 outils :

    • Un fichier php : pas très compliqué me direz-vous :p

    • Un cron : c'est un système qui permet de programmer l'exécution de scripts. Mais oublions ça, je vous en parlerez dans le IV.

    Nous allons ensemble créer cette fameuse page en php. Elle sera chargée de récupérer toutes vos données MySQL (bases, tables et contenus), puis de les enregistrées dans un ou des fichiers .sql qui seront sauvés sur votre FTP, dans un dossier préalablement créé !
    Personnellement, j'ai prévu le code pour enregistrer chaque base dans 1 fichier différent, ce qui sera plus aisé pour la restauration, s'il en faut une :p ! Par la suite, nous irons configurer un cron qui fera exécuter le fichier une fois par jour (vous serez libre de choisir le délai : 1/heure, 1/jour, 1/mois, 1/année, etc...). Le mieux reste le 1 par jour quand même, faut pas être parano au point de le faire toutes les heures :D !!!

    III - Le fichier PHP

    C'est parti…
    Le fichier php va être utilisé pour récupérer toutes vos données MySQL.

    Nous allons tout d'abord créer un fonction qui sera capable de tout copier de MySQL !

    <?php
    // création d'une fonction comportant les identifiants de connexion au FTP : 
    function mysql_structure($base)
    {
    	$host = 'localhost';
    	$user = 'monlogin'; //indiquer ici votre login MySQL
    	$pass = 'monpass'; //indiquer ici votre mot de passe MySQL
    
    	// création d'un fichier affichant en boucle le contenu des tuples de la base : 
    	mysql_connect($host, $user, $pass);
    	mysql_select_db($base);
    	$tables = mysql_list_tables($base);
    	while ($donnees = mysql_fetch_array($tables))
    	{
    		$table = $donnees[0];
    		$res = mysql_query("SHOW CREATE TABLE $table");
    		if ($res)
    		{
    			$insertions = "";
    			$tableau = mysql_fetch_array($res);
    			$tableau[1] .= ";";
    			$dumpsql[] = str_replace("n", "", $tableau[1]);
    			$req_table = mysql_query("SELECT * FROM $table");
    			$nbr_champs = mysql_num_fields($req_table);
    			while ($ligne = mysql_fetch_array($req_table))
    			{
    				$insertions .= "INSERT INTO $table VALUES(";
    				for ($i=0; $i<=$nbr_champs-1; $i++)
    				{
    					$insertions .= "'" . mysql_real_escape_string($ligne[$i]) . "', ";
    				}
    				$insertions = substr($insertions, 0, -2);
    				$insertions .= ");n";
    			}
    			if ($insertions != "")
    			{
    				$dumpsql[] = $insertions;
    			}
    		}
    	}
    	return implode("r", $dumpsql);
    }
    

    Ce code sera chargé de TOUT récupérer de votre(vos) base(s) : tables + contenus !
    Si vous lisez attentivement ce code, vous verrez qu'il recupère que les données MySQL de la base passée en paramètre de la fonction ! Il nous faudra donc exécutez cette fonction autant de fois que vous avez de bases !
    Il ne faut pas oublier de remplacer le "monlogin" et "monpass" par vos identifiants de connexion à MySQL !
    Mais ce n'est pas tout : avoir le code de restauration, c'est bien, mais le copier dans un fichier, c'est mieux :D !
    On va donc créer une 2nd fonction qui sera capable de sauvegarder votre code dans un fichier :

    // creation d'une fonction file_put_content si le script est en PHP4 : 
    if(!function_exists('file_put_contents'))
    {
    	function file_put_contents($filename, $data, $file_append = false)
    	{
    		$fp = fopen($filename, (!$file_append ? 'w+' : 'a+'));
    		if(!$fp)
    		{
    			trigger_error('file_put_contents ne peut pas écrire dans le fichier.', E_USER_ERROR);
    			return;
    		}
    		fputs($fp, $data);
    		fclose($fp);
    	}
    }
    

    Si vous m'avez bien suivi, vous devriez savoir que si on exécute ce fichier…............... il ne va rien se passer :D !
    Eh oui, nous n'avons pour l'instant créer seulement des fonctions, qui ne sont pas exécuter tant que l'on ne leur demande pas !
    Bon si vous avez pas trouvé, je ne vous en veux pas, c'est pas grave :wink: !
    Maintenant, nous allons listez tous les noms de nos bases dans un array (si vous ne savez pas ce que c'est, je vous invite à lire ça).
    On a donc un tout petit bout de code :

    //création d'un array contenant le nom de chacune de mes tables
    $bases = array ('mabase1', 'mabase2', 'mabase3');
    ```Rah, vous allez me dire que vous avez 2 bases : pas de problème, enlevez simplement le _**, 'mabase3'**_ :D
    P.S : vous pouvez aussi ajouter d'autres bases, si vous en avez plus de 3 !
    Maintenant que nous avons tout préparer, il ne nous reste plus qu'une chose à faire : exécutez les fonctions autant de fois que vous avez de bases !
    Voici donc le dernier bout de code, détaille juste dessous :
    

    for ($nb_bases = 0; $nb_bases < 3; $nb_bases++)
    {
    // création du fichier de dump sur le même niveau que ce fichier dump.php
    file_put_contents(date("d-n-Y")."_".$bases[$nb_bases].".sql", mysql_structure($bases[$nb_bases]));

    // effacement du fichier precedant (créé 7 jours plus tot)
    $time_old = getdate(mktime()-(7*24*3600));
    $an = $time_old['year'];
    $mois = $time_old['mon'];
    $jour = $time_old['mday'];
    
    // formatage des jours à 1 chiffre 
    for($k=1; $k<10; $k++)
    {
    	if ($jour==$k)
    	{
    		$jour='0'.$jour;
    	}
    }
    
    $date_old = $jour.'-'.$mois.'-'.$an;
    $file_old = $date_old."_".$bases[$nb_bases].".sql";
    if (file_exists($file_old))
    {
    	unlink($file_old);
    }
    

    }
    ?>

    
    *   ```
        for ($nb_bases = 0; $nb_bases < 3; $nb_bases++)
        ```Cette portion est chargée d'exécuter la boucle autant de fois que le nombre de vos bases. N'oubliez pas de remplacer le _3_ de _**$nb_bases < 3**_ par le nombre de bases rentrées dans l'array précédent !
    
    *   ```
        	// création du fichier de dump sur le même niveau que ce fichier dump.php
        	file_put_contents(date("d-n-Y")."_".$bases[$nb_bases].".sql", mysql_structure($bases[$nb_bases]));
        ```Ici, PHP va enregistrer les données récupérées avec 1ère fonction, et ceci à l'aide de la 2nd !
        Le fichier enregistré sera dans le même répertoire que le fichier .php, et aura comme nom :
    
        > jj-mm-aaaa_mabasex.sql
    
    *   ```
        	// effacement du fichier precedant (créé 7 jours plus tot)
        	$time_old = getdate(mktime()-(7*24*3600));
        	$an = $time_old['year'];
        	$mois = $time_old['mon'];
        	$jour = $time_old['mday'];
    
        	// formatage des jours à 1 chiffre 
        	for($k=1; $k<10; $k++)
        	{
        		if ($jour==$k)
        		{
        			$jour='0'.$jour;
        		}
        	}
    
        	$date_old = $jour.'-'.$mois.'-'.$an;
        	$file_old = $date_old."_".$bases[$nb_bases].".sql";
        	if (file_exists($file_old))
        	{
        		unlink($file_old);
        	}
        ```Viens ensuite cette dernière partie, qui est chargée de supprimer la sauvegarde de la base créée 7 jours auparavant (pour ne pas avoir des centaines de sauvegardes dans le dossier).
    
    Pris par un élan de générosité extrème ( :wink: ), voici le fichier PHP dans son intégralité :
    

    <?php
    // création d'une fonction comportant les identifiants de connexion au FTP :
    function mysql_structure($base)
    {
    $host = 'localhost';
    $user = 'monlogin'; //indiquer ici votre login MySQL
    $pass = 'monpass'; //indiquer ici votre mot de passe MySQL

    // création d'un fichier affichant en boucle le contenu des tuples de la base :
    mysql_connect($host, $user, $pass);
    mysql_select_db($base);
    $tables = mysql_list_tables($base);
    while ($donnees = mysql_fetch_array($tables))
    {
    $table = $donnees[0];
    $res = mysql_query("SHOW CREATE TABLE $table");
    if ($res)
    {
    $insertions = "";
    $tableau = mysql_fetch_array($res);
    $tableau[1] .= ";";
    $dumpsql[] = str_replace("n", "", $tableau[1]);
    $req_table = mysql_query("SELECT * FROM $table");
    $nbr_champs = mysql_num_fields($req_table);
    while ($ligne = mysql_fetch_array($req_table))
    {
    $insertions .= "INSERT INTO $table VALUES(";
    for ($i=0; $i<=$nbr_champs-1; $i++)
    {
    $insertions .= "'" . mysql_real_escape_string($ligne[$i]) . "', ";
    }
    $insertions = substr($insertions, 0, -2);
    $insertions .= ");n";
    }
    if ($insertions != "")
    {
    $dumpsql[] = $insertions;
    }
    }
    }
    return implode("r", $dumpsql);
    }

    // creation d'une fonction file_put_content si le script est en PHP4 :
    if(!function_exists('file_put_contents'))
    {
    function file_put_contents($filename, $data, $file_append = false)
    {
    $fp = fopen($filename, (!$file_append ? 'w+' : 'a+'));
    if(!$fp)
    {
    trigger_error('file_put_contents ne peut pas écrire dans le fichier.', E_USER_ERROR);
    return;
    }
    fputs($fp, $data);
    fclose($fp);
    }
    }

    //création d'un array contenant le nom de chacune de mes tables
    $bases = array ('mabase1', 'mabase2', 'mabase3');

    for ($nb_bases = 0; $nb_bases < 3; $nb_bases++)
    {
    // création du fichier de dump sur le même niveau que ce fichier dump.php
    file_put_contents(date("d-n-Y")."_".$bases[$nb_bases].".sql", mysql_structure($bases[$nb_bases]));

    // effacement du fichier precedant (créé 7 jours plus tot)
    $time_old = getdate(mktime()-(7243600));
    $an = $time_old['year'];
    $mois = $time_old['mon'];
    $jour = $time_old['mday'];

    // formatage des jours à 1 chiffre
    for($k=1; $k<10; $k++)
    {
    if ($jour==$k)
    {
    $jour='0'.$jour;
    }
    }

    $date_old = $jour.'-'.$mois.'-'.$an;
    $file_old = $date_old."_".$bases[$nb_bases].".sql";
    if (file_exists($file_old))
    {
    unlink($file_old);
    }
    }
    ?>

    Et voilà votre fichier PHP prêt et opérationnel !
    Je vous invite à l'uploader via votre FTP dans un dossier /sql/titre.php (vous êtes libre de choisir son nom) présent à la racine de votre site (dans le dossier /WWW/ en réalité) !
    
    **IV - Le cron**
    
    _Quoi, mais c'est pas fini :shock: ???_
    Rassurez-vous, ça l'est bientôt !
    Maintenant que vous avez votre fichier, ça serait complètement inutile s'il ne s'exécute pas automatiquement (même si vous pouvez le faire en l'ouvrant dans votre navigateur)…
    Nous allons donc avoir besoin d'un système qui exécute votre fichier tout les jours, et c'est là qu'apparaît [WEBCRON](http://www.webcron.org/) !
    WEBCRON est un site qui va nous permettre d'exécuter notre fichier une fois par jour !
    Tout d'abord, je vous invite à réer un compte (ça prend pas plus de 2min). Pour les veinards, voici [le lien de la page d'inscription](http://www.webcron.org/inscription.php) :D .
    
    Uns fois votre compte créer, logguez-vous, puis cliquez sur "mes tâches" !
    [![](http://img72.imageshack.us/img72/5651/webcron1op2.th.jpg)](http://img72.imageshack.us/my.php?image=webcron1op2.jpg)
    
    Cliquez ensuite sur "nouvelle tâche" !
    [![](http://img111.imageshack.us/img111/2953/webcron2bn8.th.jpg)](http://img111.imageshack.us/my.php?image=webcron2bn8.jpg)
    
    Configurons ensuite notre tâche :
    
    *   **Url :** url de votre fichier php
    
    *   **Login et passe :** laissez vide
    
    *   **Heure :** Indiquez l'heure où le script d'exécutera (pour pas surcharger le serveur, indiquez une heure de la nuit, entre 23h et 8h). Je vous conseille de la fixer à 4h ou 5h :D
    
    *   **Jour de la semaine :** Tous
    
    *   **Jour du mois :** Tous
    
    *   **Année :** Toutes
    
    [![](http://img177.imageshack.us/img177/8745/webcron3xe4.th.jpg)](http://img177.imageshack.us/my.php?image=webcron3xe4.jpg)
    
    Puis il suffit d'activer la tâche préalablement configurée !
    [![](http://img406.imageshack.us/img406/9706/webcron4du0.th.jpg)](http://img406.imageshack.us/my.php?image=webcron4du0.jpg)
    
    **V - C'est fini !**
    
    Et voilà, vous avez réalisé un système de sauvegarde quotidienne automatique de vos bases MySQL !
    Tous les fichiers de restauration seront créés dans le répertoire dans lequel se trouve votre fichier PHP.
    **N'oubliez pas de les uploader sur votre ordinateur de temps en temps !**.
    
    Il vous est possible d'apporter des améliorations sur le code, je laisse faire travailler votre imagination :D !!!
    
    Et voilà que touche à sa fin mon premier tuto, j'espère qu'il vous sera utile et que vous serez indulgent avec moi !
    
    _P.S : je me suis aidé de plusieurs tuto trouvée sur Google pour faire le fichier PHP, amélioré ensuite par mes soins pour permettre le multi-bases et la suppression sans bugs !_


  • Merci pour la contribution :)

    IV - Le cron

    Quoi, mais c'est pas fini Shocked ???
    Rassurez-vous, ça l'est bientôt !
    Maintenant que vous avez votre fichier, sa serez complètement inutile s'il ne s'exécute pas automatiquement (même si vous pouvez le faire en l'ouvrant dans votre navigateur)…

    Pour améliorer la contribution et si je me trompe pas, ça s'écrit plutôt comme cela : ça serait



  • @lave:

    Merci pour la contribution :)

    IV - Le cron

    Quoi, mais c'est pas fini Shocked ???
    Rassurez-vous, ça l'est bientôt !
    Maintenant que vous avez votre fichier, sa serez complètement inutile s'il ne s'exécute pas automatiquement (même si vous pouvez le faire en l'ouvrant dans votre navigateur)…

    Pour améliorer la contribution et si je me trompe pas, ça s'écrit plutôt comme cela : ça serait

    Corrigé !



  • Très intéressant !
    Plus qu'à le mettre sur la wiki :)



  • Serait-il possible de fournir un .rar avec les fichiers prêts à être uploadés ?



  • @arcanis:

    Très intéressant !
    Plus qu'à le mettre sur la wiki :)

    C'est prévu pour demain ou ce week-end :D !

    @cmbelgique:

    Serait-il possible de fournir un .rar avec les fichiers prêts à être uploadés ?

    Je vais optimiser le code et le distribuer en .rar et .zip dès que j'aurais un peu de temps (vendredi ou samedi quoi :p ) !



  • Je dispose d'un sublime petit CMS qui ce charge de tout sa facilement je le mettrais un jour en ligne pour tout le monde quand j'aurais le temps :roll:



  • Ce serait bien de pouvoir sauvegarder une fois par semaine.

    Ton script écrase l'ancienne sauvegarde ?



  • Génial !
    Bravo bon travail ;)

    Seul problème : Ben les gens si il connaisse notre lien, peuvent venir voler notre base mysql ... Non ?

    Et sinon a quand un système qui envoie automatiquement les fichiers de notre FTP à notre ordinateur :D ?

    En tout cas encore bravo ;)



  • @cmbelgique:

    Ce serait bien de pouvoir sauvegarder une fois par semaine.

    Ton script écrase l'ancienne sauvegarde ?

    Ce n'est pas compliqué : tu n'as qu'a exécuter le cron qu'une fois par semaine, sans oublier de changer le délai de suppression des anciennes sauvegardes (le transformé de 7 jours en 28 jours par exemple !) :

       // effacement du fichier precedant (créé 4 semaines plus tot) 
       $time_old = getdate(mktime()-(28*24*3600)); 
    

    @rerremi:

    Génial !
    Bravo bon travail

    Seul problème : Ben les gens si il connaisse notre lien, peuvent venir voler notre base mysql … Non ?

    Et sinon a quand un système qui envoie automatiquement les fichiers de notre FTP à notre ordinateur ?

    En tout cas encore bravo

    C'est effectivement le seul petit bémol, mais bon un nom de dossier un peu complexe avec un index.php contenant un header et le tour est joué :wink:
    Pour l'envoie sur ton ordinateur, tu peux, au lieu d'enregistrer le fichier sur ton FTP, te l'envoyer en pièce jointe par mail (je t'invite à surfer un peu sur Google pour savoir comment faire) !

    N'oubliez pas que ce code peu être amélioré ! Seules un peu de connaissance en php suffisent !

    P.S : l'envoie par mail du fichier, c'est pas mal, je vais essayer, je vous tiendrai au courant :wink: !!!



  • @onepiecefan:

    P.S : l'envoie par mail du fichier, c'est pas mal, je vais essayer, je vous tiendrai au courant :wink: !!!

    Une extension firefox permet d'utiliser l'espace mail de GMail en tant que plate-forme de sauvegarde de fichiers.
    Je ne l'ai jamais utilisé (j'aime pas gmail…vive yahoo :P ) mais ça a l'air intéressant, à première vue.



  • Après quelques petites heures passé sur le code, j'ai amélioré le code en permettant l'envoie du/des fichiers de sauvegardes à une adresse e-mail !

    De plus, j'ai préparé un petit script, qui sera distribué sous former de .rar (et .zip). Il suffira de configurer le fichier config.php avec différents éléments, configurer un cron, et le tour est joué :wink: !

    Je pense avoir fini ce week-end, plus qu'un petit bug du mail à résoude !



  • Niveau securité ya des risques ?



  • Oui.
    Si quelqu'un trouve l'adresse de la page il peut te surcharger à mort le site avec des sauvegardes.
    Mais bon, pour éviter ça t'a qu'à rajouter un chrono interne.



  • @arcanis:

    Oui.
    Si quelqu'un trouve l'adresse de la page il peut te surcharger à mort le site avec des sauvegardes.
    Mais bon, pour éviter ça t'a qu'à rajouter un chrono interne.

    Euh mais pouquoi pas mettre un fichier .httacces ?
    Meme si quelquin trouve l'URL , il ne peut ni toucher ni telecharger rien avec le .htacces

    PS : Tros génial ce script :D



  • Parce que dans ce cas, le cron externe ne pourra pas non plus accèder à la page.
    Il ne s'agit pas d'un vrai cron, juste un serveur externe qui envois des requêtes normales à intervals régulier.



  • @arcanis:

    Parce que dans ce cas, le cron externe ne pourra pas non plus accèder à la page.
    Il ne s'agit pas d'un vrai cron, juste un serveur externe qui envois des requêtes normales à intervals régulier.

    Ah , je comprend !! mais j'ai une petite suggestion , Pourquoi pas mettre ce script comme une option de l'hebergement de freeheberg ?
    Caveudir ci cette option est activé , chaque jour j'ai un lien de ma sauvegarde dans mon panel …

    PS : j'ai vus sa sur mon ancien hebergeur



  • Oui, ça serait super d'avoir cette option sur freeheberg :)



  • Ce script prend énormément de ressources serveur. Si il est mis en option intégrée à FreeHeberg et qu'il est exécuté par plusieurs centaines de sites en même temps, c'est la cata…

    Il est, de plus, relativement simple à mettre en place sur son site, si on en a vraiment besoin.

    /! C'est pour ces mêmes raisons que ce script doit être lancé en heures creuses du serveur (4h - 6h du matin) et à raison d'une fois par semaine de préférence /!

    Mais bon, celà dit, c'est caaptusss le maître des lieux !



  • Bonjour :)

    Il existe également MysqlDumper pour des sauvegardes.

    http://www.mysqldumper.de/en/

    Si vous voulez, je peux poster un tuto complet pour l'installation, son utilisation ensuite et relativement simple. Le système est comparable à WebCron.


Log in to reply