¿Cómo puede evitar que el esclavo MySQL repita los cambios en la base de datos 'mysql'?

9

Tengo mi esclavo configurado para no replicar la base de datos 'mysql' como se describe en este SHOW SLAVE STATUS\G;

           Slave_IO_State: Waiting for master to send event
              Master_Host: 127.0.0.1
              Master_User: replication
              Master_Port: 3306
            Connect_Retry: 60
          Master_Log_File: master-bin.000001
      Read_Master_Log_Pos: 1660
           Relay_Log_File: mysql-relay-bin.000004
            Relay_Log_Pos: 478
    Relay_Master_Log_File: master-bin.000001
         Slave_IO_Running: Yes
        Slave_SQL_Running: Yes
          Replicate_Do_DB: 
      **Replicate_Ignore_DB: mysql**
       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: 1660
          Relay_Log_Space: 633
          Until_Condition: None
           Until_Log_File: 
            Until_Log_Pos: 0

Ahora, si voy al servidor MASTER y emito un GRANTy FLUSH PRIVILEGES:

GRANT SELECT ON *.* TO `foo`@`localhost` IDENTIFIED BY 'bar';
FLUSH PRIVILEGES;

Luego vuelvo al servidor SLAVE y emito:

SHOW GRANTS FOR `foo`@`localhost`;

y recibe la respuesta:

+-------------------------------------------------------------------------------------------------------------+
| Grants for foo@localhost                                                                                    |
+-------------------------------------------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO 'foo'@'localhost' IDENTIFIED BY PASSWORD '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB' |
+-------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

¿Cómo puedo evitar que el esclavo repita los cambios en la base de datos mysql? Pensé que 'replicate_ignore_db' habría sido suficiente.

Derek Downey
fuente

Respuestas:

8

Muy bien, después de unas horas más de investigación, creo que lo descubrí. Agregar mi respuesta en caso de que esto sea útil para otros.

De acuerdo con los documentos en replicate-ignore-db :

Replicación basada en declaraciones. Le dice al subproceso SQL esclavo que no repita ninguna declaración donde la base de datos predeterminada (es decir, la seleccionada por USE) es db_name.

Por supuesto, la replicación basada en declaraciones es el valor predeterminado y lo que estaba usando. Así que intenté cambiar el formato reiniciando el master con binlog_format=rowpara ver qué pasaría. No dados. SUBVENCIONES y REVOCACIONES todavía fueron replicadas.

Más investigación sobre los documentos sobre los cambios de replicación en la tabla mysql reveló

Las declaraciones que cambian la base de datos mysql indirectamente se registran como declaraciones independientemente del valor de binlog_format. Esto se refiere a declaraciones como GRANT, REVOKE, SET PASSWORD, RENAME USER, CREATE (todas las formas excepto CREATE TABLE ... SELECT), ALTER (todas las formas) y DROP (todas las formas).

Gah! Ok, entonces revisé el binlog usando mysqlbinlogy mi GRANTdeclaración no emitía una USE mysqlllamada a la base de datos (¿por qué debería hacerlo?). Por replicate-ignore-dblo tanto , no podría ignorar en buena conciencia la declaración.

Mi solución fue eliminar completamente los cambios en la tabla mysql del registro binario agregando binlog-ignore-db=mysqla my.cnf y reiniciar el servidor. Trabajado como un encanto.

Derek Downey
fuente
Estudie cuidadosamente el algoritmo si tiene ambas _do_y _ignore_cláusulas. Se pone complicado.
Rick James
4

El problema con la respuesta de Derek Downey en esta publicación es que siempre funcionará de la misma manera (activado o desactivado).

Si se encuentra en una situación en la que desea que se repitan la mayoría de las subvenciones, pero no esta, o si no desea devolver mysql (necesario para cargar el archivo my.conf modificado), puede hacerlo de esta manera:

SET session sql_log_bin = 0;

GRANT SELECT ON *.* TO `foo`@`localhost` IDENTIFIED BY 'bar';

SET session sql_log_bin = 1;

Recuerde que la configuración de la última línea sql_log_bin = 1es muy importante porque sin ella no replicará nada.

usuario13170
fuente
2
al hacer referencia a otras respuestas, debe hacer referencia al nombre del usuario que agregó la respuesta en lugar de "la respuesta anterior". El orden de las respuestas cambia a medida que las respuestas se votan arriba y abajo, etc.
Max Vernon