Problemas de replicação do MySQL após uma queda de energia

6

Após uma queda de energia em nosso data center, os bancos de dados MySQL escravos estão com dificuldades.

Isso está nos registros de um dos escravos:

100118 10:05:56 [Note] Slave I/O thread: connected to master 'repl@db1:3306',  replication started in log 'bin-log.004712' at position 724207814
100118 10:05:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)
100118 10:05:56 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log
100118 10:05:56 [Note] Slave I/O thread exiting, read up to log 'bin-log.004712', position 724207814

E o console mostra um pouco mais de detalhes:

mysql> show slave status \G;
*************************** 1. row ***************************
             Slave_IO_State:
                Master_Host: db1
                Master_User: repl
                Master_Port: 3306
              Connect_Retry: 10
            Master_Log_File: bin-log.004712
        Read_Master_Log_Pos: 724207814
             Relay_Log_File: mysqld-relay-bin.000105
              Relay_Log_Pos: 98
      Relay_Master_Log_File: bin-log.004712
           Slave_IO_Running: No
          Slave_SQL_Running: Yes
            Replicate_Do_DB: mmplive1,mmpjcr,fui
        Replicate_Ignore_DB:
         Replicate_Do_Table:
     Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                 Last_Errno: 0
                 Last_Error:
               Skip_Counter: 0
        Exec_Master_Log_Pos: 724207814
            Relay_Log_Space: 98
            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
1 row in set (0.00 sec)

ERROR:
No query specified

Olhando para os registros da lixeira no mestre, temos:

-rw-rw---- 1 mysql mysql  724200412 Jan 18 09:22 bin-log.004712
-rw-rw---- 1 mysql mysql       1904 Jan 18 09:27 bin-log.index
-rw-rw---- 1 mysql mysql    5046830 Jan 18 11:22 slow-log
-rw-rw---- 1 mysql mysql  198249613 Jan 18 11:24 bin-log.004713
  1. O status Escravo mostra que o Exec_Master_Log_Pos e o Read_Master_Log_Pos são ambos 724207814, para o log binário bin-log.004712. No meu entender, esse valor é a posição do byte no arquivo de log binário.
  2. Esse arquivo bin-log.004712 é de apenas 724200412 bytes, então os escravos acham que fizeram mais 7402 bytes de trabalho do que realmente foi persistido no arquivo (que está em um ext3 fs, RAID-10, RHEL5) . Daí a mensagem de erro sobre a posição de log impossível, etc.

Qual é a melhor maneira de consertar os escravos?

Opções que estou considerando:

  1. Configurando cada escravo para apontar para a posição 0 no próximo arquivo bin-log (bin-log.004713) e deixá-los ir, mas não tenho certeza de como isso é seguro, ou da quantidade de dados que podem ser perdidos. / li>
  2. Em vez disso, eu preciso fazer um backup completo e restaurar (com tempo de inatividade associado presumido devido a bloqueios de tabela nas tabelas InnoDB)? Eu gostaria de evitar isso, se possível.

ATUALIZAÇÃO:

Eu perdi outra opção: apontar um pouco a posição de cada escravo de volta, para que ele tentasse replicar comandos que já haviam sido processados a partir do bin-log.004712.

    
por jabley 18.01.2010 / 12:35

2 respostas

2

Eu fui para a primeira opção.

Isso funcionou até o ponto em que o escravo começou a tentar fazer inserções que conflitavam com as chaves primárias. O escravo tinha feito mais trabalho do que o bin-log mestre persistiu, como mencionado anteriormente. Um aspecto que eu não previ era que o escravo continha dados que não estavam no mestre; Ou seja, o escravo persistiu algumas transações antes da queda de energia que o mestre HAD NOT persistiu.

Como no meu caso, essas transações não eram relacionadas a pagamento ou similares, optei por excluir os dados do escravo (perdendo alguns dados que haviam acontecido, mas que não existiam no mestre) e depois deixar replicação executar novamente. Isso trouxe os escravos completamente atualizados. Se os dados tivessem sido mais importantes, teríamos compensações de incremento automático suficientes para nos dar algum espaço de manobra para manipular manualmente os dados e garantir que a integridade referencial não fosse comprometida. Felizmente não precisávamos fazer isso neste caso.

Para uma máquina em configuração mestre-mestre (passiva) que estava nessa situação, optei por uma abordagem semelhante. Por mestre-mestre passivo, quero dizer que temos um mestre ativo (serverA) que é onde todas as gravações vão, e um mestre passivo (serverB) que está no lugar para permitir que as atualizações de esquema ocorram com tempo de inatividade zero. Os dados no mestre ativo (serverA) foram escolhidos como os valores verdadeiros, apesar de saber que isso significava que perdíamos algumas transações persistentes que não eram consideradas importantes.

  • Alterou o arquivo de log e a posição no escravo.

    CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB
    
  • Reinicialização de escravo reinicializado no mestre passivo (serverB) até que ele falhou com violações de restrição de chave primária, como acontece com os outros escravos.

     START SLAVE; -- on serverB
    
  • Parou a replicação de escravo do mestre passivo (serverB) para o mestre ativo (serverA).

    STOP SLAVE; -- on serverA
    
  • DELETE as linhas no slave (serverB) que não existiam no master no serverA.

    DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
    SHOW MASTER STATUS\G; -- get the new master log position on serverB
    
  • Mova a posição de execução do escravo mestre ativo (serverA) para pular as exclusões do mestre passivo (serverB).

    CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB
    
  • Reinicie a replicação no mestre ativo (serverA) e no mestre passivo.

    START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up.
    
por 19.01.2010 / 14:33
0

Dependeria de como é importante que o escravo seja réplicas exatas do mestre. Você é a primeira opção que vai funcionar até certo ponto, mas os escravos poderiam muito bem estar perdendo informações do mestre. Se você pode viver com isso porque os dados são transitórios ou algo assim, vá em frente. Se é importante que os escravos sejam réplicas adequadas, a segunda opção é provavelmente sua única opção. Infelizmente a replicação do MySQL não aceita gentilmente qualquer tipo de interrupção inesperada, eu acho que esses tipos de problemas são muito mais frequentes do que eu gostaria em minha arquitetura de replicação.

    
por 18.01.2010 / 15:15