Linux / MySQL: Ist es sicher, MySQL-Datenbankdateien mit dem Befehl cp von einer Datenbank in eine andere zu kopieren?

11

Die meisten Handbücher empfehlen mysqldump und einfaches SQL zum Kopieren einer Tabelle in eine andere Datenbank. Wie wäre es mit Linux Shell CP? Kann ich einfach machen

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

giorgio79
quelle

Antworten:

21

Das Kopieren ist für MyISAM sehr einfach und mit InnoDB zu 100% riskant (fast selbstmörderisch).

Von Ihrer Frage haben Sie angesprochen

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

MyISAM

Dies ist in Ordnung zu tun. Sie können die .frm jedoch nicht einfach verschieben. Sie müssen alle Komponenten verschieben. Nehmen wir aus Ihrer Frage eine Tabelle mit dem Namen db1.mytable. Bei einer normalen Installation befindet sich die Tabelle in / var / lib / mysql / db1. Die Tabelle besteht aus drei Dateien.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (Tabellendatenbank)
  • /var/lib/mysql/db1/mytable.MYI (Tabellenindizes)

Sie müssen alle drei Dateien verschieben, um die eine Tabelle zu verschieben. Wenn alle Ihre Tabellen die MyISAM-Speicher-Engine verwenden, können Sie MySQL herunterfahren und kopieren. Wenn Sie einfach eine Kopie der Tabelle erstellen und in einer anderen Datenbank ablegen, sollten Sie dies mit SQL tun.

Wenn Sie beispielsweise db1.mytable in die Datenbank db2 kopieren möchten, gehen Sie folgendermaßen vor:

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;

Wenn Sie nun nur die Tabelle von db1 nach db2 verschieben, können Sie Folgendes tun:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

Das Kopieren ist aufgrund der Infrastruktur, unter der InnoDB arbeitet, sehr gefährlich. Es gibt zwei grundlegende Infrastrukturen: 1) innodb_file_per_table deaktiviert und 2) innodb_file_per_table aktiviert

Die Achillesferse von InnoDB ist die als ibdata1 bekannte Systemtabellenbereichsdatei (normalerweise in / var / lib / mysql). Was ist in dieser Datei enthalten ?

  • Tabellendatenseiten
  • Tabellenindexseiten
  • Tabellen-MetaData (Tabellenbereichs-ID-Verwaltungsliste)
  • MVCC- Daten (zur Unterstützung der Transaktionsisolation und der ACID-Konformität )

InnoDB (innodb_file_per_table deaktiviert)

Wenn innodb_file_per_table deaktiviert ist, befinden sich alle diese Arten von InnoDB-Informationen in ibdata1. Die einzige Manifestation einer InnoDB-Tabelle außerhalb von ibdata1 ist die .frm-Datei der InnoDB-Tabelle. Das gleichzeitige Kopieren aller InnoDB-Daten erfordert das Kopieren von / var / lib / mysql.

Das Kopieren einer einzelnen InnoDB-Tabelle ist absolut unmöglich. Sie müssen mysqldump ausführen, um einen Speicherauszug der Tabelle als logische Darstellung der Daten und der entsprechenden Indexdefinitionen zu extrahieren. Sie würden diesen Speicherauszug dann in eine andere Datenbank auf demselben Server oder einem anderen Server laden.

InnoDB (innodb_file_per_table aktiviert)

Wenn innodb_file_per_table aktiviert ist, befinden sich Tabellendaten und ihre Indizes im Datenbankordner neben der .frm-Datei. Für die Tabelle db1.mytable lautet die Manifestation dieser InnoDB-Tabelle beispielsweise außerhalb von ibdata1:

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

Alle Metadaten für db1.mytable befinden sich immer noch in ibdata1, und daran führt absolut kein Weg vorbei . Redo-Protokolle und MVCC-Daten leben auch weiterhin mit ibdata1.

WARNUNG (oder GEFAHR, wie der Roboter in Lost in Space sagen würde )

Wenn Sie nur daran denken, die .frm- und .ibd-Datei zu kopieren, sind Sie in der Welt der Verletzungen. Das Kopieren der .frm- und .ibd-Datei einer InnoDB-Tabelle ist nur dann sinnvoll, wenn Sie sicherstellen können, dass die Tablespace-ID der .ibd-Datei genau mit dem Tablespace-ID-Eintrag in den Metdaten der ibdata1-Datei übereinstimmt.

Ich habe zwei Beiträge in DBA StackExchange über dieses Tablespace-ID-Konzept geschrieben

Hier finden Sie einen hervorragenden Link zum erneuten Anhängen einer .ibd-Datei an ibdata1 bei nicht übereinstimmenden Tablespace-IDs: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Nachdem Sie dies gelesen haben, sollten Sie in der Lage sein zu sehen, warum ich beinahe Selbstmord gesagt habe.

Für InnoDB brauchen Sie nur dazu

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

um eine Kopie einer InnoDB-Tabelle zu erstellen. Wenn Sie es auf einen anderen DB-Server migrieren, verwenden Sie mysqldump.

RolandoMySQLDBA
quelle
4
Andere Antworten sagten dies, also ist es vielleicht "selbstverständlich", aber es ist trotzdem gut zu sagen: InnoDB schreibt weiter in die Dateien, auch wenn die Datenbank inaktiv ist. Das Kopieren der Dateien während der Ausführung von MySQL führt also mit ziemlicher Sicherheit zu Beschädigungen! Sie können das System herunterfahren, einen Snapshot des Dateisystems erstellen oder Percona XtraBackup verwenden, um dies zu umgehen.
Baron Schwartz
1
Hervorragende Antwort wie immer, @Rolando! Die einzige große Frage, die ich habe: Warum sollte jemand dies tun wollen, anstatt einen direkten MySQL-Dump & Import durchzuführen? Ich gehe von einer reinen Datenbankgröße aus, bin aber der Meinung, dass dies angesprochen werden sollte.
JakeGould
1
@JakeGould Das Laden eines mysqldump-Skripts in mysql erfordert die Verarbeitung von viel SQL, das Einfügen von Tausenden von Zeilen gleichzeitig, das Verwenden von CPU-Zyklen, das Ausklappen von Erklärungsplänen, das Neuerstellen von Indizes (BTree Insertions, Leaf Node Splits, das Neuausgleichen von Schlüsseln, ein Tabellenscan für jedes Nicht -unique zu bauen) nur um die gleiche Tabelle zu produzieren. Warum bei MyISAM das Rad neu erfinden? Kopieren Sie einfach die .frm, .MYDund .MYI.
RolandoMySQLDBA
@JakeGould Im Fall von InnoDB hatte ich eine Live-Datenbank kopiert, die alle InnoDB mit rsync verwendete. Nach dem Kopieren mit rsync habe ich mysql heruntergefahren, eine endgültige rsync durchgeführt und mysql ohne Probleme neu gestartet. Ich schrieb einen Beitrag wie zuvor: serverfault.com/questions/288140/…
RolandoMySQLDBA
8

Das Kopieren des gesamten MySQL-Datenverzeichnisses ist eine praktische Technik, vorausgesetzt, der MySQL-Dienst wird gestoppt und Sie möchten, dass der gesamte Datenbankserver kopiert wird.

Dies ist eine nützliche Technik zum Verschieben von Datenbanken mit großen Indizes. Ein MySQL-Speicherauszug enthält keine Indizes, die beim Import neu generiert werden müssen. Ich fand diese Technik nützlich beim Einrichten von MySQL-Slaves.

Das Kopieren einer einzelnen Datei hängt vom verwendeten Tabellenschema ab, ist jedoch in den meisten Fällen keine geeignete Lösung.

Coops
quelle
2
Um dies zu erläutern: Sie müssen den Dienst nicht per se beenden. Wenn Ihr Dateisystem in der Lage ist, können Sie entweder einen LVM-Snapshot erstellen und einen Backup davon erstellen. oder frieren Sie das Dateisystem selbst ein.
Thinice
Solange ein Personal Ausfallzeiten haben kann, ist dies der einfachste Weg. +1 !!!
RolandoMySQLDBA
2

Verwenden Sie xtrabackup ohne owobackupex-Wrapper, und Sie werden sowohl in myisam- als auch in innodb-Datenbanken in Ordnung sein. Beachten Sie, dass beim Wiederherstellen von Innodb-Datenbanken die Dateien nicht nur zurückkopiert werden, selbst wenn Sie xtrabackup verwenden. Sagen Sie, wenn Sie weitere Informationen benötigen

Gabor Vincze
quelle
1

Nein, Sie sollten mit mysqdump sichern und mit dem Dienstprogramm mysql cli wiederherstellen. Kopieren Sie die frm-Datei, die Sie kopieren, nur die Tabellenstruktur und nicht die darin enthaltenen Daten. Wenn Sie sich in innodb befinden, ist das direkte Kopieren der Datei nicht möglich.

Der beste Weg ist, die Tabelle zu sichern und wiederherzustellen.

aleroot
quelle