Registro di inoltro di MySQL danneggiato, come posso ripararlo? Provato ma fallito


25

Un relè MySQL v5.1.61 si è corrotto quando la macchina si è spenta improvvisamente. Ho provato a risolverlo ma non ha funzionato.
- Come lo aggiusto? Ho fatto qualcosa di male?

Per quanto ho letto, i log dei relè MySQL corrotti possono essere facilmente corretti:

change master to master_log_file='<Relay_Master_Log_File>',
                 master_log_pos=<Exec_Master_Log_Pos>;

dove Relay_Master_Log_Filee Exec_Master_Log_Possono elencati da:
mysql> show slave status;

Tuttavia, quando l'ho fatto change master status ..., ho riscontrato un errore di violazione della chiave primaria. Come è possibile? La procedura sopra descritta non è corretta o ad esempio manca qualche +1?

(Per ora ho semplicemente reimportato un mysqldump --master-data dal master allo slave, e questo ha risolto il problema. Tuttavia, in futuro, farlo potrebbe non essere appropriato.)


Ecco i dettagli sul mio problema specifico:

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: the-master-host
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000021
          Read_Master_Log_Pos: 33639968
               Relay_Log_File: mysql-relay-bin.000271
                Relay_Log_Pos: 2031587
        Relay_Master_Log_File: mysql-bin.000020
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: the_database
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1594
                   Last_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 66395191
              Relay_Log_Space: 36559177
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 1594
               Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.

E questo è quello che ho fatto:

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='the-master-host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

E questo è quello che è successo, un errore PK:

131122 15:17:29 [Note] Slave I/O thread: connected to master 'replication@the-master-host:3306',replication started in log 'mysql-bin.000020' at position 66395191
131122 15:17:29 [ERROR] Slave SQL: Error 'Duplicate entry '71373' for key 'PRIMARY'' on query. Default database: 'the_database'. Query: 'insert into ...  values ...', Error_code: 1062
131122 15:17:29 [Warning] Slave: Data truncated for column 'date' at row 1 Error_code: 1265
131122 15:17:29 [Warning] Slave: Duplicate entry '71373' for key 'PRIMARY' Error_code: 1062

Penso di aver seguito la procedura consigliata (vedere i link qui sotto), ma si è verificato ancora un errore PK :-(? Http://bugs.mysql.com/bug.php?id=26489 , cerca "Soluzioni alternative". Http: //mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/ /programming//a/14438408


1
Sì, sembra che avrebbe dovuto funzionare, e in realtà sembra che probabilmente abbia funzionato, dato che forse il registro di inoltro originale, prima della sezione corrotta, aveva già fatto l'inserimento in quella posizione del registro principale, ma non è riuscito ad avanzare visualizzato la posizione principale al puntatore successivo, poiché quel puntatore è memorizzato nel registro di inoltro (che era corrotto). Quindi potresti essere riuscito a saltare quell'evento e passare all'evento successivo, quindi verificando che master e slave avessero effettivamente dati identici ... Non ho ancora avuto l'opportunità di rivedere la domanda in modo sufficientemente dettagliato.
Michael - sqlbot,

1
Grazie @Michael-sqlbot, quindi penso che se questo problema si ripresenta, lo farò SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;e salterò un evento sullo slave, e spero che aiuti - ha senso? Se non aiuta (se c'è ancora un errore PK), importerò --master-datanuovamente un dump .
KajMagnus,

Risposte:


35

Errore: Last_SQL_Errno: 1594 Last_SQL_Error: errore lettura log di inoltro: impossibile analizzare la voce dell'evento del log di inoltro.

Questo errore indica che il file di registro principale è danneggiato o il file di registro di inoltro è danneggiato.

  • Prima di eseguire qualsiasi operazione, eseguire il backup di tutti i database, i registri, i server di immagini, ripetere più volte e continuare solo a proprio rischio.

Per prima cosa esegui "mostra stato slave \ G" sullo slave e nota:

Master_Log_File: mysql-bin.000026
Read_Master_Log_Pos: 2377104
Relay_Log_File: mysqld-relay-bin.000056
Relay_Log_Pos: 1097303
Relay_Master_Log_File: mysql-bin.000026
Exec_Master_Log_Pos: 1097157

Per prima cosa vogliamo assicurarci che il file di registro principale sia intatto, quindi saltate sul server principale e trovate Relay_Master_Log_File (check / var / log / mysql) ed eseguite il seguente comando:

mysqlbinlog mysql-bin.000026

Il registro verrà visualizzato, ma speriamo che non vedrai alcun messaggio di errore. Se visualizzi messaggi di errore, i log principali sono danneggiati e probabilmente dovrai ri-immagine.

Quindi esegui lo stesso comando sul registro di inoltro slave (spesso in / var / lib / mysql)

mysqlbinlog mysqld-relay-bin.000056

Probabilmente vedrai alcuni errori che mostrano il danneggiamento che ha interrotto la replica, in questo modo:

ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 336, event_type: 2
ERROR: Could not read entry at offset 1097414: Error in log format or read error.
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
root@db:/var/lib/mysql#

Se vengono visualizzati errori, il registro va bene sul master e solo il registro di inoltro dello slave è danneggiato. Questa è una buona notizia, possiamo resettare lo slave e dirgli i dettagli del master e da dove continuare. Se non vedi alcun errore, smetti di leggere ora, hai un problema diverso.

Se il registro di inoltro slave presenta errori, eseguire i comandi seguenti per ripristinare lo slave e i registri danneggiati si riconnettono al master, ottenere i registri ok e ricominciare a eseguire lo slave. Si noti che MASTER_LOG_POS è il Exec_Master_Log_Pos, e MASTER_LOG_FILE è il Relay_Master_Log_File( NON il primo, che corrisponde ai log di relè che sono stati recuperati e devono essere eliminati) entrambi dal primo comando.

mysql> stop slave;
Query OK, 0 rows affected (0.14 sec)

mysql> reset slave all;
Query OK, 0 rows affected (0.43 sec)

mysql>  CHANGE MASTER TO MASTER_HOST='master.host.com', MASTER_USER='masteruser', MASTER_PASSWORD='masterpass', MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=1097157;
Query OK, 0 rows affected (0.93 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

2
Ciao, grazie per la tua risposta. Se leggi attentamente la domanda, noterai che dice "Registro di inoltro corrotto" - questo perché abbiamo già utilizzato mysqlbinlognel modo da te suggerito e abbiamo scoperto che il registro di inoltro (non il registro principale) era stato danneggiato. Concenendo la correzione che suggerisci: se leggi attentamente la domanda, noterai che la correzione che suggerisci è esattamente ciò che avevamo già tentato. Ma quello non ha funzionato, ed è di questo che si tratta. - Ma la tua risposta potrebbe essere utile per altre persone con un problema simile.
KajMagnus,

2
Si dovrebbe probabilmente essere notato, che MASTER_LOG_FILEnel CHANGE MASTERdovrebbe essere presa da Relay_Master_Log_Filee non da Master_Log_File. Di solito saranno gli stessi, ma potrebbe non essere sempre così (vedi percona.com/blog/2008/07/07/… ).
brablc,

@brablc ha ragione. Relay_Master_Log_Filedeve essere usato, no Master_Log_File. Vedi anche: percona.com/blog/2008/07/07/…
Mircea Vutcovici

nella maggior parte dei casi, non è necessario reset slave allperché le impostazioni principali non devono essere modificate (ad esempio master_host, master_user, master_password), solo MASTER_LOG_FILE e MASTER_LOG_POS, quindi reset_slavedovrebbe bastare
ympostor

Questa domanda e risposta mi hanno già salvato diverse volte. Grazie.
Artem Russakovskii,

8

[Correzione della replica di MySQL dopo che il registro di inoltro degli slave era corrotto]

La replica di MySQL su slave (versione 5.XX) è stata interrotta. Slave_IO_Running è stato contrassegnato come Sì, ma Slave_SQL_Running come No. Lo slave di arresto / avvio semplice non ha aiutato, pertanto erano necessarie ulteriori analisi dei problemi. Sembrava che il log degli relay dello slave corrente fosse corrotto perché il test con "mysqlbinlog" ha stampato un errore. Pertanto, la soluzione era quella di scartare i binlog di relè correnti e puntare lo slave sull'ultima posizione del binlog principale.

Per correggere l'errore, i file binlog correnti sullo slave devono essere eliminati e impostare una nuova posizione. Prima di impostare la nuova posizione binlog è importante ricordare i valori Relay_Master_Log_File ed Exec_Master_Log_Pos dal server slave danneggiato usando il comando SHOW SLAVE STATUS \ G :

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

OK, con questi valori, è possibile impostare una nuova posizione binlog:

# stop slave
mysql> stop slave;

# make slave forget its replication position in the master's binary log
mysql> reset slave;

# change slave to start reading from stopped position
mysql> change master to master_log_file='mysql-bin.002045', master_log_pos=103641119;

# start slave
mysql> start slave;

Basta notare che reset slavecancellerà master.info, relay-log.infoe tutti i file di log del relè, quindi non è necessario per gli avanzi pulite in /var/lib/mysqldirectory.


1
Buona risposta - di solito non è necessario modificare l'host principale, la password, ecc. Grazie!
andy250,

3

So che è passato più di un anno, ma ecco cosa potrebbe essere successo a questo particolare problema.

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='the-master-host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

Sembra che avrebbe dovuto risolverlo perché ha rimosso il registro di inoltro corrotto.

Quindi, hai ricevuto un errore PK 1062. Perché?

Esiste un bug eccezionale ( http://bugs.mysql.com/bug.php?id=60847 ) ancora attivo in MySQL 5.5

Sebbene il bug si riferisca all'uso di mysql --single-transazione --flush-logs, esiste una stranezza correlata.

Ho visto quella stranezza su alcuni server EC2 in esecuzione come Slaves per un client proprio la scorsa settimana in MySQL 5.5.15

Sul Master, c'era uno strano INSERTO esteso a più righe in cui ogni tupla da inserire era un SELEZIONARE. Ciò che è accaduto è stato che il LAST_INSERT_ID nel registro di inoltro, che costituisce il successivo incremento automatico da assegnare, era già in uso sullo slave a causa di inserimenti su più righe.

L'INSERTO serializzato nel registro di inoltro sembrava

INSERT INTO tablname (column,column) VALUES (value,value,...)

L'elenco delle colonne non includeva la chiave primaria numerica. Quando l'errore 1062 è tornato, vorrei utilizzare la stessa query su cui non è riuscito, eseguire la query manualmente. Non ha riscontrato l'errore 1062. Quindi, ho eseguito i soliti comandi skip slave:

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SET @sleepnumber = SLEEP(3);
SHOW SLAVE STATUS\G

Quindi, la replica ha raggiunto.

Il mio consiglio sarebbe di serializzare correttamente i tuoi INSERTI sul Master perché questa situazione simile a un bug è in realtà abbastanza evitabile.


1

L'hai fatto abbastanza bene (come altri hanno già detto).

L'unico problema riguarda il file master.info (contiene informazioni sulla posizione nel mysql-bin.log del master) poiché questo file non viene sincronizzato su disco dopo l'elaborazione di ogni query.

Quindi le tue informazioni sulle posizioni nel registro del master sono obsolete e stai elaborando query già elaborate che devono essere ignorate SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;.

Sfortunatamente, se usi domande come UPDATE table SET counter=counter+1 WHERE id = 12345e l'utilizzo dei binlog_format=STATEMENTtuoi database potrebbe non essere sincronizzato, penso.

Puoi dire al server MySQL di sincronizzare master.info dopo ogni evento impostando la variabile sync_master_info ma probabilmente avrà enormi conseguenze sulle prestazioni.

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.