Der MySQL-Server konnte den Import großer Dumps nicht mehr behindern


14

Ich versuche, einen großen SQL-Speicherauszug (2 GB) in mein lokales MySQL auf meinem Mac zu importieren. Ich konnte dies in der Vergangenheit tun (ich habe MAMP verwendet), aber jetzt erhalte ich einen FEHLER 2006 (HY000) in Zeile 7758: Der MySQL-Server ist jedes Mal weg, wenn ich versuche, den Dump zu importieren. Die Datenbank enthält Innodb-Tabellen.

Ich habe versucht, die Datei my-innodb-heavy-4G.cnf in my.cnf zu kopieren, um zu sehen, ob diese Einstellungen helfen würden, aber kein Glück.

Irgendwelche Ideen, was zu optimieren ist?

Ich verwende das "Mac OS X Version 10.6 (x86, 64-Bit), DMG-Archiv" von hier: http://dev.mysql.com/downloads/mysql/

Antworten:


15

Einer der stillen Killer von MySQL Connections ist das MySQL-Paket. Sogar der I / O-Thread von MySQL Replication kann davon betroffen sein.

Nach der MySQL-Dokumentation

  • Sie können diese Fehler auch erhalten, wenn Sie eine falsche oder zu große Abfrage an den Server senden. Wenn mysqld ein zu großes oder nicht ordnungsgemäßes Paket empfängt, wird davon ausgegangen, dass beim Client ein Fehler aufgetreten ist, und die Verbindung wird geschlossen. Wenn Sie große Abfragen benötigen (z. B. wenn Sie mit großen BLOB-Spalten arbeiten), können Sie das Abfragelimit erhöhen, indem Sie die Variable max_allowed_packet des Servers mit einem Standardwert von 1 MB festlegen. Möglicherweise müssen Sie auch die maximale Paketgröße auf der Client-Seite erhöhen. Weitere Informationen zum Einstellen der Paketgröße finden Sie in Abschnitt C.5.2.10, „Paket zu groß“.

  • Eine INSERT- oder REPLACE-Anweisung, die sehr viele Zeilen einfügt, kann ebenfalls diese Art von Fehlern verursachen. Eine dieser Anweisungen sendet unabhängig von der Anzahl der einzufügenden Zeilen eine einzelne Anforderung an den Server. Daher können Sie den Fehler häufig vermeiden, indem Sie die Anzahl der pro INSERT oder REPLACE gesendeten Zeilen verringern.

Zumindest müssen Sie sicherstellen, dass die Paketgrößen sowohl für den Computer, von dem Sie mysqldump erstellt haben, als auch für den Computer, den Sie laden, identisch sind.

Es kann zwei (2) Ansätze geben:

ANSATZ 1: Führen Sie den mysqldump mit --skip-extended-insert aus

Dadurch wird sichergestellt, dass das MySQL-Paket nicht mit mehreren BLOBs und TEXT-Feldern überschwemmt wird. Auf diese Weise werden SQL INSERTs einzeln ausgeführt. Die Hauptnachteile sind

  1. der mysqldump ist viel größer
  2. Das Neuladen eines solchen Dumps dauert viel länger.

ANSATZ 2: Erhöhen Sie max_allowed_packet

Dies kann der bevorzugte Ansatz sein, da die Implementierung nur einen Neustart von MySQL entfernt ist. Das Verstehen, was das MySQL-Paket ist, kann dies verdeutlichen.

In den folgenden Abschnitten wird dies auf Seite 99 von "Grundlegendes zu MySQL-Interna" (ISBN 0-596-00957-7) erläutert:

Der MySQL-Netzwerkkommunikationscode wurde unter der Annahme geschrieben, dass Abfragen immer relativ kurz sind und daher in einem Block, der in der MySQL-Terminologie als Paket bezeichnet wird, an den Server gesendet und von diesem verarbeitet werden können . Der Server weist den Speicher für einen temporären Puffer zum Speichern des Pakets zu und fordert genug an, um es vollständig zu passen. Diese Architektur erfordert eine Vorsichtsmaßnahme, um zu vermeiden, dass dem Server der Speicher ausgeht - eine Obergrenze für die Größe des Pakets, die mit dieser Option erreicht wird.

Der Code von Interesse in Bezug auf diese Option befindet sich in sql / net_serv.cc . Schauen Sie sich my_net_read () an , folgen Sie dann dem Aufruf von my_real_read () und achten Sie besonders auf net_realloc () .

Diese Variable begrenzt auch die Länge eines Ergebnisses vieler Zeichenkettenfunktionen. Weitere Informationen finden Sie in sql / field.cc und sql / intem_strfunc.cc .

Angesichts dieser Erklärung wird ein MySQL-Paket durch Bulk-INSERTs ziemlich schnell geladen / entladen. Dies gilt insbesondere dann, wenn max_allowed_packet für die angegebene Datenmenge zu klein ist.

FAZIT

Bei den meisten Installationen von MySQL stelle ich normalerweise 256M oder 512M ein. Sie sollten mit größeren Werten experimentieren, wenn beim Laden von Daten "MySQL ist weg" -Fehler auftreten.


Ich habe versucht, mich max_allowed_packetauf 900M einzustellen, und ich habe verwendet --skip-extended-insert(und Sie haben Recht - das sorgt für riesige Db-Dumps), aber es schlägt immer noch fehl. Ich vermute jetzt eine bestimmte Zeile im Dump, die ich wahrscheinlich umgehen kann. Aber es ist immer noch seltsam - der Dump kann problemlos auf meinen CentOS-Server importiert werden.
Naxoc

Am Ende habe ich ein Insert aus dem SQL-Dump entfernt, das eine sehr, sehr lange Zeile war. Das hat es behoben (und die Leitung wurde nicht benötigt).
Naxoc

Übrigens: Stellen Sie sicher, dass das Standardzeichen für den Daten-Dump unter MacOSX Operating System und unter MySQL unterstützt wird.
RolandoMySQLDBA

@naxov - Ich bin nur neugierig auf die eine Zeile, die Sie in der Müllkippe vermuten. Sind TEXT- oder BLOB-Felder betroffen?
RolandoMySQLDBA

Ja, ein sehr langes Textfeld.
Naxoc

2

Wie lange dauert es, bis eine Zeitüberschreitung eintritt? Der erste Schritt wäre, die wait_timeoutund interactive_timeout-Einstellungen zu überprüfen , um sicherzustellen, dass sie groß genug für Ihren Import sind:

SHOW VARIABLES LIKE '%_timeout';
SET SESSION wait_timeout=28800;

Die Standardeinstellung ist 8 Stunden (28800), daher ist dies möglicherweise nicht das Problem. Weitere Hinweise zu diesem Problem finden Sie hier . Eines, das auffällt, ist folgendes:

Eine Client-Anwendung, die auf einem anderen Host ausgeführt wird, verfügt nicht über die erforderlichen Berechtigungen, um von diesem Host aus eine Verbindung zum MySQL-Server herzustellen.

Überprüfen Sie zuerst die Berechtigungen, gehen Sie dann die Liste der potenziellen Probleme durch.


Es ist alles auf localhost, also verstehe ich entweder nicht, was du meinst, oder es ist nicht das Problem. Meinten Sie Berechtigungen wie in Privilegien in MySQL?
Naxoc

2

Ja, wenn ich normalerweise mit wait_timeout und max_allowed_packets spiele, kann ich die Fehlermeldung auch umgehen.


Das hat bei mir nicht funktioniert. Ich musste den SQL-Code in der Dump-Datei bearbeiten und eine sehr lange Zeile entfernen, die das Problem verursachte.
Naxoc

man sollte nicht mit einigen Parametern spielen, die er nicht versteht
Jeredepp

2

Es ist vielleicht nicht das "richtige", aber es könnte funktionieren (fertig, oder?):

Versuchen Sie, Ihren großen Speicherauszug in mehrere Dateien zu unterteilen und nacheinander auszuführen. Mein Ansatz wäre es, es in zwei Hälften zu teilen und zu testen. Brechen Sie dann jede Hälfte in zwei Hälften, wiederholen Sie den Test und so weiter.

Ich bin etwas neugierig, ob die Menge an RAM, die Sie auf Ihrer Box haben, etwas damit zu tun haben könnte. Lädt MySQL den gesamten Speicherauszug in den Speicher, wenn es ausgeführt wird? Ich weiß nicht ... aber wenn Sie nur 2 GB RAM haben und ein Teil davon für Ihr Betriebssystem und andere Apps verwendet wird, könnte dies das Problem sein.


2

Diejenigen, die nicht Erfolg mit den anderen Vorschlägen hatte vielleicht sollten Sie einen Blick auf die BigDump PHP unter gestaffelte MySQL - Dump Importeur Skript .

Es ist eine Problemumgehung für den Import großer Datenbank-Dumps in MySQL. Ich habe es erfolgreich verwendet, um einen großen MySQL-Speicherauszug in meine lokale Entwicklungsumgebung zu importieren (in diesem Fall verwende ich MAMP).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.