DUPLICATION D'UNE BASE DE DONNÉES POUR SAUVEGARDE

webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 - 19 déc. 2008 à 00:51
zroxx Messages postés 1 Date d'inscription jeudi 13 novembre 2008 Statut Membre Dernière intervention 30 avril 2009 - 30 avril 2009 à 04:03
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/48742-duplication-d-une-base-de-donnees-pour-sauvegarde

zroxx Messages postés 1 Date d'inscription jeudi 13 novembre 2008 Statut Membre Dernière intervention 30 avril 2009
30 avril 2009 à 04:03
Bonjour,

j'ai utilisé ce script il marche très bien, mais lorsque les table sont copiés il semble que l'auto incrémentation ne se copie pas. Ça ajoute également la valeur "0" par défault...

qqun a-t-il une solution ? c'est une variable de mysql qui n'est pas correcte ?

merci !
pouyelayese Messages postés 7 Date d'inscription vendredi 9 mai 2008 Statut Membre Dernière intervention 28 avril 2014
11 janv. 2009 à 17:28
slt je m'adresse à fmarie s'il peut mettre des commentaires dans son code car pour les débutants comme nous c'est un peu difficile de comprendre.
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
21 déc. 2008 à 00:04
>> Sinon, pourquoi ne pas utiliser l'extension mysqli plutôt que mysql ?

Ou même PDO tant qu'à faire :)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
20 déc. 2008 à 22:15
Salut,

Concernant l'exécution d'un script shell par l'utilisateur, il est vivement recommandé, à moins d'apporter un soin extrême à la configuration de PHP et du serveur (ce qui n'est pas une mince affaire), de ne pas le faire directement par PHP.

Le mieux est, comme le disait WebDeb, d'utiliser une tâche auto avec cron, exécutée sous root.
Il n'est pas nécessaire que la tâche soit exécutée 1 fois par jour... On peut imaginer que le script de backup cherche un fichier précis à un endroit précis (lequel aura été créé par PHP dans un répertoire de l'utilisateur qui ne se trouve pas dans l'arborescence de publication http). Si le fichier est trouvé (il peut d'ailleurs contenir le(s) nom(s) de la / des base(s) à sauvegarder), alors le dump est effectué. Sinon, non.
Cette tâche peut très bien être exécutée toutes les 5/10 minutes par exemple.
Dans le même ordre d'idée, pour la restauration, on peut imaginer l'inverse... L'utilisateur doit placer son fichier .sql à un endroit précis. La tâche de restauration cherche les fichiers SQL dans ce répertoire précis et les exécute. Idem, elle peut tourner toutes les 5/10 minutes.

C'est à mon avis une des solutions les plus simples à mettre en place sans sacrifier la sécurité (plutôt que d'avoir un script PHP qui exécute un script shell contenant le mot de passe MySQL de root) et, puisque tu t'adresses à des personnes qui ont un serveur dédié, bien plus adaptées qu'un script PHP.

Pour revenir sur le point 2 évoqué par WebDeb : pourquoi utiliser MySQL connect sur chaque page avec des variables définies dans un autre fichier ? Pourquoi ne pas simplement inclure un fichier qui contient la fonction mysql_connect() avec les arguments ? Bon c'est du détail, hein...

Sinon, pourquoi ne pas utiliser l'extension mysqli plutôt que mysql ?
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
19 déc. 2008 à 19:26
# mysql_query($SQL);
# if (!$SQL) {

<=>

# $truc = mysql_query($SQL);
# if (!$truc) {
fmarie Messages postés 6 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 19 décembre 2008
19 déc. 2008 à 14:27
Ok ! Merci de l'information !
Mes bases sont en effet en MyISAM.

Et si tu as encore 5 minutes à me consacrer pour les questions de mon message de 01:14:52 ;)
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
19 déc. 2008 à 13:23
Les transactions ne fonctionnent que si tes bases de données utilisent le moteur de stockage InnoDB. Si tu es en MyISAM, ça ne fera rien, bien que les requêtes BEGIN, COMMIT et ROLLBACK s'exécutent bien.
fmarie Messages postés 6 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 19 décembre 2008
19 déc. 2008 à 12:14
J'ai oublié de mettre la ligne :
begin();

entre :

$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";

et

$result=@mysql_query($SQL);
fmarie Messages postés 6 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 19 décembre 2008
19 déc. 2008 à 12:12
A l'attention de Webdeb !
J'ai cherché un peu sur le point 7 et les transactions.

Si je fais quelque chose de ce type :
<?
$db="base"; // Base a sauvegarder
$dbdest=$db."_".date("Ymd_Hi"); // Cela créera la base avec le nom de la base intiale + date et heure ex : base_20001231_2359

function begin()
{
@mysql_query("BEGIN");
}
function commit()
{
@mysql_query("COMMIT");
}
function rollback()
{
@mysql_query("ROLLBACK");
}

$connexion=mysql_connect("localhost","root","pass"); //on effectue la connexion
if (!$connexion) {
die('Connexion impossible : ' . mysql_error());
exit;
}

echo "Lancement de la sauvegarde

\n";

//Création de la base de données de sauvegarde
$SQL="CREATE DATABASE `$dbdest` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; // Si besoin modifier les character
mysql_query($SQL);
if (!$SQL) {
die('Erreur sur la creation de la base $dbdest : ' . mysql_error());
exit;
}

echo "Base $dbdest créée.
\n";

//Création et copie des tables
$tables = mysql_list_tables($db, $connexion);
while ($enr = mysql_fetch_row($tables)) {
$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";
$result=@mysql_query($SQL);
if (!$result) {
rollback();
die('Requête invalide sur la table $enr[0] : ' . mysql_error());
exit;
}else{
commit();
echo "TABLE ".$enr[0]." sauvegardée.
\n";
}
}
echo "

Sauvegarde terminée. La base de sauvegarde est $dbdest.
\n\n";
mysql_close($connexion);
?>

Est-ce que cela parait correct ?
J'ai lu cet article et repris les fonctions de départ :
http://www.devarticles.com/c/a/MySQL/Using-Transactions-with-MySQL-4.0-and-PHP/
fmarie Messages postés 6 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 19 décembre 2008
19 déc. 2008 à 01:14
Je passerai sur les différents points où tu as raison et que je modifierai plus tard en effet, à savoir les points 1,3,4,6,8.
Point 2, je fais un include logiquement pour n'avoir qu'un fichier de connexion et j'ai simplement fait la copie des variables.
Point 5, à vrai dire, je n'ai pas trouver la solution et je n'ai pas non plus cherché beaucoup en effet. Si tu as la réponse, je suis preneur.
Point 7, qu'appelle-tu transaction ? Un lien d'explication me suffira.

En ce qui concerne le dump, je suis évidement d'accord avec toi mais je ne sais pas comment faire pour que sur une page d'administration d'un site internet, les utilisateurs puissent lancer cet utilitaire à tout moment.
Pour moi, l'important est que les utilisateurs puissent faire une sauvegarde avant de modifier de façon significative une base de données.

Merci de tes éventuelles réponses.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
19 déc. 2008 à 01:04
c'est a cause de lignes comme ca :

$connexion=mysql_connect("$host","$user","$password");

que beaucoup de gens pensent que php est un langage de merde.

c'est pas du bash la... c'est du php !
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
19 déc. 2008 à 00:51
Ca ne sert strictement à rien comme code. Tu t'exposes à de gros problèmes de pertes de cohérence des données au moment de la sauvegarde en procédant de cette manière. De plus ton code est complètement mal écrit pour de multiples raisons :

1/ Le bon tag PHP d'ouverture de script est <?php et non <? qui peut-être désactivés sur les serveurs dignes de ce nom,
2/ Quel est l'intérêt de faire des variables pour stocker les identifiants de connexion plutôt que de les écrire directement en dur dans le mysql_connect() ?
3/ Que se passe-t-il si la connexion au serveur SQL ne se fait pas ? Pourquoi le script continue-t-il ?
4/ Pourquoi mettre des apostrophes inutiles autour des variables ?
5/ Et si je n'utilise pas l'UTF-8 comme encodage de chaque table ?
6/ Que se passe-t-il si un mysql_query() échoue ? Pourquoi continuer le script ?
7/ Malheureusement, il n'y a aucune transaction (donc pas de moteur de stockage InnoDB) pour assurer que toutes les données ont bien été copiées et que l'intégrité référentielle entre les tables a été respectée.
8/ Pas de mysql_close() ?
9/ ...

Bref tout ça pour dire que tu peux jeter ton code à la poubelle ! On ne fait jamais de backups d'une base de données comme ça sur un site en production, c'est complètement fou. Un backup doit être réalisé par une tâche automatique qui lance périodiquement un script shell qui appelle par exemple l'utilitaire mysqldump. C'est beaucoup beaucoup beaucoup beaucoup plus performant et beaucoup beaucoup beaucoup moins dangereux pour la base de données car mysqldump est un utilitaire qui maîtrise les sauvegardes et qui est conçu pour ça.

Pour rappel :

mysqldump -u root -p MaDatabase > MaDatabase.sql

permet en 1 ligne de commande de dumper proprement MaDatabase dans le fichier MaDatabase.sql.
Rejoignez-nous