Quale max_allowed_packet è abbastanza grande e perché devo cambiarlo?


14

Ho MySQL (5.5) nella configurazione master-slave e ho creato un altro server slave.

Ho fermato lo slave originale, scaricato i dati, copiato e reimportato e ha funzionato bene. Ho notato la posizione master_log dello slave originale e ho usato questi comandi per impostarlo sul nuovo slave

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;

Quando ho iniziato il nuovo schiavo ho avuto

Last_IO_Error: errore irreversibile 1236 dal master durante la lettura dei dati dal registro binario: 'la voce dell'evento registro ha superato max_allowed_packet; Aumenta max_allowed_packet sul master "

Tuttavia, quando ho avviato lo slave originale, ha raggiunto bene, ed è ora sincronizzato.

Quindi le domande:

  • il valore attuale è 16M, come faccio a sapere quanto grande andare? (Preferirei evitare tentativi ed errori con un server di produzione).

  • perché devo aumentare il valore sul master quando lo slave originale ha funzionato bene, il problema potrebbe davvero riguardare il nuovo slave?

aggiornare

Ho aumentato il max_allowed_packet a 1073741824 come suggerito da Rolando al master, al vecchio slave e al nuovo slave, e li SET GLOBAL max_allowed_packet = 1073741824;ho riavviati ( per qualche motivo non sembra prendere)

ora l'ultimo errore IO è lo stesso di prima, ma ora vedo

Last_SQL_Error: errore lettura log di inoltro: impossibile analizzare la voce dell'evento del log di inoltro. I possibili motivi sono: il registro binario del master è danneggiato (è possibile verificarlo eseguendo "mysqlbinlog" sul registro binario), il registro di inoltro dello slave è danneggiato (è possibile verificarlo eseguendo "mysqlbinlog" nel registro di inoltro), un problema di rete o un bug nel codice MySQL del master o dello slave. Se si desidera controllare il registro binario del master o il registro di inoltro dello slave, sarà possibile conoscerne i nomi emettendo "SHOW SLAVE STATUS" su questo slave.

Se eseguo un mysqlbinlog sul file del master, scorre per anni con i comandi abbastanza felicemente - il file è 722M - se lo faccio per il registro di relè slave ottengo

ERRORE: errore in Log_event :: read_log_event (): 'Controllo di integrità non riuscito', data_len: 38916267, tipo_evento: 69

ERRORE: impossibile leggere la voce all'offset 253: errore nel formato registro o errore di lettura.

Ho controllato le variabili e le modifiche hanno funzionato comunque

mysql> mostra le variabili LIKE '% max_allowed_packet%';

sul nuovo schiavo mostrato max_allowed_packetE slave_max_allowed_packetdove solo come sul padronemax_allowed_packet

così ho fatto un controllo di versione sul master:

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

e sul nuovo schiavo

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

Queste 2 versioni sono troppo distanti?


C'è qualcosa di interessante qui . Spero che questo possa essere utile.
Sathish D

Risposte:


18

È OK per massimizzare l' max_allowed_packet1G. Ogni volta che viene creato un pacchetto MySQL, non salterà a 1G dall'inizio. Perché?

Per prima cosa devi sapere cos'è un pacchetto MySQL. Pagina 99 del libro

Comprensione di MySQL Internals

lo spiega nei paragrafi 1-3 come segue:

Il codice di comunicazione della rete MySQL è stato scritto partendo dal presupposto che le query sono sempre ragionevolmente brevi e pertanto possono essere inviate ed elaborate dal server in un unico blocco, che viene chiamato pacchetto nella terminologia MySQL. Il server alloca la memoria per un buffer temporaneo per archiviare il pacchetto e richiede abbastanza per adattarlo interamente. Questa architettura richiede una precauzione per evitare che il server esaurisca la memoria, ovvero un limite alla dimensione del pacchetto, che questa opzione consente.

Il codice di interesse in relazione a questa opzione si trova in sql / net_serv.cc . Dai un'occhiata a my_net_read () , quindi segui la chiamata a my_real_read () e presta particolare attenzione a net_realloc () .

Questa variabile limita anche la lunghezza di un risultato di molte funzioni stringa. Vedi sql / field.cc e sql / intem_strfunc.cc per i dettagli.

Confrontalo con la documentazione di MySQL su max_allowed_packet:

La dimensione massima di un pacchetto o qualsiasi stringa generata / intermedia o qualsiasi parametro inviato dalla funzione API C mysql_stmt_send_long_data (). L'impostazione predefinita è 4 MB a partire da MySQL 5.6.6, 1 MB prima.

Il buffer dei messaggi di pacchetto è inizializzato in byte net_buffer_length, ma può crescere fino a max_allowed_packet byte quando necessario. Questo valore di default è piccolo, per catturare pacchetti grandi (possibilmente errati).

È necessario aumentare questo valore se si utilizzano colonne BLOB di grandi dimensioni o stringhe lunghe. Dovrebbe essere grande quanto il BLOB più grande che desideri utilizzare. Il limite di protocollo per max_allowed_packet è di 1 GB. Il valore dovrebbe essere un multiplo di 1024; i non multipli sono arrotondati per difetto al multiplo più vicino.

Quando si modifica la dimensione del buffer dei messaggi modificando il valore della variabile max_allowed_packet, è necessario modificare anche la dimensione del buffer sul lato client se il programma client lo consente. Sul lato client, max_allowed_packet ha un valore predefinito di 1 GB. Alcuni programmi come mysql e mysqldump consentono di modificare il valore sul lato client impostando max_allowed_packet sulla riga comandi o in un file di opzioni.

Date queste informazioni, dovresti essere felice che MySQL espanderà e contrarrà il pacchetto MySQL secondo necessità. Pertanto, vai avanti e

Master e Slave dovrebbero corrispondere in termini di chi trasmettono i dati, in particolare i dati BLOB.

AGGIORNAMENTO 2013-07-04 07:03 EDT

Dai tuoi messaggi riguardanti il ​​registro di inoltro, sembra che tu abbia il seguente

  • un registro di inoltro corrotto
  • un buon registro principale

SUGGERIMENTO

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;

L'esecuzione CHANGE MASTER TOcancella tutti i registri di inoltro e inizia con uno nuovo. Verrà replicato dall'evento BinLog dell'ultimo master (BinLog, posizione) eseguito sullo slave.

Provaci !!!


grazie, è fantastico che sia sicuro; ma ancora non capisco perché devo cambiarlo quando il valore corrente corrisponde al master e all'altro slave che funziona perfettamente?
CodeMonkey,

sta succedendo qualcos'altro, ho aggiunto ulteriori dettagli
CodeMonkey il

1
Solo per tua informazione: questo mi è successo quando ho ripristinato il processo di replica e ho inserito per errore il MASTER_LOG_FILEnome sbagliato . Ad esempio usato mysql-bin.000001quando avrei dovuto usare mysql-bin.000003da SHOW MASTER STATUSdentro CHANGE MASTER TO.
Mikko Ohtamaa,

8

Piuttosto imbarazzante il problema erano i nomi di file errati per i registri, che causavano strani risultati, reimportati con i nomi di file corretti e tutto andava bene si blocca nella vergogna


Molte grazie! Non sei stato l'unico a fare questo errore.
Mikko Ohtamaa,

3
Vale sempre la pena pubblicare la risposta anche se è sciocca. Tutti fanno errori stupidi perché siamo tutti umani. A parte quelli di noi che sono robot.
John Hunt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.