begin process at 2012 05 27 18:10:04
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Base de données

 > PROGRAMMER DES COPIES DE TABLES SUR UNE BASE MYSQL

PROGRAMMER DES COPIES DE TABLES SUR UNE BASE MYSQL


 Information sur la source

 Description

Intervenant à titre amical sur des sites persos en PHP/MySQL, j'ai rencontré le problème de prévoir un minimum de sauvegarde des données à l'intérieur de la même base. La solution présentée ici permet de programmer simplement des copies périodiques des tables voulues de la BDD.

Tout d'abord, il faut ajouter deux tables à la BDD, que je nomme `maintenance` et `sauvegardes`. La première contient le nom des tables à copier et le délai entre deux sauvegardes (en jours). Le webmaster n'a plus qu'à y indiquer les tables dont il souhaite une copie et la périodicité. La seconde table enregistre pour chaque table à sauvegarder la date de la dernière copie.

Ensuite vous devez appeler la fonction PHP svg_tables(), par exemple sur votre page d'accueil. A chaque fois qu'un internaute consulte cette page, svg_tables() vérifie s'il y a des tables à copier. Si c'est le cas, chaque table est copiée dans une nouvelle portant le même nom suivi de _copie, en écrasant au besoin les copies précédentes.

Source

  • -- Code SQL de création des deux tables `maintenance` et `sauvegardes`
  • CREATE TABLE maintenance (
  • nom_table varchar(255) NOT NULL ,
  • delai tinyint(3) unsigned NOT NULL default 0,
  • PRIMARY KEY (nom_table)
  • )
  • CREATE TABLE sauvegardes (
  • nom_table varchar(255) NOT NULL ,
  • date_copie datetime NOT NULL ,
  • PRIMARY KEY (nom_table)
  • )
  • // fonction PHP qui effectue la copie des tables selon les indications de la table maintenance
  • function svg_tables() {
  • global $BDD ; // je suppose qu'une connexion à la base est ouverte et référencée par $BDD
  • $sql = "SELECT M.nom_table
  • FROM maintenance M
  • LEFT JOIN sauvegardes S ON M.nom_table = S.nom_table
  • WHERE M.delai > 0
  • AND (S.date_copie IS NULL
  • OR CURDATE() > DATE_ADD(S.date_copie, INTERVAL delai DAY)
  • )" ;
  • $req = mysql_query($sql, $BDD) ;
  • while ($lig = mysql_fetch_array($req) ) {
  • $table = $lig['nom_table'] ;
  • $sql = "DROP TABLE IF EXISTS {$table}_copie " ;
  • mysql_query($sql, $BDD) ;
  • $sql = "CREATE TABLE {$table}_copie SELECT * FROM $table " ;
  • mysql_query($sql, $BDD) ;
  • $sql = "REPLACE INTO sauvegardes (nom_table, date_copie) VALUES ('$table', CURDATE() ) " ;
  • mysql_query($sql, $BDD) ;
  • }
  • mysql_free_result($req) ;
  • }
-- Code SQL de création des deux tables `maintenance` et `sauvegardes`
CREATE TABLE maintenance (
  nom_table varchar(255) NOT NULL ,
  delai tinyint(3) unsigned NOT NULL default 0,
  PRIMARY KEY  (nom_table)
) 

CREATE TABLE sauvegardes (
  nom_table varchar(255) NOT NULL ,
  date_copie datetime NOT NULL ,
  PRIMARY KEY  (nom_table)
)

// fonction PHP qui effectue la copie des tables selon les indications de la table maintenance
function svg_tables() {
	global $BDD ; // je suppose qu'une connexion à la base est ouverte et référencée par $BDD
	$sql = "SELECT M.nom_table
		FROM maintenance M
			LEFT JOIN sauvegardes S ON M.nom_table = S.nom_table
		WHERE M.delai > 0 
			AND (S.date_copie IS NULL 
				OR CURDATE() > DATE_ADD(S.date_copie, INTERVAL delai DAY)
			)" ;
	$req = mysql_query($sql, $BDD) ;

	while ($lig = mysql_fetch_array($req) ) {
		$table = $lig['nom_table'] ;
		$sql = "DROP TABLE IF EXISTS {$table}_copie " ;
		mysql_query($sql, $BDD) ;
		$sql = "CREATE TABLE {$table}_copie SELECT * FROM $table " ;
		mysql_query($sql, $BDD) ;
		$sql = "REPLACE INTO sauvegardes (nom_table, date_copie) VALUES ('$table', CURDATE() ) " ;
		mysql_query($sql, $BDD) ;
	}
	mysql_free_result($req) ;
}

 Conclusion

Pour être un peu plus précis, une table est copiée dans deux cas :
- le délai de sauvegarde a été atteint la veille
- la table n'a jamais été copiée

Si, le 1er août à 11h, vous ajoutez une table avec copie quotidienne (delai = 1), la première copie aura lieu dès que quelqu'un appelera la page avec le déclencheur, et la suivante se produira à partir du 3 août à 0h (la condition étant Curdate > date_copie + 1 j).

A noter qu'un délai de 0 désactive la copie de la table en question ; le délai minimum est donc de 1.

Enfin, si votre craignez de ne pas avoir au moins un visiteur chaque jour, il ne vous reste plus qu'à programmer un cron pour appeler votre page régulièrement... ou à la mettre en page d'accueil de votre navigateur ;-)


 Sources de la même categorie

Source avec Zip ORM : DAO, ACTIVERECORD ET DBLIST par Reldan
Source avec une capture CET EXTRAIT PERMET D'AJOUTER DANS UN TABLEAU UNE AGRÉGATION ... par Denis007
EXPORT DE BASE AU FORMAT CSV par remib74
Source avec Zip RECHERCHE DES DOUBLONS DANS UNE TABLE MYSQL EN SÉLECTIONNANT... par aladec2007
[CRON] INSERT ON DUPLICATE KEY UPDATE par pierreSabatier

 Sources en rapport avec celle ci

Source avec Zip RECHERCHE DES DOUBLONS DANS UNE TABLE MYSQL EN SÉLECTIONNANT... par aladec2007
Source avec Zip Source avec une capture CONVERTIR BASE FIREBIRD EN MYSQL par castelfrederic29
Source avec une capture SQL/EXE EXECUTEUR DE REQUETTES SQL par enokbyreal
SONDAGE - VOTE - POLL (AVEC MYSQL) par hornet_bzz
Source avec Zip EXTEND MYSQLI par petibras

Commentaires et avis

Commentaire de Anthomicro le 31/07/2005 13:06:26

Salut,

si j'ai bien compris, tu prends une table que tu recopies dans une autre table dans ta boucle ?

Pourquoi ne pas faire une seule requête au lieu de faire de multiples requêtes dans ta boucle ?

Une requête à base d'INSERT INTO table(SELECT INTO autre_table champ,champ2)... ?

à moins que tu aies déjà tenté de le faire ;-)

a +

Commentaire de antoinedi le 31/07/2005 14:27:16

Je ne suis pas sûr de très bien comprendre ta question... Voici des éléments de réponse :

1) je ne copie une table ligne par ligne, et je ne copie pas non plus une table dans une autre qui existerait déjà ; je fais un CREATE... SELECT pour chacunes DES tables à copier. Ma boucle est donc une boucles des tables et non une boucles des lignes.

2) je préfère de loin mon CREATE... SELECT que le INSERT... SELECT que tu proposes. INSERT est un peu plus rapide, mais il complique la tâche du webmaster, qui doit alors créer lui-même un clone de chacune des tables qu'il veut sauvegarder, et le re-créer à chaque modification de structure de la table d'origine.

CREATE fait lui-même le clone à chaque fois ; tout ce que le webmaster a à faire c'est de renseigner le nom de la table à copier et la fréqence de copie, le reste se fait tout. Comme c'est un script qui tournera au maximum une fois par jour, économiser quelques dixièmes de seconde ne présente pas un intérêt énorme...

3) tu parles de "multiples requêtes" dans la boucle. Il y a trois requêtes dans ma boucle : la première supprime un éventuel clone déjà existant ; la deuxième effectue la copie ; la troisième renseigne la nouvelle date de copie dans `sauvegardes`. La première et la troisième pourraient effectivement être sorties de la boucle, mais au détriment de l'atomicité des traitements...

... autrement dit, je pourrais faire un DROP table1_copie, table2_copie, etc. juste avant la boucle. Mais si qqch déconne au cours du traitement, par exemple si une table est trop grosse et que sa copie dépasse le temps d'exécution alloué par le serveur, j'ai perdu toutes mes sauvegardes ! (mon script actuel n'en perd qu'une)

De même, je pourrai faire un seul REPLACE INTO `sauvegardes` à la fin de la boucle, mais si le script est interrompu est cours de boucle, la date de màj ne sera renseignée pour aucune des tables.

Là encore, ce script n'est amené à tourner qu'au maximum une fois par jour, donc la performance est un objectif très secondaire par rapport à la sécurité, la facilité de maintenance, etc.

Commentaire de Anthomicro le 31/07/2005 14:32:54

Merci pour ces explications claires, effectivement pour la boucle je pensais que c'était une boucle par ligne de table, d'où mon commentaire.

a +

Commentaire de tchoulak le 01/08/2005 06:41:52

Je ne veut pas dire mais ca sert a quoi cette source si t'as un crash de serveur et que tu pert toute ta BDD, t'as beau avoir fait des sauvegardes ca servira a rien, le but d'une sauvegarde c'est de conserver une copie a un autre endroit !

Commentaire de hellodelu007 le 01/08/2005 10:07:27

Non seulement le crash du serveur de BdD perdra toutes les infos, mais en plus je me demande comment ce script se comporte avec une grosse table ?

Commentaire de antoinedi le 01/08/2005 11:19:58

Tchoulak : J'ai mis en place ce script suite à la suppression accidentelle de la table principale d'un site par le webmaster... C'est un contexte de site perso/associatif chez un hébergeur spécialisé, où le risque n'est pas le crash serveur mais l'administration par un non-professionnel, le développement à chaud, les erreurs de manipes, etc.

Hellodelu007 : ce script fait un CREATE... SELECT table par table, sans parallélisation... encore une fois, ce script est un système minimaliste qui ne prétend pas répondre à des besoins de taille professionnelle, mais simplement simplifier la vie des amateurs.

Commentaire de Anthomicro le 01/08/2005 11:55:13

Pour parfaire un minimum je pense que tu pourrais sauvegarder ça dans une autre base, mais c'est sûr qu'un petit fichier contenant les requêtes serait pas mal ;-)

Commentaire de hellodelu007 le 01/08/2005 12:32:48

Ou bien simplement recréer l'export de MySQL et le stocker dans sur un FTP ? Ca ne serait pas possible ?

Commentaire de Anthomicro le 01/08/2005 12:37:59

Si ça serait possible, et ça serait préférable ;-)

Commentaire de hellodelu007 le 01/08/2005 14:01:03

Et puis pourquoi pas avec un petit zippage du fichier au passage, et un petit Hashage pour verifier son intégrité à la fin ?
Tout cela en automatique ?
Bon, d'accord, ca s'eloigne de la première source, j'admets... :)

Commentaire de hellodelu007 le 01/08/2005 14:01:17

Et puis pourquoi pas avec un petit zippage du fichier au passage, et un petit Hashage pour verifier son intégrité à la fin ?
Tout cela en automatique ?
Bon, d'accord, ca s'eloigne de la première source, j'admets... :)

Commentaire de caviar le 29/09/2006 14:58:11

ouaip effectivement ça serai achement bien ça !
faudrait y penser à l'export zip avec sauvegarde de la bdd sur le serveur direct ;)
cool !!!
@+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

mysql et php [ par nico606 ] Salut g un probleme je debute en php et je viens de charger un espace membre pour mon site il est evidemment en php et Mysql y a une page d'installati Select dans deux table [ par speedylol ] Bonjour j aimerais selectionner un champs ou plusieur de deux table mes je vois pas comment faire cela sauriez vous m'aider merci? car je débute en ph besoins d'aide pour E-commerce [ par speedylol ] Bonjour j aimerais selectionner un champs ou plusieur de deux table mes je vois pas comment faire cela sauriez vous m'aider merci?car je débute en php Creer MySQL database [ par pluton83fr ] Slt Je suis un debutant en php, Je suis en train d installer un portail :Neocrome http://www.neocrome.net Et il me dise ca!!Mais le pb c'est que je n Création de table [ par chatainsim ] Bonsoir, j'ai une petite question, comment crée des tables mysql à l'aide du php ? En fait j'aimerais pouvoir créer une installation au Création de table [ par chatainsim ] Bonsoir, j'ai une petite question, comment crée des tables mysql à l'aide du php ? En fait j'aimerais pouvoir créer une installation au pb DELETE requete sql [ par kyript ] Bonjours à tous voila mon problème j'ai un script avec un formulaire qui met a jour une table de la bdd. A la fin de ce script j'ai un "i Probleme recuperation de l'id d'une table pour insérer dans une autre par la methode update [ par Alpha911 ] Bonjour,Je test plusieurs methodes pour pouvoir prendre l'id d'une table qui et la recopier dans une autre table j'ai 2 tables UTILISATEUR et une autr Afficher données de 2 tables dans un tableau [ par Chewba ] Bonjour, Je cherche comment je peux faire pour afficher les données provenant de 2 tables différentes dans un tableau.J'ai une table Roster_members et Affichage du plut grand au plutspetit [ par f1actu ] Bonjour alors , j'ai une table "cla" et dans cette table cla , un champs qui se nomme "total" et je voudrai qui s'affiche du plus grand au plus petit


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
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 : 0,671 sec (4)

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