Speak English? Click here to read my English blog!

script php de sauvegarde mysql

Posté par jbl le 18 août 2009 dans Développement, PHP13 commentaires
Protected by Copyscape Duplicate Content Check
 

Cet article fait suite à cet autre article Sauvegarder/Exporter une base de données avec PHP. J'en ai eu besoin ce matin pour faire une sauvegarde d'une base de données mysql d'un site. Seul moyen d'accès que j'avais : l'accès par ftp et le site en safe mode. Pas la peine de préciser que ce script m'a été bien utile !

J'ai fais quelques modifications dans le script, pour éviter de me heurter au timeout (non modifiable en safe mode) :

- un fichier par table, dans un répertoire accessible en écriture. Dans ce cas précis il s'agit du répertoire temp

- enregistrement immédiat de chaque ligne, qui est compressée à la volée par gz

- procédure de reprise en cas de problème, on relance le script après avoir modifié l'appel, $dump = dump(5); pour sauter les 5 premières tables par exemple.

- le $tables = mysql_list_tables($database, $db); m'ayant parfois causé des soucis, je l'ai remplacé par $sql = "SHOW TABLES FROM $database";

function dump($ignore)
{
 $server = '*********';
 $database = '*********';
 $user = '*********';
 $password = '*********';

 //Connexion à la base
 $db = mysql_connect($server, $user, $password) or die(mysql_error());
 mysql_select_db($database, $db) or die(mysql_error());

 //on récupère la liste des tables de la base de données
 //$tables = mysql_list_tables($database, $db) or die(mysql_error());
 $sql = 'SHOW TABLES FROM '.$database;
 $tables = mysql_query($sql) or die(mysql_error());

 // si on ne veut pas récupérer les $ignore premières tables
 for ($i=0; $i<$ignore; $i++) ($donnees = mysql_fetch_array($tables));

 // aller on boucle sur toutes les tables
 while ($donnees = mysql_fetch_array($tables))
 {
  // on récupère le create table (structure de la table)
  $table = $donnees[0];
  $sql = 'SHOW CREATE TABLE '.$table;
  $res = mysql_query($sql) or die(mysql_error().$sql);
  if ($res)
  {
   $backup_file = '../temp/backup_' . $table . '.sql.gz';
   $fp = gzopen($backup_file, 'w');

   $tableau = mysql_fetch_array($res);
   $tableau[1] .= ";\n";
   $insertions = $tableau[1];
   gzwrite($fp, $insertions);

   $req_table = mysql_query('SELECT * FROM '.$table) or die(mysql_error());
   $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; $i++)
    {
     $insertions .= '\'' . mysql_real_escape_string($ligne[$i]) . '\', ';
    }
    $insertions = substr($insertions, 0, -2);
    $insertions .= ");\n";
    gzwrite($fp, $insertions);
   }
  } // fin if ($res)
  mysql_free_result($res);
  gzclose($fp);
 }
 return true;
}

//appel de la fonction
$dump = dump(0);

Et voilà un script de sauvegarde très rapide. Il suffit d'aller récupérer les fichiers.

Pour ceux qui veulent sauvegarder qu'une seule table dont le nom est connu :

function dump($table)
{
 $server = '******';
 $database = '******';
 $user = '******';
 $password = '******';
 //Connexion à la base
 $db = mysql_connect($server, $user, $password) or die(mysql_error());
 mysql_select_db($database, $db) or die(mysql_error());

 $sql = 'SHOW CREATE TABLE '.$table;
 $res = mysql_query($sql) or die(mysql_error().$sql);
 if ($res)
 {
   $backup_file = '../temp/backup_' . $table . '.sql.gz';
   $fp = gzopen($backup_file, 'w');

   $tableau = mysql_fetch_array($res);
   $tableau[1] .= ";\n";
   $insertions = $tableau[1];
   gzwrite($fp, $insertions);

   $req_table = mysql_query('SELECT * FROM '.$table) or die(mysql_error());
   $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; $i++)
    {
     $insertions .= '\'' . mysql_real_escape_string($ligne[$i]) . '\', ';
    }
    $insertions = substr($insertions, 0, -2);
    $insertions .= ");\n";
    gzwrite($fp, $insertions);
   }
 } // fin if ($res)
 mysql_free_result($res);
 gzclose($fp);
 return true;
}

//appel de la fonction
$dump = dump('nomdelatable');

Autres articles dans la catégorie Développement



Autres articles dans la catégorie PHP



13 commentaires

» Flux RSS des commentaires
  1. merci infiniment pour l’info, je trouve toujours des choses bien utiles sur ce site.

  2. Pourquoi ne pas utiliser tout simplement mysqldump ?

    exec(‘mysqldump –opt –host=localhost –databases=mabase –user=monuser –password=monpassword > monfichier.sql’);

  3. Oui c’est le plus simple malheureusement ce n’est pas toujours possible : exec pas autorisé (et pas la main sur php.ini pour le changer) et/ou mysqldump pas installé/accessible.

  4. MERCI ;-)
    Je pensais devoir me taper tout le boulot, mais tu l’as fait ;-)

  5. Merci pour le script, ca peut toujours servir ;)

  6. Tout juste ce que je cherchais. Merci

  7. Pas mal le script mais quand on a un serveur, il y a plus simple. J’ai préféré le script sur l’alerte email en cas de défaillance. L’idée est vraiment bonne.

  8. J’ai des soucis avec mysqldump qui perd la connexion au bout d’un moment sur une base de plusieurs Go, alors je me penche sur ton script.

    Avantage de ta solution :
    - il serait possible de contrôler la bonne exécution de chaque étape et d’agir en fonction selon l’erreur rencontrée (comme par exemple la perte de la connexion au serveur MySQL).

    Inconvénients de ta solution :
    - Le serveur est davantage sollicité que lors de l’utilisation de l’utilitaire mysqldump, et des Slow Queries sont générées.
    - Il n’y a que les tables et non les triggers, et autres joyeusetés de ce genre (mais dans mon cas ça ne me gêne pas)

    Amélioration de ta solution :
    - l’utilisation de mysql_unbuffered_query à la place de mysql_query devrait améliorer les performances.

  9. Parfois la fonction exec() n’est pas disponible mais la fonction system() oui, qui est aussi puissante, et surtout vous n’avez pas le problème de timeout avec.
    Mais c’est sur, ce n’est pas toujours accessible, surtout sur du mutualiser.

  10. Merci pour ce script qui s’avère bien utile lorsque la fonction exec() n’est pas disponible.

  11. Très bon script. Je pense que cela pourrait être intéressant de faire une classe avec différentes fonctions comme la sauvegarde complète, sauvegarde avec un nombre de tables passé en paramètre, etc qu’en dites vous?

  12. Quelle est la licence de ce script ?

  13. Tu fais ce que tu veux de ce code car c’est juste un exemple. La plupart du temps il faudra l’adapter à ses besoins.

Commenter