¿Qué max_allowed_packet es lo suficientemente grande y por qué necesito cambiarlo?

14

Tengo MySQL (5.5) en la configuración maestro-esclavo y creé otro servidor esclavo.

Detuve al esclavo original, descargué los datos, copié y volví a importar y funcionó bien. Noté la posición master_log del esclavo original y usé estos comandos para configurarlo en el nuevo esclavo

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;

Cuando comencé el nuevo esclavo que obtuve

Last_IO_Error: error grave 1236 del maestro al leer datos del registro binario: 'la entrada del evento de registro excedió max_allowed_packet; Aumentar max_allowed_packet en master '

Sin embargo, cuando comencé el esclavo original, se puso al día bien y ahora está sincronizado.

Entonces las preguntas:

  • el valor actual es 16M, ¿cómo sé qué tan grande ir? (Prefiero evitar la prueba y error con un servidor de producción).

  • ¿por qué necesito aumentar el valor en el maestro cuando el esclavo original se las arregló bien, podría realmente ser el problema con el nuevo esclavo?

actualizar

Aumenté el max_allowed_packet a 1073741824 como Rolando sugirió en el maestro, esclavo viejo y esclavo nuevo, y los reinicié ( SET GLOBAL max_allowed_packet = 1073741824;por alguna razón no pareció tomar)

ahora el último error de IO es el mismo que antes, pero ahora veo

Last_SQL_Error: error de lectura del registro de retransmisión: no se pudo analizar la entrada del evento de registro de retransmisión. Las posibles razones son: el registro binario del maestro está dañado (puede verificar esto ejecutando 'mysqlbinlog' en el registro binario), el registro de retransmisión del esclavo está dañado (puede verificar esto ejecutando 'mysqlbinlog' en el registro de retransmisión), un problema de red, o un error en el código MySQL del maestro o esclavo. Si desea verificar el registro binario del maestro o el registro de retransmisión del esclavo, podrá conocer sus nombres al emitir 'SHOW SLAVE STATUS' en este esclavo.

Si hago un mysqlbinlog en el archivo del maestro, se desplaza más allá con comandos muy felices durante siglos: el archivo es 722M, si lo hago para el registro de retransmisión esclavo, obtengo

ERROR: Error en Log_event :: read_log_event (): 'Error de comprobación de cordura', data_len: 38916267, event_type: 69

ERROR: no se pudo leer la entrada en el desplazamiento 253: error en el formato de registro o error de lectura.

Sin embargo, verifiqué las variables y los cambios funcionaron

mysql> muestra las variables como '% max_allowed_packet%';

en el nuevo esclavo mostró max_allowed_packetY slave_max_allowed_packetdonde como en el maestro solo tienemax_allowed_packet

así que hice una verificación de versión en el maestro:

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

y en el nuevo esclavo

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

¿Estas 2 versiones están demasiado separadas?

CodeMonkey
fuente
Hay algo interesante aquí . Espero que esto sea útil.
Sathish D

Respuestas:

18

Está bien maximizar el máximo max_allowed_packeta 1G. Cada vez que se construye un paquete MySQL, no saltará a 1G desde el principio. ¿Por qué?

Primero necesitas saber qué es un paquete MySQL. Página 99 del libro

Comprender los aspectos internos de MySQL

lo explica en los párrafos 1-3 de la siguiente manera:

El código de comunicación de red MySQL se escribió bajo el supuesto de que las consultas siempre son razonablemente cortas y, por lo tanto, el servidor puede enviarlas y procesarlas en un fragmento, que se denomina paquete en la terminología de MySQL. El servidor asigna la memoria para un búfer temporal para almacenar el paquete, y solicita lo suficiente para ajustarlo por completo. Esta arquitectura requiere una precaución para evitar que el servidor se quede sin memoria, un límite en el tamaño del paquete, lo que esta opción logra.

El código de interés en relación con esta opción se encuentra en sql / net_serv.cc . Eche un vistazo a my_net_read () , luego siga la llamada a my_real_read () y preste especial atención a net_realloc () .

Esta variable también limita la longitud de un resultado de muchas funciones de cadena. Vea sql / field.cc y sql / intem_strfunc.cc para más detalles.

Compare eso con la documentación de MySQL en max_allowed_packet:

El tamaño máximo de un paquete o cualquier cadena intermedia / generada, o cualquier parámetro enviado por la función de API mysql_stmt_send_long_data () C. El valor predeterminado es 4 MB a partir de MySQL 5.6.6, 1 MB antes de eso.

El búfer de mensajes de paquete se inicializa en bytes net_buffer_length, pero puede crecer hasta bytes max_allowed_packet cuando sea necesario. Este valor por defecto es pequeño, para capturar paquetes grandes (posiblemente incorrectos).

Debe aumentar este valor si está utilizando columnas BLOB grandes o cadenas largas. Debe ser tan grande como el BLOB más grande que quieras usar. El límite de protocolo para max_allowed_packet es de 1 GB. El valor debe ser un múltiplo de 1024; los no múltiples se redondean al múltiplo más cercano.

Cuando cambia el tamaño del búfer de mensajes cambiando el valor de la variable max_allowed_packet, también debe cambiar el tamaño del búfer en el lado del cliente si su programa cliente lo permite. En el lado del cliente, max_allowed_packet tiene un valor predeterminado de 1 GB. Algunos programas como mysql y mysqldump le permiten cambiar el valor del lado del cliente configurando max_allowed_packet en la línea de comando o en un archivo de opciones.

Dada esta información, debe alegrarse de que MySQL se expanda y contraiga el paquete MySQL según sea necesario. Por lo tanto, adelante y

Master y Slave deben coincidir en términos de a quién transmiten datos, especialmente datos BLOB.

ACTUALIZACIÓN 2013-07-04 07:03 EDT

De sus mensajes relacionados con el registro de retransmisión, parece que tiene lo siguiente

  • un registro de retransmisión corrupto
  • un buen registro maestro

SUGERENCIA

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;

La ejecución CHANGE MASTER TOborra todos los registros de retransmisión y comienza con uno nuevo. Se replicará desde el último evento maestro de BinLog (BinLog, posición) que se ejecutó en el esclavo.

Darle una oportunidad !!!

RolandoMySQLDBA
fuente
gracias, es genial que sea seguro; pero todavía no entiendo por qué necesito cambiarlo cuando el valor actual coincide con el maestro y el otro esclavo que funciona perfectamente.
CodeMonkey
algo más está sucediendo, he agregado más detalles
CodeMonkey
1
Solo para su información: esto ocurrió cuando reinicié el proceso de replicación y accidentalmente ingresé un MASTER_LOG_FILEnombre incorrecto . Por ejemplo, usado mysql-bin.000001cuando debería haberlo usado mysql-bin.000003desde SHOW MASTER STATUSadentro CHANGE MASTER TO.
Mikko Ohtamaa
8

Más bien el problema era vergonzosamente nombres de archivos incorrectos para troncos, producir resultados extraños, reimportadas con los nombres de los archivos correctos y todo estaba bien cuelga la cabeza de vergüenza

CodeMonkey
fuente
¡Muchas gracias! No fuiste el único que cometió este error.
Mikko Ohtamaa
3
Siempre vale la pena publicar la respuesta, incluso si es una tontería. Todos cometen errores tontos ya que todos somos humanos. Aparte de aquellos de nosotros que somos robots.
John Hunt