Welches max_allowed_packet ist groß genug und warum muss ich es ändern?

14

Ich habe MySQL (5.5) im Master-Slave-Setup und einen anderen Slave-Server erstellt.

Ich habe den ursprünglichen Slave gestoppt, die Daten gelöscht, kopiert und wieder importiert und es hat gut funktioniert. Ich habe die master_log-Position des ursprünglichen Slaves notiert und diese Befehle verwendet, um sie für den neuen Slave festzulegen

CHANGE MASTER TO MASTER_HOST='<ipaddress>', 
MASTER_USER='<username>', MASTER_PASSWORD='<password>', 
MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000851', 
MASTER_LOG_POS=15824150, 
MASTER_CONNECT_RETRY=10;

Als ich mit dem neuen Sklaven anfing, bekam ich

Last_IO_Error: Schwerwiegender Fehler 1236 vom Master beim Lesen von Daten aus dem Binärlog: 'Logereignis-Eintrag überschritten max_allowed_packet; Erhöhe max_allowed_packet auf master '

Als ich den ursprünglichen Sklaven startete, holte er jedoch gut auf und ist jetzt synchronisiert.

Also die Fragen:

  • Der aktuelle Wert ist 16 Millionen. Woher weiß ich, wie groß der Rest sein muss? (Ich würde lieber das Ausprobieren mit einem Produktionsserver vermeiden).

  • Warum muss ich den Wert auf dem Master erhöhen, wenn der ursprüngliche Slave einwandfrei funktioniert hat? Kann das Problem wirklich beim neuen Slave liegen?

aktualisieren

Ich erhöhte das max_allowed_packet auf 1073741824, als Rolando den Master, den alten und den neuen Slave vorschlug, und startete sie neu ( SET GLOBAL max_allowed_packet = 1073741824;aus irgendeinem Grund schien es nicht zu dauern)

jetzt ist der letzte E / A-Fehler derselbe wie zuvor, aber jetzt sehe ich

Last_SQL_Error: Fehler beim Lesen des Relaisprotokolls: Der Ereigniseintrag des Relaisprotokolls konnte nicht analysiert werden. Mögliche Gründe sind: Das Binärlog des Masters ist beschädigt (Sie können dies überprüfen, indem Sie im Binärlog 'mysqlbinlog' ausführen), das Relay-Log des Slaves ist beschädigt (Sie können dies überprüfen, indem Sie im Relay-Log 'mysqlbinlog' ausführen), a Netzwerkproblem oder ein Fehler im MySQL-Code des Masters oder Slaves. Wenn Sie das Binärprotokoll des Masters oder das Relaisprotokoll des Slaves überprüfen möchten, können Sie deren Namen ermitteln, indem Sie für diesen Slave die Meldung 'SHOW SLAVE STATUS' ausgeben.

Wenn ich ein mysqlbinlog für die Master-Datei mache, scrollt es mit Befehlen ziemlich glücklich für Ewigkeiten vorbei - die Datei ist 722M groß - wenn ich das für das Slave-Relay-Protokoll mache, das ich erhalte

FEHLER: Fehler in Log_event :: read_log_event (): 'Überprüfung der Datenqualität fehlgeschlagen', data_len: 38916267, event_type: 69

FEHLER: Eintrag bei Offset 253 konnte nicht gelesen werden: Fehler im Protokollformat oder Lesefehler.

Ich habe die Variablen überprüft und die Änderungen haben jedoch funktioniert

mysql> show variables LIKE '% max_allowed_packet%';

auf dem neuen sklaven zeigte max_allowed_packetUNDslave_max_allowed_packet wo wie auf dem master es nur hatmax_allowed_packet

Also habe ich den Master einer Versionsprüfung unterzogen:

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 1.1.6                                |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.11-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

und auf den neuen sklaven

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.5.32                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.32-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

Sind diese beiden Versionen zu weit voneinander entfernt?

CodeMonkey
quelle
Es gibt etwas , was interessant hier . Hoffe das wäre hilfreich.
Sathish D

Antworten:

18

Es ist in Ordnung, das max_allowed_packetauf 1G zu maximieren. Jedes Mal, wenn ein MySQL-Paket erstellt wird, springt es von Anfang an nicht auf 1G. Warum?

Zuerst müssen Sie wissen, was ein MySQL-Paket ist. Seite 99 des Buches

Grundlegendes zu MySQL-Interna

erklärt es in den Absätzen 1-3 wie folgt:

MySQL-Netzwerkkommunikationscode wurde unter der Annahme geschrieben, dass Abfragen immer relativ kurz sind und daher in einem Block, der als Paket bezeichnet wird, an den Server gesendet und von diesem verarbeitet werden können in der MySQL-Terminologie . 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 . Schau dir my_net_read () an , folge dann dem Aufruf von my_real_read () und achte 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 .

Vergleichen Sie das mit der MySQL-Dokumentation unter max_allowed_packet:

Die maximale Größe eines Pakets oder einer generierten Zeichenfolge / Zwischenzeichenfolge oder eines Parameters, der von der C-API-Funktion mysql_stmt_send_long_data () gesendet wird. Der Standardwert ist 4 MB ab MySQL 5.6.6, davor 1 MB.

Der Paketnachrichtenpuffer wird auf net_buffer_length Bytes initialisiert, kann aber bei Bedarf auf max_allowed_packet Bytes anwachsen. Dieser Wert ist standardmäßig klein, um große (möglicherweise falsche) Pakete abzufangen.

Sie müssen diesen Wert erhöhen, wenn Sie große BLOB-Spalten oder lange Zeichenfolgen verwenden. Es sollte so groß sein wie das größte BLOB, das Sie verwenden möchten. Das Protokolllimit für max_allowed_packet beträgt 1 GB. Der Wert sollte ein Vielfaches von 1024 sein. Nichtmehrfache werden auf das nächste Vielfache abgerundet.

Wenn Sie die Größe des Nachrichtenpuffers ändern, indem Sie den Wert der Variablen max_allowed_packet ändern, sollten Sie auch die Größe des Puffers auf der Clientseite ändern, wenn Ihr Client-Programm dies zulässt. Auf der Clientseite hat max_allowed_packet einen Standardwert von 1 GB. Mit einigen Programmen wie mysql und mysqldump können Sie den clientseitigen Wert ändern, indem Sie max_allowed_packet in der Befehlszeile oder in einer Optionsdatei festlegen.

Angesichts dieser Informationen sollten Sie froh sein, dass MySQL das MySQL-Paket nach Bedarf erweitert und komprimiert. Deshalb mach weiter und

Master und Slave sollten übereinstimmen, wen sie Daten übertragen, insbesondere BLOB-Daten.

UPDATE 04.07.2013 07:03 EDT

Aus Ihren Nachrichten zum Relay-Protokoll geht hervor, dass Sie Folgendes haben

  • ein beschädigtes Relay-Protokoll
  • ein gutes Master Log

VORSCHLAG

SHOW SLAVE STATUS\G
STOP SLAVE;
CHANGE MASTER TO
MASTER_LOG_FILE='(Relay_Master_Log_File from SHOW SLAVE STATUS\G)',
MASTER_LOG_POS=(Exec_Master_Log_Pos from SHOW SLAVE STATUS\G);
START SLAVE;

Beim Ausführen werden CHANGE MASTER TOalle Relaisprotokolle gelöscht und es wird ein neues Protokoll erstellt. Sie replizieren vom letzten Master-BinLog-Ereignis (BinLog, Position), das auf dem Slave ausgeführt wurde.

Versuche es !!!

RolandoMySQLDBA
quelle
danke, das ist toll, dass es sicher ist; aber ich verstehe immer noch nicht, warum ich es überhaupt ändern muss, wenn der aktuelle Wert mit dem Master und dem anderen Slave übereinstimmt, der perfekt funktioniert?
CodeMonkey
etwas anderes ist los, ich habe mehr Details hinzugefügt
CodeMonkey
1
Nur zu Ihrer Information: Dies ist mir passiert, als ich den Replikationsprozess zurückgesetzt und versehentlich einen falschen MASTER_LOG_FILENamen eingegeben habe . ZB verwendet , mysql-bin.000001wenn ich verwendet habe , sollte mysql-bin.000003von SHOW MASTER STATUSin CHANGE MASTER TO.
Mikko Ohtamaa
7

Eher peinlich war das Problem, dass falsche Dateinamen für Protokolle, die seltsame Ergebnisse verursachten, mit den richtigen Dateinamen reimportiert wurden und alles in Ordnung war, hängt Kopf in Schande

CodeMonkey
quelle
Danke vielmals! Sie waren nicht der einzige, der diesen Fehler gemacht hat.
Mikko Ohtamaa
2
Es lohnt sich immer, die Antwort zu posten, auch wenn es albern ist. Jeder macht dumme Fehler, da wir alle Menschen sind. Abgesehen von denen von uns, die Roboter sind.
John Hunt