Kopieren Sie von einer MySQL-Tabelle in eine andere MySQL-Tabelle derselben Datenbank

14

Ich habe ungefähr 40 Millionen Zeilen in einer MySQL-Tabelle und möchte diese Tabelle in eine andere Tabelle in derselben Datenbank kopieren. Was ist der effizienteste Weg, dies zu tun? Wie lange wird es dauern (ungefähr)?

Devashish Dixit
quelle
Was ist der Motor Ihres Tisches?
Abdul Manaf
InnoDB Engine ..
Devashish Dixit

Antworten:

22

Angenommen, Sie haben mydb.mytbund möchten erstellenmydb.mytbcopy

Ich habe fünf (5) Ansätze, um diese Kopie zu machen

Ansatz # 1

Im mysqlClient den folgenden

USE mydb
CREATE TABLE mytbcopy LIKE mytb;
INSERT INTO mytbcopy SELECT * FROM mytb;

Ansatz # 2

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb | mysql ${MYSQL_CONN} -Dtest
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

Ansatz # 3

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dtest < ${DUMPFILE}
rm -f ${DUMPFILE}
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

ANSATZ 4

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

ANSATZ 5

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dmydb < ${DUMPFILE}
rm -f ${DUMPFILE}

ANALYSE

  • ANSATZ 1 ist in Bezug auf die Schritte am einfachsten, erfordert jedoch das Pushen von 40 Millionen Zeilen in einer Transaktion. Dies ist die höchste Belastung für die InnoDB Storage Engine.
  • Bei den anderen Ansätzen sendet mysqldump 40 Millionen Zeilen in Spannfuttern mit Tausenden von Zeilen
    • Mit ANSATZ 2 und ANSATZ 3 wird die Tabelle in die Testdatenbank kopiert . Nach dem Erstellen der Tabelle in der Testdatenbank wird diese anschließend umbenannt und in die ursprüngliche Datenbank verschoben
    • APPROACH # 4 und APPROACH # 5 benennen die Tabelle mit sed gegen den Stream um, der vom mysqldump kommt, während die INSERT-Befehle wiedergegeben werden
    • ANSATZ 2 und ANSATZ 4 verwenden Pipes anstelle einer Ausgabedatei
    • ANSATZ 3 und ANSATZ 5 verwenden eine Outpuit-Datei für das anschließende Neuladen

Wenn Sie mydb.mytbin eine bereits vorhandene Tabelle kopieren möchten mydb.mytbcopyund die beiden Tabellen identische Strukturen haben:

Ansatz # 6

INSERT INTO mytbcopy SELECT * FROM mytb;

Wie #APPROACH 1 , #APPROACH 6 würde eine einzelne Transaktion von 40 Millionen Zeilen

ANSATZ 7

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} -t mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

Dieser Ansatz lässt die Tabelle nicht fallen. Es werden einfach die INSERTs generiert

EPILOG

Ich kann Ihnen keine Zeitschätzung geben, da ich den Aufbau des DB-Servers, die Tabellenstruktur, das Indexlayout und ähnliches nicht kenne.

VERSUCHE ES !!!

RolandoMySQLDBA
quelle
0

InnoDB-Tabellen können im Gegensatz zu MyISAM * nicht "einfach wegkopiert" werden, da sich ein Teil des Datenwörterbuchs (und möglicherweise anderer Strukturen, von denen die Tabelle abhängig ist, wie der Zusammenführungspuffer) im Arbeitsspeicher (wenn der Server ausgeführt wird) und in befindet Der Common / Main-Tablespace, auch bekannt als die große Datei, die aufgerufen wird ibdata1.

Wenn Sie Percona Server> = 5.1 oder MySQL> = 5.6 verwenden, werden transportierbare Tablespaces unterstützt, mit denen Sie Tabellen direkt aus dem Dateisystem exportieren und importieren können. Hier ist es die Methode für MySQL und für Percona . In beiden Fällen ist es erforderlich, dass Sie die Tabelle mit der innodb_file_per_tableOption erstellt haben und die Verwendung von DISCARD TABLESPACE/IMPORT TABLESPACEund / oder Percona Xtrabakup verwenden (wenn der Export online erfolgen soll). Bitte beachten Sie, dass Percona Server oder Xtrabakup nicht für Windows verfügbar sind.

Diese Methode ist im Allgemeinen so schnell wie das Kopieren der Datei mit den Dateisystembefehlen (cp, rsync).

Es kann zwar vorkommen, dass dies in MySQL <5.6 (auf eine hackige Art und Weise) für Wiederherstellungen funktioniert, bei einer Tabellenkopie funktioniert es jedoch nicht. In diesen Fällen können Sie SQL verwenden :

CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table SELECT * FROM old_table;

Dies ist so schnell, wie InnoDB ausgeführt werden kann, Handler_read_rnd_nextund zwar Handler_writeeinmal pro Zeile. Wenn Sie diese Methode verwenden, stellen Sie sicher, dass Sie die Haltbarkeitsoptionen zumindest vorübergehend deaktivieren und über einen großen Pufferpool und ein Transaktionsprotokoll verfügen. Unter diesen Umständen kann es die Importzeit verkürzen, aber es passt definitiv nicht vollständig in den Speicher. Erwarten Sie also viel Zeit. Außerdem versuchen Sie, 40 Millionen Zeilen in eine einzelne Transaktion zu importieren, was zu Problemen führen kann.

Meine eigentliche Empfehlung in diesem zweiten Fall wäre, so etwas wie pt-archiver zu verwenden , da es eine Operation ausführt, die der gerade erwähnten ähnelt, aber in "Stücken" ausgeführt wird, wobei der Transaktionsaufwand vermieden wird (es könnte sein) nicht schneller sein, aber im Falle eines Fehlers wird nicht versucht, den gesamten Tisch rückgängig zu machen (ewig dauernd). Für die von Ihnen genannten Datengrößen ist dies wahrscheinlich der beste Weg.

Eine letzte Option wäre das Exportieren und Importieren im CSV- (oder TSV-) Format mit einer Kombination aus SELECT INTO OUTFILE / mysqldump und LOAD DATA / mysqlimport. Dies war eine sehr häufige Option, wenn Sie in bestimmten alten Versionen von mysql eine Parallelität benötigen, da mit sql größere Sperren erstellt wurden (nicht mehr wahr, wenn dies korrekt durchgeführt wurde). Da mysqldump / import nur serialisiert funktioniert, würde ich Ihnen empfehlen, nach Optionen zu suchen, um es zu parallelisieren. Dies ist sehr nützlich für große Tabellen.

Vermeiden Sie auf jeden Fall mehrere SQL-Sätze, da dies Ihr wichtigster Engpass ist, wenn Sie viele verschiedene Abfragen ausführen (die einzeln ausgeführt, analysiert und optimiert werden müssen).


* MyISAM-Strukturen können nicht im laufenden Betrieb kopiert werden, es ist jedoch sehr einfach, sie vorübergehend auf die Festplatte zu synchronisieren FTWRL.

jynus
quelle
0

Verschieben von Daten von einer Tabelle in eine andere im Schema

create table your_table_name select * from old_schema_table;

Shahzad Hussain
quelle