Quel max_allowed_packet est assez grand, et pourquoi dois-je le changer?

14

J'ai MySQL (5.5) dans la configuration maître-esclave et j'ai créé un autre serveur esclave.

J'ai arrêté l'esclave d'origine, vidé les données, copié et réimporté et cela a bien fonctionné. J'ai noté le master_log pos de l'esclave d'origine et utilisé ces commandes pour le définir sur le nouvel esclave

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;

Quand j'ai commencé le nouvel esclave, j'ai

Last_IO_Error: erreur fatale 1236 obtenue du maître lors de la lecture des données du journal binaire: 'l'entrée d'événement de journal a dépassé max_allowed_packet; Augmenter max_allowed_packet sur le maître '

Cependant, lorsque j'ai démarré l'esclave d'origine, il a très bien rattrapé et est maintenant synchronisé.

Donc les questions:

  • la valeur actuelle est de 16M, comment savoir quelle taille aller? (Je préfère éviter les essais et erreurs avec un serveur de production).

  • pourquoi dois-je augmenter la valeur sur le maître lorsque l'esclave d'origine a très bien fait face, le problème pourrait-il vraiment être avec le nouvel esclave?

mise à jour

J'ai augmenté le max_allowed_packet à 1073741824 comme Rolando l'a suggéré sur le maître, l'ancien esclave et le nouvel esclave, et les SET GLOBAL max_allowed_packet = 1073741824;ai redémarrés ( pour une raison quelconque, cela ne semblait pas prendre)

maintenant la dernière erreur d'E / S est la même qu'avant, mais maintenant je vois

Last_SQL_Error: échec de lecture du journal de relais: impossible d'analyser l'entrée d'événement du journal de relais. Les raisons possibles sont: le journal binaire du maître est corrompu (vous pouvez le vérifier en exécutant 'mysqlbinlog' sur le journal binaire), le journal de relais de l'esclave est corrompu (vous pouvez le vérifier en exécutant 'mysqlbinlog' sur le journal de relais), un problème de réseau ou bogue dans le code MySQL du maître ou de l'esclave. Si vous souhaitez vérifier le journal binaire du maître ou le journal des relais de l'esclave, vous pourrez connaître leurs noms en émettant 'SHOW SLAVE STATUS' sur cet esclave.

Si je fais un mysqlbinlog sur le fichier du maître, il défile avec bonheur avec des commandes depuis des lustres - le fichier est 722M - si je le fais pour le journal du relais esclave que j'obtiens

ERREUR: erreur dans Log_event :: read_log_event (): 'Échec de la vérification de l'intégrité', data_len: 38916267, event_type: 69

ERREUR: impossible de lire l'entrée à l'offset 253: erreur au format du journal ou erreur de lecture.

J'ai vérifié les variables et les changements ont fonctionné cependant

mysql> afficher les variables LIKE '% max_allowed_packet%';

sur le nouvel esclave a montré max_allowed_packetET slave_max_allowed_packetoù, comme sur le maître, il n'a quemax_allowed_packet

j'ai donc fait une vérification de version sur le maître:

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                                |
+-------------------------+--------------------------------------+

et sur le nouvel esclave

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                                |
+-------------------------+--------------------------------------+

Ces 2 versions sont-elles trop éloignées?

CodeMonkey
la source
Il y a quelque chose d'intéressant ici . J'espère que cela serait utile.
Sathish D

Réponses:

18

Il est normal de maximiser le max_allowed_packet1G. Chaque fois qu'un paquet MySQL est construit, il ne sautera pas à 1G dès le départ. Pourquoi?

Vous devez d'abord savoir ce qu'est un paquet MySQL. Page 99 du livre

Comprendre les internes de MySQL

l'explique aux paragraphes 1 à 3 comme suit:

Le code de communication réseau MySQL a été écrit en supposant que les requêtes sont toujours raisonnablement courtes, et peuvent donc être envoyées et traitées par le serveur en un seul morceau, qui est appelé un paquet dans la terminologie MySQL. Le serveur alloue la mémoire à un tampon temporaire pour stocker le paquet et il en demande suffisamment pour l'adapter entièrement. Cette architecture nécessite une précaution pour éviter que le serveur manque de mémoire --- un plafond sur la taille du paquet, ce que cette option accomplit.

Le code d'intérêt par rapport à cette option se trouve dans sql / net_serv.cc . Jetez un œil à my_net_read () , puis suivez l'appel à my_real_read () et portez une attention particulière à net_realloc () .

Cette variable limite également la longueur d'un résultat de nombreux fonctons de chaîne. Voir sql / field.cc et sql / intem_strfunc.cc pour plus de détails.

Comparez cela avec la documentation MySQL sur max_allowed_packet:

La taille maximale d'un paquet ou de toute chaîne générée / intermédiaire, ou de tout paramètre envoyé par la fonction API C mysql_stmt_send_long_data (). La valeur par défaut est 4 Mo à partir de MySQL 5.6.6, 1 Mo avant cela.

Le tampon de message de paquet est initialisé en octets net_buffer_length, mais peut atteindre jusqu'à octets max_allowed_packet si nécessaire. Cette valeur par défaut est petite, pour intercepter de gros paquets (éventuellement incorrects).

Vous devez augmenter cette valeur si vous utilisez de grandes colonnes BLOB ou de longues chaînes. Il doit être aussi grand que le plus grand BLOB que vous souhaitez utiliser. La limite de protocole pour max_allowed_packet est de 1 Go. La valeur doit être un multiple de 1024; les non multiples sont arrondis au multiple le plus proche.

Lorsque vous modifiez la taille de la mémoire tampon de messages en modifiant la valeur de la variable max_allowed_packet, vous devez également modifier la taille de la mémoire tampon côté client si votre programme client le permet. Côté client, max_allowed_packet a une valeur par défaut de 1 Go. Certains programmes tels que mysql et mysqldump vous permettent de modifier la valeur côté client en définissant max_allowed_packet sur la ligne de commande ou dans un fichier d'options.

Compte tenu de ces informations, vous devriez être content que MySQL développe et contracte le paquet MySQL selon les besoins. Par conséquent, allez-y et

Le maître et l'esclave doivent correspondre en fonction de qui ils transmettent les données, en particulier les données BLOB.

MISE À JOUR 2013-07-04 07:03 EDT

D'après vos messages concernant le journal de relais, il semble que vous ayez les éléments suivants

  • un journal de relais corrompu
  • un bon journal principal

SUGGESTION

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;

Fonctionnement CHANGE MASTER TO efface tous les journaux de relais et commence par un nouveau. Vous allez répliquer à partir du dernier événement BinLog maître (BinLog, Position) qui s'est exécuté sur l'esclave.

Essaie !!!

RolandoMySQLDBA
la source
merci, c'est génial que ce soit sûr; mais je ne comprends toujours pas pourquoi je dois le changer du tout lorsque la valeur actuelle correspond au maître et à l'autre esclave qui fonctionne parfaitement?
CodeMonkey
quelque chose d'autre se passe, j'ai ajouté plus de détails
CodeMonkey
1
Juste pour votre information: cela m'est arrivé lorsque j'ai réinitialisé le processus de réplication et entré accidentellement un mauvais MASTER_LOG_FILEnom. Par exemple , utilisé mysql-bin.000001quand je aurais dû mysql-bin.000003partir SHOW MASTER STATUSen CHANGE MASTER TO.
Mikko Ohtamaa
8

Plutôt gênant, le problème était des noms de fichiers incorrects pour les journaux, provoquant des résultats étranges, réimportés avec les noms de fichiers corrects et tout allait bien se bloque la tête de honte

CodeMonkey
la source
Merci beaucoup! Vous n'étiez pas le seul à faire cette erreur.
Mikko Ohtamaa
3
Cela vaut toujours la peine de poster la réponse même si c'est idiot. Tout le monde fait des erreurs idiotes car nous sommes tous humains. À part ceux d'entre nous qui sont des robots.
John Hunt