Problemas de replicación de MySQL después de un corte de energía

Problemas de replicación de MySQL después de un corte de energía

Después de un corte de energía en nuestro centro de datos, las bases de datos MySQL esclavas tienen problemas.

Esto está en los registros de uno de los esclavos:

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

Y la consola muestra un poco más de detalle:

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

Mirando los registros del contenedor en el maestro, tenemos:

-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. El estado de esclavo muestra que Exec_Master_Log_Pos y Read_Master_Log_Pos son ambos 724207814, para el registro binario bin-log.004712. Tengo entendido que este valor es la posición del byte en el archivo de registro binario.
  2. Ese archivo bin-log.004712 tiene solo 724200412 bytes, por lo que los esclavos piensan que han realizado 7402 bytes más de trabajo del que realmente se ha conservado en el archivo (que está en un ext3 fs, RAID-10, RHEL5). De ahí el mensaje de error sobre la posición imposible del registro, etc.

¿Cuál es la mejor manera de arreglar a los esclavos?

Opciones que estoy considerando:

  1. Configurar cada esclavo para que apunte a la posición 0 en el siguiente archivo bin-log (bin-log.004713) y dejarlos ir, pero no estoy seguro de qué tan seguro es o de cuántos datos podrían perderse.
  2. ¿Debo, en cambio, hacer una copia de seguridad completa y una restauración (con un presunto tiempo de inactividad asociado debido a bloqueos de tablas en las tablas InnoDB)? Me gustaría evitar eso si es posible.

ACTUALIZAR:

Me perdí otra opción: apuntar un poco hacia atrás cada posición ejecutada por esclavo, para que intentara replicar los comandos que ya había procesado desde bin-log.004712.

Respuesta1

Fui por la primera opción.

Eso funcionó hasta el punto en que el esclavo comenzó a intentar realizar inserciones que entraban en conflicto con las claves principales. El esclavo había hecho más trabajo del que el maestro bin-log había persistido, como se mencionó anteriormente. Un aspecto que no anticipé fue que el esclavo contenía datos que no estaban en el maestro; es decir, el esclavo persistió en algunas transacciones antes del corte de energía que el maestroNO HApersistió.

Dado que, en mi caso, estas transacciones no estaban relacionadas con pagos o similares, elegí eliminar los datos del esclavo (perdiendo así algunos datos que habían sucedido, pero que no existían en el maestro) y luego dejé que la replicación se ejecutara nuevamente. . Esto actualizó por completo a los esclavos. Si los datos hubieran sido más importantes, tenemos compensaciones de incremento automático suficientes para darnos cierto margen de maniobra para manipular manualmente los datos y garantizar que la integridad referencial no se vea comprometida. Afortunadamente, no necesitábamos hacer eso en este caso.

Para una máquina en configuración maestro-maestro (pasiva) que se encontraba en esta situación, elegí un enfoque similar. Por maestro-maestro pasivo, quiero decir que tenemos un maestro activo (servidorA) que es donde van todas las escrituras, y un maestro pasivo (servidorB) que está implementado para permitir que se realicen actualizaciones del esquema sin tiempo de inactividad. Los datos en el maestro activo (servidorA) se eligieron como valores verdaderos, a pesar de saber que esto significaba que perdimos un par de transacciones persistentes que no se consideraron importantes.

  • Se modificó el archivo de registro y la posición en el esclavo.

    CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB
    
  • Se reinició la replicación de esclavos en el maestro pasivo (servidorB) hasta que falló con violaciones de restricciones de clave primaria, al igual que con los otros esclavos.

     START SLAVE; -- on serverB
    
  • Se detuvo la replicación de esclavos desde el maestro pasivo (servidorB) al maestro activo (servidorA).

    STOP SLAVE; -- on serverA
    
  • BORRAR las filas en el esclavo (servidorB) que no existían en el maestro en el servidorA.

    DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
    SHOW MASTER STATUS\G; -- get the new master log position on serverB
    
  • Mueva la posición ejecutiva del esclavo maestro activo (servidorA) para omitir esas eliminaciones del maestro pasivo (servidorB).

    CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB
    
  • Reinicie la replicación tanto en el maestro activo (servidorA) como en el maestro pasivo.

    START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up.
    

Respuesta2

Dependería de lo importante que sea que el esclavo sea réplica exacta del maestro. Su primera opción funcionará hasta cierto punto, pero es muy posible que a los esclavos les falte información del maestro. Si puedes vivir con eso porque los datos son transitorios o algo así, entonces hazlo. Si es importante que los esclavos sean réplicas adecuadas, entonces la segunda opción es probablemente su única opción. Desafortunadamente, la replicación de MySQL no acepta ningún tipo de interrupción inesperada. He descubierto que este tipo de problemas son mucho más frecuentes de lo que me gustaría en mi arquitectura de replicación.

información relacionada