Linux / mysql: est-il sûr de copier des fichiers db mysql avec la commande cp d'une base de données à une autre?


11

La plupart des guides recommandent mysqldump et SQL simple pour copier une table vers un autre db. Que diriez-vous du shell Linux cp? Puis-je simplement faire

cp /db1/mytable.frm /db2/mytable.frm

Réponses:


21

La copie est très simple pour MyISAM et complètement 100% risquée (quasi suicidaire) avec InnoDB.

De votre question, vous avez évoqué

cp /db1/mytable.frm /db2/mytable.frm

MyISAM

C'est OK à faire. Cependant, vous ne pouvez pas simplement déplacer le .frm. Vous devez déplacer tous les composants. De votre question, prenons une table appelée db1.mytable. Dans une installation normale, la table se trouve dans / var / lib / mysql / db1. Il y aurait trois fichiers constituant la table.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (base de données de table)
  • /var/lib/mysql/db1/mytable.MYI (Index de table)

Vous devez déplacer les trois fichiers pour déplacer une table. Si toutes vos tables utilisent le moteur de stockage MyISAM, vous pouvez arrêter mysql et copier. Si vous faites simplement une copie de la table et la placez dans une autre base de données, vous devez le faire en utilisant SQL.

Par exemple, si vous souhaitez copier db1.mytable dans la base de données db2, procédez comme suit:

CREATE TABLE db2.mytable LIKE db1.mytable;
ALTER TABLE db2.mytable DISABLE KEYS;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
ALTER TABLE db2.mytable ENABLE KEYS;

Maintenant, si vous déplacez simplement la table de db1 à db2, vous pouvez le faire:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

La copie est très dangereuse en raison de l'infrastructure sous laquelle InnoDB fonctionne. Il existe deux infrastructures de base: 1) innodb_file_per_table désactivé et 2) innodb_file_per_table activé

Le talon d'Achille d'InnoDB est le fichier d'espace de table système appelé ibdata1 (normalement situé dans / var / lib / mysql). Que contient ce fichier ?

  • Pages de données de table
  • Pages d'index de table
  • Table MetaData (liste de gestion des identifiants d'espace disque logique)
  • Données MVCC (pour prendre en charge l'isolement des transactions et la conformité ACID )

InnoDB (innodb_file_per_table désactivé)

Avec innodb_file_per_table désactivé, tous ces types d'informations InnoDB vivent dans ibdata1. La seule manifestation d'une table InnoDB en dehors d'ibdata1 est le fichier .frm de la table InnoDB. La copie de toutes les données InnoDB à la fois nécessite la copie de tout / var / lib / mysql.

La copie d'une table InnoDB individuelle est totalement impossible. Vous devez mysqldump pour extraire un vidage de la table en tant que représentation logique des données et de ses définitions d'index correspondantes. Vous devez ensuite charger ce vidage dans une autre base de données sur le même serveur ou un autre serveur.

InnoDB (innodb_file_per_table activé)

Lorsque innodb_file_per_table est activé, les données de table et ses index vivent dans le dossier de base de données à côté du fichier .frm. Par exemple, pour la table db1.mytable, la manifestation de cette table InnoDB en dehors d'ibdata1 serait:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

Toutes les métadonnées de db1.mytable résident toujours dans ibdata1 et il n'y a absolument aucun moyen de contourner cela . Les journaux de rétablissement et les données MVCC vivent également avec ibdata1.

AVERTISSEMENT (ou DANGER comme dirait le robot dans Lost in Space )

Si vous songez à copier simplement le fichier .frm et .ibd, vous êtes en ligne pour le monde de mal. La copie des fichiers .frm et .ibd d'une table InnoDB n'est bonne que si vous pouvez garantir que l'ID d'espace disque logique du fichier .ibd correspond exactement à l'entrée d'ID d'espace disque logique dans les métdonnées du fichier ibdata1.

J'ai écrit deux articles dans DBA StackExchange sur ce concept d'ID d'espace de table

Voici un excellent lien sur la façon de rattacher et de fichier .ibd à ibdata1 en cas d'ID d'espace table incompatibles: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Après avoir lu ceci, vous devriez pouvoir voir pourquoi j'ai dit presque suicidaire.

Pour InnoDB, il vous suffit de

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

pour faire une copie d'une table InnoDB. Si vous le migrez vers un autre serveur DB, utilisez mysqldump.


4
D'autres réponses ont dit cela, alors peut-être que cela "va sans dire", mais il est bon de dire quand même: InnoDB continue d'écrire dans les fichiers même si la base de données est inactive, donc copier ses fichiers pendant que MySQL est en cours d'exécution est presque certain de provoquer la corruption! Vous pouvez arrêter, prendre un instantané du système de fichiers ou utiliser Percona XtraBackup pour contourner ce problème.
Baron Schwartz

1
Excellente réponse comme toujours, @Rolando! La seule grande question que j'ai: pourquoi quelqu'un voudrait-il faire cela plutôt que de faire un dump & import direct de MySQL? Je suppose la taille de la base de données, mais je pense que cela devrait être soulevé.
JakeGould

1
@JakeGould Le chargement d'un script mysqldump dans mysql nécessite de traiter beaucoup de SQL, d'insérer des milliers de lignes à la fois, d'utiliser des cycles de CPU, de lancer des plans d'explication, de reconstruire des index (BTree Insertions, Leaf Node Splits, rééquilibrer les clés, une analyse de table pour chaque non -unique à construire) juste pour produire la même table. Dans le cas de MyISAM, pourquoi réinventer la roue? Juste une copie du .frm, .MYDet .MYI.
RolandoMySQLDBA

@JakeGould Dans le cas d'InnoDB, j'avais copié une base de données en direct qui utilisait tous les InnoDB avec rsync. Après avoir copié à l'aide de rsync, j'ai exécuté un arrêt de mysql, effectué une rsync finale et redémarré mysql sans problème. J'ai écrit un article comme avant: serverfault.com/questions/288140/…
RolandoMySQLDBA

8

La copie de l'intégralité du datadir MySQL est une technique pratique, en supposant que le service MySQL est arrêté et que vous souhaitez copier l'intégralité du serveur de base de données.

Il s'agit d'une technique utile pour déplacer des bases de données avec de gros index, et un vidage mysql n'inclura pas les index, qui devront être régénérés au moment de l'importation. J'ai trouvé cette technique utile lors de la configuration des esclaves MySQL.

La copie d'un fichier individuel dépend du schéma de table utilisé, mais dans la plupart des cas, ce n'est pas une solution appropriée.


2
Pour exposer: vous n'avez pas à arrêter le service en soi, si votre système de fichiers est capable, vous pouvez soit effectuer un instantané LVM et en sauvegarder; ou geler le système de fichiers lui-même.
Thinice

Tant qu'un individu peut manger des temps d'arrêt, c'est le moyen le plus simple. +1 !!!
RolandoMySQLDBA

2

Utilisez xtrabackup w / ow w / o innobackupex wrapper et tout ira bien sur les bases de données myisam et innodb. Notez que la restauration des bases de données innodb ne consiste pas seulement à recopier les fichiers même si vous utilisez xtrabackup. Dites si vous avez besoin de plus d'informations


1

Non, vous devez sauvegarder avec mysqdump et restaurer avec l'utilitaire mysql cli, en copiant le fichier frm, vous copiez uniquement la structure de la table et non les données à l'intérieur, et si vous êtes sur innodb, copier le fichier directement n'est pas possible.

La meilleure façon est de vider et de restaurer la table.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.