Wie kann MySQL einen riesigen (32 GB) SQL-Dump schneller importieren?

67

Ich habe diesen riesigen 32 GB SQL-Speicherauszug, den ich in MySQL importieren muss. Ich musste noch nie einen so großen SQL-Dump importieren. Ich habe das übliche gemacht:

mysql -uroot dbname < dbname.sql

Es dauert zu lange. Es gibt eine Tabelle mit ungefähr 300 Millionen Zeilen, die in ungefähr 3 Stunden auf 1,5 Millionen angestiegen ist. Es scheint also, dass das Ganze 600 Stunden dauern würde (das sind 24 Tage) und unpraktisch ist. Meine Frage ist also, gibt es einen schnelleren Weg, dies zu tun?

Weitere Infos / Befunde

  1. Die Tabellen sind alle InnoDB und es sind keine Fremdschlüssel definiert. Es gibt jedoch viele Indizes.
  2. Ich habe keinen Zugriff auf den ursprünglichen Server und die ursprüngliche Datenbank, daher kann ich keine neue Sicherung erstellen oder eine "heiße" Kopie usw. erstellen.
  3. Die hierinnodb_flush_log_at_trx_commit = 2 vorgeschlagene Einstellung scheint keine (deutlich sichtbare / exponentielle) Verbesserung zu bewirken.
  4. Serverstatistiken während des Imports (von MySQL Workbench): https://imgflip.com/gif/ed0c8 .
  5. MySQL-Version ist 5.6.20 Community.
  6. innodb_buffer_pool_size = 16M und innodb_log_buffer_size = 8M. Muss ich diese erhöhen?
SBhojani
quelle
Können Sie dem Server schnellere Komponenten hinzufügen, nämlich mehr RAM- und SSD-Speicher?
@ Bert der Server hat 8 GB RAM, von denen der größte Teil nur ungenutzt ist. Es kann auch kein weiterer Speicher hinzugefügt werden. Wie würde das helfen? Sind wirklich die Schreibvorgänge so langsam?
Was ist der Engpass? Ist ein CPU-Kern gekoppelt?
Chris S
@ ChrisS Nein, die CPU-Auslastung beträgt 3 bis 4%. Ich bin mir nicht sicher, was der Engpass ist. Ich denke, es sind die Indizes. Wie würde man den Engpass finden / bestätigen?
1
Wenn Sie die SQL haben, können Sie die Anweisungen zum Erstellen eines Index herausschneiden und sehen, ob sie schneller sind? Sobald Sie die Daten importiert haben, müssen Sie sie neu erstellen

Antworten:

84

Perconas Vadim Tkachenko hat diese schöne bildliche Darstellung von InnoDB gemacht

InnoDB-Architektur

Sie müssen auf jeden Fall Folgendes ändern

innodb_buffer_pool_size = 4G
innodb_log_buffer_size = 256M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0

Warum diese Einstellungen?

Starten Sie mysql so neu

service mysql restart --innodb-doublewrite=0

Dies deaktiviert den InnoDB Double Write Buffer

Importieren Sie Ihre Daten. Wenn Sie fertig sind, starten Sie mysql normal neu

service mysql restart

Dadurch wird der InnoDB Double Write Buffer wieder aktiviert

Versuche es !!!

SEITLICHER HINWEIS : Sie sollten ein Upgrade auf 5.6.21 durchführen, um die neuesten Sicherheitspatches zu erhalten .

RolandoMySQLDBA
quelle
1
Ich habe ein Skript Linux - Bash für sie, senkte einige Werte innerhalb Vagabund mit niedrigeren Speicher arbeiten gist.github.com/OZZlE/57d550c3cc1c1ff17481e465e4f6d674
OZZIE
9

Müssen Sie wirklich die gesamte Datenbank wiederherstellen? Wenn nicht, mein 2c:

Sie können bestimmte Tabellen extrahieren, um die Wiederherstellung für "Chunks" durchzuführen. Etwas wie das:

zcat your-dump.gz.sql | sed -n -e '/DROP TABLE.*`TABLE_NAME`/,/UNLOCK TABLES/p' > table_name-dump.sql

Ich habe es einmal gemacht und es dauerte ungefähr 10 Minuten, um die benötigte Tabelle zu extrahieren - meine vollständige Wiederherstellung dauerte 13 bis 14 Stunden, mit einem 35-GB-Speicherauszug (gziped).

Die /pattern/,/pattern/pmit dem -nParameter macht eine Scheibe „zwischen den Mustern“ - auch sie.

Wie auch immer, um die 35 GB wiederherzustellen, habe ich eine AWS EC2-Maschine (c3.8xlarge) verwendet, Percona über yum (Centos) installiert und gerade die folgenden Zeilen hinzugefügt / geändert my.cnf:

max_allowed_packet=256M
wait_timeout=30000

Ich denke, die Zahlen sind viel zu hoch, aber für mein Setup funktioniert.

Bruno J. Araujo
quelle
5

Der schnellste Weg, Ihre Datenbank zu importieren, besteht darin, die Dateien (.frm, .MYD, .MYI) unter MyISAM direkt in das Verzeichnis / var / lib / mysql / "database name" zu kopieren.

Ansonsten können Sie versuchen: mysql > use database_name; \. /path/to/file.sql

Das ist eine andere Möglichkeit, Ihre Daten zu importieren.

Alex
quelle
1

Eine Möglichkeit, den Import zu beschleunigen, besteht darin, die Tabelle beim Import zu sperren. Verwenden Sie die Option --add-locks für mysqldump.

mysqldump --add-drop-table --add-locks --database db > db.sql

Oder Sie können einige nützliche Parameter mit --opt aktivieren. Dies aktiviert eine Reihe nützlicher Dinge für den Dump.

mysqldump --opt --database db > db.sql

Wenn Sie ein anderes Speichergerät auf dem Server haben, verwenden Sie dieses. Durch Kopieren von einem Gerät auf ein anderes können Sie die Übertragung beschleunigen.

Sie können mit --ignore-table auch Tabellen herausfiltern, die nicht benötigt werden

pgee70
quelle