Layer 8Ehrlicher Tech-Support
SoftwareSchweregrad: LästigER_NET_PACKET_TOO_LARGE

MySQL: Paket zu groß, Verbindung weg

Ein Einspielvorgang bricht ab, weil das Paket größer ist als erlaubt? MySQL kappt die Verbindung — Client und Server brauchen beide mehr Luft.

Aufwand:
ca. 20 Min.
Voraussetzung:
Zugriff auf die Serverkonfiguration, Kommandozeilen-Client, Neustartrecht für den Datenbankdienst
Gilt für:
MySQL 8.0

Das Symptom

Ein Datenbankabzug läuft beim Einspielen minutenlang brav durch und bricht dann mitten in einer Tabelle ab. Oder eine Anwendung speichert ein Bild, ein PDF, einen langen Textblock — und genau an dieser Stelle ist die Verbindung plötzlich fort. Mal steht in der Meldung, das Paket sei zu groß, mal nur, die Verbindung sei während der Abfrage verloren gegangen. Ein zweiter Versuch scheitert an derselben Zeile. Der Server läuft dabei völlig unbeeindruckt weiter.

Die „Layer 8“-Wahrheit

MySQL redet nicht in Zeilen, sondern in Paketen. Jede Anweisung und jede Antwort geht als ein solches Paket über die Leitung, und für dessen Größe gibt es eine harte Obergrenze. Wird sie überschritten, diskutiert der Server nicht: Er meldet den Fehler und legt auf. Genau deshalb sieht der Abbruch nach einem Netzwerkproblem aus, obwohl kein einziges Kabel schuld ist — der Verbindungsabbruch ist die Reaktion, nicht die Ursache.

Der Denkfehler steckt fast immer in der Annahme, es gebe nur eine Stellschraube. Es sind zwei: Client und Server führen dieses Limit getrennt, und wer nur den Server hochsetzt, wundert sich, dass der Kommandozeilen-Client mit seinen werkseitigen 16 MB weiterhin die Reißleine zieht. Der Server bringt in MySQL 8.0 ab Werk 64 MB mit, der Client also deutlich weniger — eine Asymmetrie, die genau dann auffällt, wenn man sie am wenigsten gebrauchen kann.

Den Wert anzuheben ist erlaubt und billig; der zusätzliche Speicher wird nur belegt, wenn er wirklich gebraucht wird. Trotzdem ist das Limit kein Schikanewerk, sondern eine Bremse gegen fehlerhafte Pakete und gegen Anwendungen, die versehentlich den Arbeitsspeicher leerräumen. Und über 1 GB kommt in MySQL 8.0 ohnehin nichts hinaus. Wer diese Grenze regelmäßig streift, hat kein Konfigurationsproblem, sondern legt Dateien in einer Datenbank ab — dem teuersten Dateisystem der Welt.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Den geltenden Wert am Server ablesen

    Zuerst nachsehen, wovon überhaupt die Rede ist. Der Wert des Servers ist laut MySQL-8.0-Handbuch standardmäßig 64 MB — wenn dort etwas deutlich Kleineres steht, hat jemand ihn gesetzt, oft vor Jahren in einer alten Konfigurationsdatei:

    SHOW VARIABLES LIKE 'max_allowed_packet';
    
  2. 2.

    Den Client nicht vergessen

    Client und Server haben jeweils ein eigenes Limit, und das Handbuch verlangt ausdrücklich, für große Pakete beide anzuheben. Der Kommandozeilen-Client mysql bringt von Haus aus 16 MB mit — also weniger als der Server. Beim Einspielen eines Abzugs den Wert direkt mitgeben:

    mysql --max_allowed_packet=256M -u benutzer -p meinedb < abzug.sql
    
  3. 3.

    Den Wert am Server dauerhaft setzen

    Für den Dauerbetrieb gehört der Wert in die Optionsdatei des Servers, nicht in ein Startskript. Der Abschnitt für den Serverprozess ist [mysqld]; die Schreibweise mit M für Megabyte ist die im Handbuch gezeigte:

    [mysqld]
    max_allowed_packet=128M
    
  4. 4.

    Dienst neu starten und den Server gegenprüfen

    Ohne Neustart des Dienstes bleibt die Optionsdatei ein frommer Wunsch. Unter Debian und Ubuntu heißt die Einheit mysql, bei MariaDB oder in RHEL-Paketen mariadb beziehungsweise mysqld — den passenden Namen einsetzen. Danach prüfen, ob der Server wieder antwortet, und zwar mit einem Werkzeug, das wirklich das MySQL-Protokoll spricht:

    sudo systemctl restart mysql
    mysqladmin -u root -p ping
    
  5. 5.

    Schon beim Erzeugen des Abzugs vorsorgen

    Auch mysqldump redet mit dem Server und hat dieselbe Grenze. Wer den Wert beim Erzeugen mitgibt, bekommt einen Abzug, der sich später wieder einspielen lässt, statt einen, der auf halber Strecke abbricht:

    mysqldump --max-allowed-packet=256M -u benutzer -p meinedb > abzug.sql
    
  6. 6.

    Die eigentliche Frage stellen

    Wenn einzelne Zeilen so groß werden, dass sie ein Kommunikationspaket sprengen, liegen meist Bilder, PDFs oder Videos als BLOB in der Datenbank. Dafür ist eine Datenbank das teuerste denkbare Dateisystem. Der saubere Weg ist, die Datei in einem Objektspeicher oder im Dateisystem abzulegen und in der Tabelle nur den Pfad zu führen — dann verschwindet dieses Limit von selbst aus dem Blickfeld.

Häufige Fragen (FAQ)

?Warum bricht ausgerechnet das Einspielen eines Abzugs ab?

Weil ein Abzug gern aus wenigen, dafür riesigen Anweisungen besteht: mysqldump packt viele Zeilen in ein einziges INSERT, und ein einzelnes BLOB-Feld kann für sich allein schon gewaltig sein. Jede dieser Anweisungen geht als ein Kommunikationspaket über die Leitung. Reißt sie das Limit, ist Schluss. Das MySQL-Handbuch ist da eindeutig: Empfängt ein Client oder der Server ein Paket, das größer ist als max_allowed_packet, wirft er ER_NET_PACKET_TOO_LARGE und schließt die Verbindung. Und weil beide Seiten ihr eigenes Limit haben, reicht es nicht, nur am Server zu drehen.

?Warum sehe ich stattdessen eine Meldung über eine verlorene Verbindung?

Das ist derselbe Vorgang aus Sicht des Clients. Der Server bricht die Verbindung ab, sobald das zu große Paket ankommt — manche Clients bekommen die eigentliche Fehlermeldung dann gar nicht mehr zu sehen und melden nur noch, dass die Verbindung während der Abfrage verloren ging. Das Handbuch nennt genau diesen Fall. Wer also eine abgerissene Verbindung sucht und dabei an Netzwerk oder Zeitlimits denkt, sucht oft an der falschen Stelle: Die Ursache liegt in der Größe der Anweisung, nicht in der Leitung.

?Ist es gefährlich, den Wert einfach hochzudrehen?

Weniger, als viele befürchten. Laut Handbuch belegt MySQL den zusätzlichen Speicher nur bei Bedarf, ein größerer Wert verschenkt also nicht dauerhaft Arbeitsspeicher. Der kleine Vorgabewert ist eine Vorsichtsmaßnahme, um fehlerhafte Pakete abzufangen und zu verhindern, dass eine Anwendung den Speicher aus Versehen leerräumt. Eine Obergrenze gibt es trotzdem: Das größte Paket, das ein MySQL-8.0-Server oder -Client überhaupt übertragen kann, ist 1 GB. Wer regelmäßig dagegenläuft, speichert vermutlich Dateien in der Datenbank, die dort nichts verloren haben.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

SWLästigAccess denied for user

MySQL: Access denied for user

Der Login wird abgewiesen, obwohl das Passwort stimmt? Bei MySQL zählt auch, von welchem Host aus man kommt — der Benutzer ist an eine Herkunft gebunden.