MySQL: Führen Sie eine Big-Data-Migration zwischen Tabellen durch

7

Ich möchte Daten zwischen 2 InnoDB-Tabellen migrieren.

Derzeit führe ich diese Abfrage aus:

INSERT INTO table_a SELECT * FROM table_b;

Was ist der beste Weg, um eine CPU-Überlastung zu vermeiden, wenn der Datensatz wächst?

Vielen Dank

Mich Dart
quelle
3
CPU wird nicht Ihr Problem sein, Disk I / O wird.
Ich denke, Sie kürzen die Tabelle, in die Sie die ganze Zeit migrieren? Dann sollten Sie in Betracht ziehen, nur den Unterschied zur letzten Migration zu migrieren (auch bekannt als Speichern des Zeitstempels bei der letzten Migration und Übertragen von Zeilen mit einem größeren Zeitstempel)
Möglicherweise möchten Sie Indizes vorübergehend löschen, bevor Sie sie verschieben, und sie nach der erfolgreichen Migration neu erstellen.
Biziclop
Ja, vor der Ausführung der Abfrage deaktiviere ich Indizes. Trotzdem bemerke ich eine Überlastung der Festplatte / CPU.
1
Welche Speicher-Engine verwenden Sie? Innodb oder Myisam? Gleich für beide Tische?
Atxdba

Antworten:

2

Da Sie InnoDB verwenden, möchte ich Folgendes vorschlagen:

VORSCHLAG # 1

Wenn Sie INSERT, UPDATEs und DELETEs ausführen, laden Sie die Tabelle wie folgt in großen Mengen:

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT * FROM table_b;
ALTER TABLE table_a RENAME table_old;
ALTER TABLE table_new RENAME table_a;
DROP TABLE table_old;

Wenn Sie nur INSERTs und SELECTs ausführen, laden Sie neue Einträge in die Tabelle. Unter der Annahme , den Primärschlüssel table_aund table_bwird id, führen die Last wie folgt aus :

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT B.* FROM table_b B
LEFT JOIN table_a A USING (id) WHERE A.id IS NULL;
INSERT INTO table_a SELECT * FROM table_new;
DROP TABLE table_new;

VORSCHLAG 2: InnoDB für mehrere CPUs optimieren

Stellen Sie sicher, dass Sie MySQL 5.5 verwenden. Wenn Sie MySQL 5.1.38 oder höher haben, müssen Sie das InnoDB-Plugin installieren . Wenn Sie MySQl 5.1.37 oder früher haben, aktualisieren Sie einfach auf MySQL.

Sobald Sie dies getan haben (oder wenn Sie bereits MySQL 5.5 haben), müssen Sie InnoDB für mehrere CPUs optimieren. Anstatt das Rad neu zu erfinden, sind hier meine letzten Beiträge darüber, wie und warum dies zu tun ist:

Versuche es !!!

Ich könnte andere Dinge wie Puffer, Protokolldateien usw. vorschlagen. Ich habe nur diese beiden Bedenken angesprochen.

RolandoMySQLDBA
quelle
Lassen Sie mich Ihren ersten Vorschlag verstehen. Sie verwenden eine temporäre Tabelle (table_new), in der Daten gespeichert werden. Am Ende führen Sie eine SQL-Abfrage durch, die meiner ziemlich ähnlich ist ... Ist Ihre effizienter? Habe ich Probleme mit der Festplatten-E / A?
Mich Dart
Was ist mit den Daten, die in A eingefügt werden, bevor A nach B kopiert wird? Wird B nicht unvollständig sein?
KeatsKelleher
1

In diesem Fall ist normalerweise die beste Lösung ein mysqldump mit der folgenden --tabOption:

mysqldum --tab=/path/to/serverlocaldir --single-transaction <database> table_a

Die Tab-Option erzeugt 2 Dateien, eine Datei -table_a.sql-, die nur die Anweisung create table enthält, und die andere Datei -table_a.txt- enthält tabulatorgetrennte Daten.

Jetzt können Sie Ihre neue Tabelle erstellen

create table table_b like table_a;

Dann laden Sie einfach Daten in Ihre neue Tabelle über, LOAD DATAohne auf den Namen der Tabelle zu achten.

LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt' 
  INTO TABLE table_b FIELDS TERMINATED BY '\t' ...

LOAD DATA ist normalerweise 20-mal schneller als die Verwendung von INSERT-Anweisungen.

Hoffe das hilft

Cristian Porta
quelle
Dies ist eine gute Lösung, erfordert jedoch einen manuellen Eingriff oder einen Shell-basierten Befehl. Ich werde es als gültige Option nehmen. Vielen Dank
Mich Dart