web-dev-qa-db-fra.com

Comment déplacer une base de données d'un serveur à un autre?

Comment déplacer des tables MySQL d'un serveur physique à un autre?

Tels que ce scénario exact: J'ai un serveur MySQL qui utilise la table innodb et a une taille d'environ 20 Go.

Je veux le déplacer vers un nouveau serveur, quelle est la façon la plus efficace de procéder?

142
John

Ma façon préférée est de diriger une commande sqldump vers une commande sql. Vous pouvez créer toutes les bases de données ou une spécifique. Ainsi, par exemple,

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

Vous pouvez faire toutes les bases de données avec

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

Le seul problème est lorsque la base de données est trop grande et que le tuyau s'effondre. Dans ce cas, vous pouvez faire table par table ou l'une des autres méthodes mentionnées ci-dessous.

84
David Hall

J'ai récemment déplacé une base de données de 30 Go avec la stratégie suivante:

Ancien serveur

  • Arrêter le serveur mysql
  • Copiez le contenu de datadir vers un autre emplacement sur le disque (~/mysqldata/*)
  • Redémarrez le serveur mysql (le temps d'arrêt était de 10 à 15 minutes)
  • compresser les données (tar -czvf mysqldata.tar.gz ~/mysqldata)
  • copier le fichier compressé sur un nouveau serveur

Nouveau serveur

  • installer mysql (ne pas démarrer)
  • décompressez le fichier compressé (tar -xzvf mysqldata.tar.gz)
  • déplacer le contenu de mysqldata vers datadir
  • Assurez-vous que votre innodb_log_file_size est le même sur le nouveau serveur, ou si ce n'est pas le cas, ne copiez pas les anciens fichiers journaux ( mysql générera ces )
  • Démarrez mysql
67
Derek Downey

Selon le MySQL 5.0 Certification Study Guide , Chapter 32 Section 32.3.4, Pages 456,457 décrivent les Conditions de portabilité binaire qui faire ressortir ce qui suit:

La portabilité binaire est importante si vous souhaitez effectuer une sauvegarde binaire effectuée sur une machine et l'utiliser sur une autre machine ayant une architecture différente. Par exemple, l'utilisation d'une sauvegarde binaire est un moyen de copier des bases de données d'un serveur MySQL vers un autre.

Pour MyISAM, la portabilité binaire signifie que vous pouvez copier directement les fichiers d'une table MyISAM d'un serveur MySQL vers un autre sur une machine différente et le deuxième serveur pourra accéder à la table.

Pour InnoDB, la portabilité binaire signifie que vous pouvez copier directement les fichiers du tablespace d'un serveur MySQL sur une machine vers un autre serveur sur une machine différente et le deuxième serveur pourra accéder au tablespace. Par défaut, toutes les tables InnoDB gérées par un serveur sont stockées ensemble dans l'espace table, donc la portabilité de l'espace table est fonction du fait que toutes les tables InnoDB individuelles sont portables. Si même une table n'est pas portable, l'espace de table ne l'est pas non plus.

Les tables MyISAM et les espaces de table InnoDB sont portables binaires d'un hôte à un autre si deux conditions sont remplies:

  • Les deux machines doivent utiliser l'arithmétique à deux compléments
  • Les deux machines doivent utiliser le format à virgule flottante IEEE, sinon les tables ne doivent contenir aucune colonne à virgule flottante (FLOAT ou DOUBLE)

En pratique, ces deux conditions posent peu de restrictions. L'arithmétique à deux entiers et le format à virgule flottante IEEE sont la norme sur le matériel moderne. Une troisième condition pour la portabilité binaire InnoDB est que vous devez utiliser des noms en minuscules pour les tables et les bases de données. En effet, InnoDB stocke ces noms en interne (dans son dictionnaire de données) en minuscules sous Windows. L'utilisation de noms en minuscules permet la portabilité binaire entre Windows et Unix, pour forcer l'utilisation de noms en minuscules, vous pouvez placer les lignes suivantes dans un fichier d'options:

[mysqld]
lower_case_table_names=1

Si vous configurez InnoDB pour utiliser des espaces de table par table, les conditions de portabilité binaire sont étendues pour inclure également les fichiers .ibd pour les tables InnoDB. (Les conditions pour les espaces de table partagés s'appliquent toujours car il contient le dictionnaire de données qui stocke des informations sur toutes les tables InnoDB.)

Si les conditions de portabilité binaire ne sont pas remplies, vous pouvez copier les tables MyISAM ou InnoDB d'un serveur à un autre en les vidant en utilisant un certain format de texte (par exemple, avec mysqldump) et en les rechargeant sur le serveur de destination.

Il existe deux méthodes principales basées sur le moteur de stockage pour déplacer des tables individuelles.

Pour l'exemple donné, nous supposerons ce qui suit:

  1. datadir est/var/lib/mysql
  2. base de données appelée mydb
  3. table dans mydb base de données appelée mytable.

Tables MyISAM

Si mydb.mytable utilise le moteur de stockage MyISAM, le tableau se manifestera physiquement sous la forme de trois fichiers distincts

  1. /var/lib/mysql/mydb/mytable.frm (fichier .frm)
  2. /var/lib/mysql/mydb/mytable.MYD (fichier .MYD)
  3. /var/lib/mysql/mydb/mytable.MYI (fichier .MYI)

Le .frm contient la structure de la table
Le .MYD contient les données de la table
Le .MYI contient la page d'index de table

Ces fichiers sont utilisés de manière interdépendante pour représenter la table d'un point de vue logique dans mysql. Étant donné que ces fichiers n'ont plus aucune association logique à leur associer, la migration d'une table d'un serveur de base de données vers un autre. Vous pouvez même y accéder depuis un serveur Windows vers un serveur Linux ou un MacOS. Bien sûr, vous pouvez arrêter mysql et copier les 3 fichiers de table. Vous pouvez exécuter ce qui suit:

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

en une seule session ssh pour tenir la table en lecture seule et maintenir le verrou pendant 24 heures. Une seconde plus tard, effectuez la copie dans une autre session ssh. Ensuite, tuez la session mysql avec le verrou de 24 heures. Vous n'avez pas besoin d'attendre 24 heures.

Tables InnoDB

Sur la base de la citation susmentionnée du livre de certification, de nombreux facteurs régissent la façon de sauvegarder une table InnoDB spécifique. Pour des raisons de simplicité, de clarté et de brièveté, effectuez simplement un vidage mysqld de la table souhaitée en utilisant les paramètres --single-transaction pour avoir un vidage ponctuel parfait de la table. Pas besoin de vous soucier de la sémantique InnoDB si vous ne voulez qu'une seule table. Vous pouvez recharger ce fichier de vidage sur n'importe quel serveur MySQL de votre choix.

Puisque deux questions ont été fusionnées ici (jcolebrand): EDIT

Si vous êtes plus que disposé à vivre avec des performances de base de données lentes, vous pouvez effectuer une série de rsyncs de l'ancien serveur (ServerA) vers le nouveau serveur (ServerB) même si mysql est toujours en cours d'exécution sur ServerA.

Étape 01) installez la même version de mysql sur ServerB que ServerA a

Étape 02) Sur ServerA, exécutez SET GLOBAL innodb_max_dirty_pages_pct = 0; de mysql et environ 10 minutes (Cela purge les pages sales du pool de tampons InnoDB. Il permet également d'effectuer un arrêt mysql plus rapidement) Si votre base de données est entièrement MyISAM, vous pouvez ignorer cette étape.

Étape 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

Étape 04) Répétez l'étape 03 jusqu'à ce qu'une rsync prenne moins de 1 minute

Étape 05) service mysql stop sur ServerA

Étape 06) Effectuez un rsync supplémentaire

Étape 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Étape 08) service mysql start sur ServerB

Étape 08) service mysql start sur ServerA (facultatif)

Essaie !!!

CAVEAT

Vous pouvez créer un esclave de réplication comme celui-ci. N'oubliez pas de définir explicitement l'ID du serveur dans le maître /etc/my.cnf et un numéro différent pour l'ID du serveur dans l'esclave /etc/my.cnf

34
RolandoMySQLDBA

Vous n'avez même pas besoin de mysqldump si vous déplacez un schéma de base de données entier, et vous êtes prêt à arrêter la première base de données (donc c'est cohérent lors du transfert)

  1. Arrêtez la base de données (ou verrouillez-la)
  2. Accédez au répertoire où se trouvent les fichiers de données mysql.
  3. Transférez le dossier (et son contenu) vers le répertoire de données mysql du nouveau serveur
  4. Démarrer la sauvegarde de la base de données
  5. Sur le nouveau serveur, exécutez une commande "créer une base de données". "
  6. Recréez les utilisateurs et accordez les autorisations.

Je ne me souviens pas si mysqldump gère les utilisateurs et les autorisations, ou seulement les données ... mais même si c'est le cas, c'est façon plus rapide que de faire un vidage et de l'exécuter. Je ne l'utiliserais que si j'avais besoin de vider une base de données mysql pour ensuite la réinsérer dans un autre SGBDR, si j'avais besoin de changer les options de stockage (innodb vs myisam), ou peut-être si je changeais les principales versions de mysql (mais Je pense que je l'ai fait entre 4 et 5, cependant)

29
Joe

Si vous souhaitez simplement déplacer une table spécifique, essayez:

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

Vous pouvez spécifier plus de noms de table ci-dessus, dans la même commande. Une fois la commande terminée, déplacez le fichier databasename.tablename.sql vers l'autre serveur, puis restaurez-le en utilisant:

mysql -u username -ppassword databasename < databasename.tablename.sql

Notez que le fichier .sql arrière est créé en utilisant le programme mysqldump, et la restauration se fait directement dans mysql.

12
StanleyJohns
  1. Si vous avez un accès ssh, vous pouvez utiliser mysqldump depuis la ligne de commande
  2. Si vous n'avez pas d'accès ssh mais que vous avez un accès phpMyAdmin, vous pouvez l'utiliser pour exporter/importer
  3. Si vous n'avez pas accès à phpMyAdmin, il existe des scripts php pratiques qui seront exportés et importés (cependant, d'après ma propre expérience, je n'en ai jamais trouvé un aussi fiable que phpMyAdmin).

Il peut y avoir cette possibilité où vous déplacez les fichiers de base de données réels (pour mon installation, ils sont situés dans/var/lib/mysql), mais je ne suis pas vraiment sûr de la façon dont il agira/fonctionnera.

7
poelinca

Vous allez devoir prendre un temps d'arrêt. Cela va prendre un certain temps en fonction de la vitesse de votre réseau. Je vais supposer que vous utilisez MySQL sous Linux/Unix. Voici le processus que j'utilise:

  1. Arrêtez le démon mysql sur l'hôte source.
  2. Créez un dossier tmp sur votre hôte cible pour recevoir les fichiers.
  3. Utilisez écran pour créer une session Shell qui survivra si votre ssh se déconnecte.
  4. Utilisez rsync pour transférer les fichiers entre les hôtes. Quelque chose comme: rsync -avhP source user @ targethost:/path/to/folder /
  5. Exécutez vos cas de test pour vous assurer que vous n'avez rien perdu dans le transfert.

Ensuite, procédez comme d'habitude pour configurer MySQL local.

* Remarque: vous pouvez également utiliser le paramètre -c avec rsync pour ajouter une somme de contrôle au transfert, mais cela sera lent en fonction de la vitesse du processeur.

5
randomx

Je pense que toutes les réponses précédentes fonctionnent probablement bien, mais ne résolvent pas vraiment le problème de la définition d'un nom de base de données pendant le transfert.

Voici comment je l'ai fait avec bash:

Il vaut mieux utiliser rsync que scp et ne pas compresser le fichier si vous le faites souvent.

Sur mon serveur source:

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

Sur mon serveur de destination:

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

Sur chaque machine pour voir la progression:

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

Tout cela suppose que vous avez configuration MySQL fichier dans votre répertoire personnel sur les deux machines et définissez les autorisations:

$ echo "
[client]
user=drupal6
password=metoknow
Host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf
4
ErichBSchulz

Je peux confirmer que la méthode de DTest fonctionne également pour la copie entre ubuntu et osx.

Pour copier toutes les bases de données sans avoir à effectuer de vidage ou similaire:

Assurez-vous que vous avez un mysql propre de mysql (installé le dmg téléchargé depuis mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), que (TRÈS IMPORTANT) n'a jamais été exécuté.

Copiez le contenu du dossier/var/lib/mysql/depuis la machine ubuntu au-dessus de/usr/local/mysql/data/contents sur le mac. Pour avoir accès au dossier get sur la machine Ubuntu, j'ai dû utiliser Sudo, c'est-à-dire:

Sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
Sudo chown -R foouser /home/foouser/mysql_data_folder

J'ai copié le dossier en utilisant scp.

Avant de commencer, prenez une copie du dossier mysql sur le mac pour vous assurer de ne rien gâcher.

Après avoir copié le dossier, procédez comme suit sur la machine mac:

Sudo chown -R _mysql /usr/local/mysql/data/
Sudo chgrp -R wheel /usr/local/mysql/data/
Sudo chmod -R g+rx /usr/local/mysql/data/

Démarrez le serveur mysql pour la première fois (à partir du volet des préférences sous Préférences Système-> mysql). Tous les utilisateurs et bases de données doivent maintenant être configurés correctement.

Cela a fonctionné avec mysql 5.1.61 sur ubuntu 64 bits 11.10 et mysql 5.1.63 sur osx lion (macbook pro).

4
paalvibe

le déplacez-vous vers une autre base de données du serveur mysql? si c'est le cas, faites une exportation dessus

# mysqldump -u username -ppassword database_name > FILE.sql
3
seyz4all

Méthode Linux générique:

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

éditez le datadir (et le socket) pour mysqld et mysqld_safe (le cas échéant) pour pointer vers le nouvel emplacement, puis

/etc/init.d/mysql start

J'ai posté cela parce que personne ne semblait simplement énumérer le moins d'étapes pour le faire et je pense que c'est le moyen le plus simple personnellement.

3
seeafish

Je suggérerais les deux étapes simples pour transférer la base de données entière d'un serveur à un autre.

Étape 1: Faites une sauvegarde complète des bases de données dans le serveur source en utilisant mysqldump.

Étape 2: Vous pouvez utiliser la commande rsync pour transférer l'intégralité des bases de données vers le serveur de destination.

2
Rudra

C'est peut-être une meilleure façon de procéder:

Version 1: copie des fichiers de données (MYISAM uniquement)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

ssh server2 service restart mysql

  • Si vos fichiers de base de données sont en lecture seule, vous pouvez ignorer l'arrêt du serveur.

Version 2: mysqldump

Installez pigz - sur les processeurs modernes Xeon ou Opteron, surtout lorsque vous avez 2 processeurs ou plus, c'est BEAUCOUP plus rapide que gzip.

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

Version: master/slave + mysqldump/file-copy

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

scénario:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

PS:

pour copier de petites tables, utilisez:

table de schéma mysqldump ssh server1 | schéma mysql de ssh server2

2
parf