Registro de retransmissão do MySQL corrompido, como corrigi-lo? Tentou, mas falhou

25

Um relé MySQL v5.1.61 foi corrompido quando a máquina foi desligada repentinamente. Tentei consertar, mas não funcionou.
- Como faço para corrigir isso? Fiz algo de errado?

Até onde eu li, os logs de retransmissão do MySQL corrompidos são facilmente corrigidos:

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

onde Relay_Master_Log_Filee Exec_Master_Log_Possão listados por:
mysql> show slave status;

No entanto, quando o fiz change master status ..., recebi um erro de violação de chave primária. Como isso é possível? O procedimento acima não está correto ou, por exemplo, está faltando algum +1?

(Por enquanto, simplesmente reimportei um mysqldump --master-data do master para o slave, e isso resolveu o problema. No entanto, no futuro, fazer isso pode não ser apropriado.)


A seguir, detalhes sobre o meu problema específico:

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 foi isso que eu fiz:

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 foi isso que aconteceu, um erro de 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

Acho que segui o procedimento recomendado (consulte os links logo abaixo), ainda houve um erro de PK :-(? Http://bugs.mysql.com/bug.php?id=26489 , procure por "Soluções alternativas". Http: //mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/ /programming//a/14438408

KajMagnus
fonte
11
Sim, parece que deveria ter funcionado e, na verdade, provavelmente funcionou, porque talvez o log de retransmissão original, antes da seção corrompida, já tivesse feito a inserção nessa posição de log mestre, mas não pudesse avançar o exibiu a posição mestre para o próximo ponteiro, uma vez que esse ponteiro está armazenado no log de retransmissão (que estava corrompido). Portanto, você pode ter pulado esse evento e movido para o próximo evento e, em seguida, verificando se o mestre e o escravo realmente tinham dados idênticos ... Ainda não tive a oportunidade de revisar a questão em detalhes suficientes.
Michael - sqlbot
11
Obrigado @ Michael-sqlbot, acho que, se esse problema ocorrer novamente, vou SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;pular um evento no escravo e espero que ajude - isso faz sentido? Se isso não ajudar (se ainda houver um erro de PK), importarei um dump --master-datanovamente.
KajMagnus

Respostas:

35

Erro: Last_SQL_Errno: 1594 Last_SQL_Error: Falha na leitura do log de retransmissão: Não foi possível analisar a entrada do evento do log de retransmissão.

Este erro significa que o arquivo de log principal está corrompido ou o arquivo de log de retransmissão está corrompido.

  • Antes de fazer qualquer coisa, faça backup de todos os seus bancos de dados, logs, servidores de imagem, repita várias vezes e continue por seu próprio risco.

Primeiro execute "show status do escravo \ G" no escravo e observe:

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

Primeiro, queremos ter certeza de que o arquivo de log mestre está intacto, então vá para o servidor mestre e encontre o Relay_Master_Log_File (verifique / var / log / mysql) e execute o seguinte comando:

mysqlbinlog mysql-bin.000026

O log será exibido, mas espero que você não veja nenhuma mensagem de erro. Se você vir mensagens de erro, os logs principais estão corrompidos e você provavelmente terá que criar uma nova imagem.

Em seguida, execute o mesmo comando no log de retransmissão escravo (geralmente em / var / lib / mysql)

mysqlbinlog mysqld-relay-bin.000056

Você provavelmente verá alguns erros mostrando a corrupção que interrompeu a replicação, assim:

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 houver algum erro, o log está correto no mestre e apenas o log de retransmissão do escravo está corrompido. Esta é uma boa notícia, podemos redefinir o escravo e contar os detalhes do mestre e de onde continuar. Se você não encontrar nenhum erro, pare de ler agora, você tem um problema diferente.

Se o log do relé escravo apresentar erros, execute os seguintes comandos para redefinir o escravo e os logs corrompidos reconectam-se ao mestre, obtenha os logs ok e comece a executar o slaving novamente. Observe que MASTER_LOG_POS é o Exec_Master_Log_Pos, e MASTER_LOG_FILE é o Relay_Master_Log_File( NÃO o primeiro, que corresponde aos logs de retransmissão que foram buscados e precisam ser jogados fora) ambos no primeiro 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)
A.Badger
fonte
2
Oi, obrigado pela sua resposta. Se você ler a pergunta com atenção, notará que ela diz "Log de retransmissão corrompido" - é porque já tínhamos usado mysqlbinlogda maneira sugerida e descobrimos que o log de retransmissão (e não o log mestre) estava corrompido. Concordando com a correção sugerida - se você ler a pergunta com atenção, perceberá que a correção sugerida é exatamente o que já tentamos. Mas isso não funcionou, e é disso que se trata. - Mas sua resposta pode ser útil para outras pessoas com um problema semelhante.
precisa saber é o seguinte
2
Provavelmente deve-se notar que MASTER_LOG_FILEin CHANGE MASTERdeve ser retirado Relay_Master_Log_Filee não de Master_Log_File. Geralmente eles serão os mesmos, mas pode não ser sempre o caso (consulte percona.com/blog/2008/07/07/… ).
brablc
@brablc está certo. Relay_Master_Log_Filedeve ser usado, não Master_Log_File. Veja também: percona.com/blog/2008/07/07/…
Mircea Vutcovici
na maioria dos casos, não há necessidade de reset slave allporque as configurações de mestre não precisa ser alterado (por exemplo MASTER_HOST, master_user, master_password), apenas MASTER_LOG_FILE e MASTER_LOG_POS, em seguida, um reset_slavedeve ser suficiente
ympostor
Esta pergunta e resposta já salvaram minha bunda várias vezes. Obrigado.
Artem Russakovskii
8

[Corrigindo a replicação do MySQL após o log de retransmissão dos escravos estar corrompido]

A replicação do MySQL no slave (versão 5.XX) parou. Slave_IO_Running foi marcado como Sim, mas Slave_SQL_Running como Não. O escravo simples de parar / iniciar não ajudou, sendo necessária uma análise mais aprofundada do problema. Parecia que o log de retransmissão do escravo atual estava corrompido porque o teste com o “mysqlbinlog” imprimiu um erro. Portanto, a solução foi descartar os binlogs de retransmissão atuais e apontar o slave para a última posição do binlog mestre.

Para corrigir o erro, os arquivos binlog atuais no escravo devem ser descartados e definir uma nova posição. Antes de definir a nova posição no binlog , é importante lembrar os valores Relay_Master_Log_File e Exec_Master_Log_Pos do servidor escravo corrompido usando o comando SHOW SLAVE STATUS \ G :

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

OK, com esses valores, a nova posição do binlog pode ser definida:

# 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;

Só para nota que reset slavevai apagar master.info, relay-log.infoe todos os arquivos de log de retransmissão, por isso não é necessário para sobras limpas no /var/lib/mysqldiretório.

Mohamed Ayas
fonte
11
Boa resposta - geralmente não precisamos alterar o host principal, a senha etc. Thx!
andy250 27/02
3

Sei que já faz mais de um ano, mas aqui está o que pode ter acontecido com esse problema em particular.

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;

Parece que isso deveria ter sido corrigido porque removeu o log de retransmissão corrompido.

Então, você tem um erro PK 1062. Por que?

Existe um erro pendente ( http://bugs.mysql.com/bug.php?id=60847 ) que ainda está ativo no MySQL 5.5

Embora o erro esteja relacionado ao uso do mysql - única transação - - flush-logs, existe uma peculiaridade relacionada.

Eu vi essa peculiaridade em alguns servidores EC2 sendo executados como escravos para um cliente na semana passada no MySQL 5.5.15

No Master, havia um estranho INSERT estendido de várias linhas, onde cada tupla inserida era um SELECT. O que aconteceu foi que o LAST_INSERT_ID no log de retransmissão, que forma o próximo incremento automático a ser atribuído, já estava sendo usado no Slave por causa de inserções de várias linhas anteriormente.

O INSERT serializado no log de retransmissão parecia

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

A lista de colunas não incluiu a chave primária numérica. Quando o erro 1062 voltasse, eu usaria a mesma consulta em que falhou, execute a consulta manualmente. Não atingiu o erro 1062. Em seguida, executei os comandos skip slave comuns:

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

Em seguida, a replicação alcançou.

Meu conselho seria serializar corretamente seus INSERTs no Master, porque essa situação semelhante a um bug é realmente bastante evitável.

RolandoMySQLDBA
fonte
1

Você fez tudo certo (como já foi dito).

O único problema é com o arquivo master.info (contém informações sobre a posição no mysql-bin.log do mestre), porque esse arquivo não é sincronizado com o disco após o processamento de cada consulta.

Portanto, suas informações sobre posições no registro mestre estão desatualizadas e você está processando consultas já processadas que precisam ser ignoradas SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;.

Infelizmente, se você usar algumas consultas como UPDATE table SET counter=counter+1 WHERE id = 12345e usar binlog_format=STATEMENTseus bancos de dados pode ficar fora de sincronia, eu acho.

Você pode dizer ao servidor MySQL para sincronizar master.info após cada evento, configurando a variável sync_master_info, mas provavelmente terá enormes conseqüências de desempenho.

Dragonn
fonte