begin process at 2012 02 15 20:41:14
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Base de données

 > RESTAURATION DE BASE MYSQL PAR PORTION (POUR EVITER LES DEPASSEMENT DE TIMELIMIT)

RESTAURATION DE BASE MYSQL PAR PORTION (POUR EVITER LES DEPASSEMENT DE TIMELIMIT)


 Information sur la source

Note :
6,5 / 10 - par 2 personnes
6,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Base de données Niveau :Initié Date de création :06/07/2004 Vu :3 206

Auteur : multicite

Ecrire un message privé
Site perso
Commentaire sur cette source (4)
Ajouter un commentaire et/ou une note

 Description

Lorsque l'on effectue une sauvegarde d'une base mysql, le fichier peut etre tres gros. Et quand on le restaure on peut être confronté à la limitation de temps (timeout, timelimit) d'éxecution du script PHP.

Pour contrer cela, ce script de restauration s'arrete automatiquement avant un temps prédéfini, puis relance un nouveau script qui reprend la restauration à l'endroit où elle s'est arrétée dans le script précédent et ainsi de suite jusqu'à ce que le fichier .sql soit lu et restauré en entier.

Les paramètres sont classiques : serveur, nom de base, utilisateur, mot de passe
puis
fichier=nom du fichier sql à restaurer
duree=timeout à ne pas dépasser (5 secondes par défaut)

tout ceci se paramètre en fin de script

Source

  • <html>
  • <head><title>Restauration de base MySql</title></head>
  • <body>
  • <?
  • function td() //temp initial
  • {
  • global $TPSDEB,$TPSCOUR;
  • list ($usec,$sec)=explode(" ",microtime());
  • $TPSDEB=$sec;
  • $TPSCOUR=0;
  • }
  • function tf() //temp final ou intermediaire
  • {
  • global $TPSDEB,$TPSCOUR;
  • list ($usec,$sec)=explode(" ",microtime());
  • $TPSFIN=$sec;
  • if (round($TPSFIN-$TPSDEB,1)>=$TPSCOUR+1) //une seconde de plus
  • {
  • $TPSCOUR=round($TPSFIN-$TPSDEB,1);
  • echo $TPSCOUR.".";
  • flush();
  • }
  • }
  • function restoreMySqlDump($dumpFile , $database , $mysqlUser , $mysqlPassword , $hostMySql, $duree)
  • {
  • // $dumpFile, fichier source
  • // $database, nom de la base de données cible
  • // $mysqlUser, login pouyr la connexion au serveur MySql
  • // $mysqlPassword, mot de passe
  • // $histMySql, nom de la machine serveur MySQl
  • // $duree=timeout pour changement de page (-1 = aucun)
  • global $TPSCOUR,$offset,$cpt;
  • $mySqlHandle = mysql_connect($hostMySql, $mysqlUser, $mysqlPassword);
  • if (!$mySqlHandle)
  • {
  • echo "Connexion impossible à $hostMySql pour $mysqlUser";
  • return false;
  • }
  • if(!file_exists($dumpFile))
  • {
  • echo "$dumpFile non trouvé<br>";
  • return FALSE;
  • }
  • $fileHandle = fopen($dumpFile, "rb");
  • if(!$fileHandle)
  • {
  • echo "Ouverture de $dumpFile non trouvé<br>";
  • return FALSE;
  • }
  • if ($offset!=0)
  • {
  • if (fseek($fileHandle,$offset,SEEK_SET)!=0) //erreur
  • {
  • echo "Impossible de trouver l'octet ".number_format($offset,0,""," ")."<br>";
  • return FALSE;
  • }
  • else
  • echo "Reprise à l'octet ".number_format($offset,0,""," ")."<br>";
  • flush();
  • }
  • else
  • {
  • $query = "DROP DATABASE IF EXISTS " . $database;
  • $result = mysql_query($query);
  • $query = "CREATE DATABASE " . $database;
  • $result = mysql_query($query);
  • }
  • $query = "USE " . $database;
  • $result = mysql_query($query);
  • $formattedQuery = "";
  • while(!feof($fileHandle))
  • {
  • tf();
  • if ($duree>0 and $TPSCOUR>=$duree) //on atteint la fin du temps imparti
  • return TRUE;
  • //echo $TPSCOUR."<br>";
  • $buffer=fgets($fileHandle);
  • if (substr($buffer,strlen($buffer),1)==0)
  • $buffer=substr($buffer,0,strlen($buffer)-1);
  • //echo $buffer."<br>";
  • if(substr($buffer, 0, 1) != "#")
  • {
  • $formattedQuery .= $buffer;
  • // echo $formattedQuery."<hr>";
  • if ($formattedQuery)
  • if (mysql_query($formattedQuery)) //réussie sinon continue à conca&téner
  • {
  • $offset=ftell($fileHandle);
  • //echo $offset;
  • $formattedQuery = "";
  • $cpt++;
  • //echo $cpt;
  • }
  • }
  • }
  • if (mysql_error())
  • echo "<hr>ERREUR à partir de [$formattedQuery]<br>".mysql_error()."<hr>";
  • fclose($fileHandle);
  • mysql_close($mySqlHandle);
  • $offset=0;
  • return TRUE;
  • }
  • td(); //initialise le temps
  • if (!isset($offset)) $offset=0; //début de fichier
  • if (!isset($duree)) $duree=5; //timeout de 5 secondes par défaut, -1 pour utiliser sans timeout
  • if (!isset($fichier)) $fichier="sauvebase.sql"; //si le nom du fichier n'est pas en paramètre le mettre ici
  • echo "Restauration de $fichier.<br>Traitement en cours... ";
  • if ($duree>0) echo "timeout de $duree s.<br>";
  • flush();
  • //echo "$offset";
  • //exit;
  • //nom du fichier, nom de la base, nom d'utilisateur, mot de passe, serveur, duree
  • if (restoreMySqlDump($fichier , "base" , "root" , "pass", "localhost",$duree))
  • {
  • if ($offset!=0)
  • {
  • echo "<br>Nombre de requêtes traitées à ce stade : $cpt<br>";
  • echo "<br>mais il faut continuer à l'octet ".number_format($offset,0,""," ");
  • echo "<br>Redirection automatique sinon cliquez <a href=\"restore.php?duree=$duree&offset=$offset&cpt=$cpt\">ici</a>";
  • echo "<script>window.location=\"restore.php?duree=$duree&offset=$offset&cpt=$cpt\";</script>";
  • }
  • else
  • echo "<br>Terminé. Nombre de requêtes totales traitées : $cpt<br>";
  • }
  • ?>
  • </body>
  • </html>
<html>
<head><title>Restauration de base MySql</title></head>
<body>
<?
function td() //temp initial
{
  global $TPSDEB,$TPSCOUR;
  
  
  list ($usec,$sec)=explode(" ",microtime());
  $TPSDEB=$sec;
  $TPSCOUR=0;

}

function tf() //temp final ou intermediaire
{
  global $TPSDEB,$TPSCOUR;
  list ($usec,$sec)=explode(" ",microtime());
  $TPSFIN=$sec;
  if (round($TPSFIN-$TPSDEB,1)>=$TPSCOUR+1) //une seconde de plus
  {
    $TPSCOUR=round($TPSFIN-$TPSDEB,1);
    echo $TPSCOUR.".";
    flush();
  }

}

function restoreMySqlDump($dumpFile , $database , $mysqlUser , $mysqlPassword , $hostMySql, $duree)
{
 // $dumpFile, fichier source
 // $database, nom de la base de données cible
 // $mysqlUser, login pouyr la connexion au serveur MySql
 // $mysqlPassword, mot de passe
 // $histMySql, nom de la machine serveur MySQl
 // $duree=timeout pour changement de page (-1 = aucun)

global $TPSCOUR,$offset,$cpt;

 $mySqlHandle = mysql_connect($hostMySql, $mysqlUser, $mysqlPassword);
 if (!$mySqlHandle)
 {
   echo "Connexion impossible à $hostMySql pour $mysqlUser";
   return false;
 }

 if(!file_exists($dumpFile))
 {
   echo "$dumpFile non trouvé<br>";
   return FALSE;
 }
 $fileHandle = fopen($dumpFile, "rb");

 if(!$fileHandle)
 {
  echo "Ouverture de $dumpFile non trouvé<br>";
  return FALSE;
 }

 if ($offset!=0)
 {
   if (fseek($fileHandle,$offset,SEEK_SET)!=0) //erreur
   {
      echo "Impossible de trouver l'octet ".number_format($offset,0,""," ")."<br>";
      return FALSE;
   }
   else
     echo "Reprise à l'octet ".number_format($offset,0,""," ")."<br>";
  flush();
 }
 else
 {
   $query = "DROP DATABASE IF EXISTS " . $database;
   $result = mysql_query($query);
   $query = "CREATE DATABASE " . $database;
   $result = mysql_query($query);
  }
  
  $query = "USE " . $database;
  $result = mysql_query($query);


 $formattedQuery = "";

 while(!feof($fileHandle))
 {
    tf();
    if ($duree>0 and $TPSCOUR>=$duree) //on atteint la fin du temps imparti
      return TRUE;
    //echo $TPSCOUR."<br>";
    $buffer=fgets($fileHandle);
    if (substr($buffer,strlen($buffer),1)==0)
      $buffer=substr($buffer,0,strlen($buffer)-1);
    
    //echo $buffer."<br>";
    
    if(substr($buffer, 0, 1) != "#")
    {
      $formattedQuery .= $buffer;
       // echo $formattedQuery."<hr>";
      if ($formattedQuery)
        if (mysql_query($formattedQuery)) //réussie sinon continue à conca&téner
        {
          $offset=ftell($fileHandle);
          //echo $offset;
          $formattedQuery = "";
          $cpt++;
          //echo $cpt;
        }
  }
 }

 if (mysql_error())
   echo "<hr>ERREUR à partir de [$formattedQuery]<br>".mysql_error()."<hr>";

 fclose($fileHandle);
 mysql_close($mySqlHandle);
 $offset=0;
 return TRUE;
}


td(); //initialise le temps
if (!isset($offset)) $offset=0; //début de fichier
if (!isset($duree)) $duree=5; //timeout de 5 secondes par défaut, -1 pour utiliser sans timeout

if (!isset($fichier)) $fichier="sauvebase.sql"; //si le nom du fichier n'est pas en paramètre le mettre ici

echo "Restauration de $fichier.<br>Traitement en cours... ";

if ($duree>0) echo "timeout de $duree s.<br>";
flush();
//echo "$offset";
//exit;
//nom du fichier, nom de la base, nom d'utilisateur, mot de passe, serveur, duree
if (restoreMySqlDump($fichier , "base" , "root" , "pass", "localhost",$duree))
{
  if ($offset!=0)
  {
    echo "<br>Nombre de requêtes traitées à ce stade : $cpt<br>";
    echo "<br>mais il faut continuer à l'octet ".number_format($offset,0,""," ");
    echo "<br>Redirection automatique sinon cliquez <a href=\"restore.php?duree=$duree&offset=$offset&cpt=$cpt\">ici</a>";
    echo "<script>window.location=\"restore.php?duree=$duree&offset=$offset&cpt=$cpt\";</script>";
  }
  else
   echo "<br>Terminé. Nombre de requêtes totales traitées : $cpt<br>";

}

?>
</body>
</html>

 Conclusion

Le script de restauration est lui meme repris dans les scripts de ce site. Je n'ai fait qu'ajouter la gestion du timeout.

J'ai essayé de mettre un affichage de la progression, mais on ne la voit pas vraiment. Si le javascript est activé, la boucle se fait toute seule il n'y a rien à faire qu'attendre. Sinon en fin de chaque script il y a possibilité de cliquer pour activer le suivant.


 Sources de la même categorie

Source avec Zip RECHERCHE DES DOUBLONS DANS UNE TABLE MYSQL EN SÉLECTIONNANT... par aladec2007
[CRON] INSERT ON DUPLICATE KEY UPDATE par pierreSabatier
Source avec Zip CLASS MYSQL 5/PHP5 AVEC GESTION DES EXCEPTION ET DES REQUÊTE... par devil_may_cry
Source avec Zip Source avec une capture MOTEUR DE RECHERCHE SUR BASE MYSQL FULLTEXT ET BOOLEAN AVEC ... par cod57
SYSTÈME DE PAGINATION AVEC BDD ET IMAGES (FICHIERS) par begueradj

Commentaires et avis

Commentaire de Magicking le 06/07/2004 18:51:52

set_time_limit(0);
Et hop tu n'as plus de time limit(c'est fonction n'est pas autorisé partout)

Commentaire de multicite le 07/11/2005 22:47:02

Bien sûr j'aurais du le préciser... pour les hébergeurs qui bloquent la fonction
set_time_limit(0);

ce qui à mon avis est la majorité...

Je n'ai jamais réussi à faire fonctionner
set_time_limit(0);
qu'en local sur mon serveur et jamais chez un hébergeur... ce serait une belle faille de sécurité

Commentaire de Shibo_Sources le 17/12/2005 19:59:02

Script super utile, merci!!!
J'aurais bien voulu l'utiliser mais vu que le copier/coller copie aussi le numero de chaque ligne j'ai pas envie de me taper la suppression à la main. Rhalala, bon script + mauvais site mal coder = script qui ne sera jamais utilisé...

Commentaire de Gantz le 24/07/2006 11:42:00

[Hors sujet]effectivement les numeros de lignes suivent lors d'un copier/coller du code, mais le phenomene ne se produit pas avec Internet Explorer ... chez moi ca ne le fait qu'avec FireFox... sacre renard!

il faudrait un systeme de caddie comme chez nexen.net par exemple

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 2,761 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales