Wie können Sie verhindern, dass MySQL-Slave Änderungen an der 'mysql'-Datenbank repliziert?

9

Ich habe meinen Slave so eingestellt, dass er die 'mysql'-Datenbank nicht wie hier beschrieben repliziert 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

Wenn ich jetzt zum MASTER- Server gehe und ein GRANTund ausstelle FLUSH PRIVILEGES:

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

Ich gehe dann zurück zum SLAVE- Server und stelle Folgendes aus :

SHOW GRANTS FOR `foo`@`localhost`;

und erhalten Sie die Antwort:

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

Wie kann ich verhindern, dass der Slave Änderungen an der MySQL-Datenbank repliziert? Ich dachte, 'replicate_ignore_db' hätte ausgereicht.

Derek Downey
quelle

Antworten:

8

Okay, nach ein paar Stunden Nachforschungen denke ich, ich habe es herausgefunden. Hinzufügen meiner Antwort für den Fall, dass dies für andere von Nutzen ist.

Laut den Dokumenten zu replicate-ignore-db :

Anweisungsbasierte Replikation. Weist den Slave-SQL-Thread an, keine Anweisung zu replizieren, bei der die Standarddatenbank (dh die von USE ausgewählte) db_name ist.

Natürlich ist die anweisungsbasierte Replikation die Standardeinstellung und das, was ich verwendet habe. Also habe ich versucht, das Format zu ändern, indem ich den Master mit neu gestartet habe, um binlog_format=rowzu sehen, was passieren würde. Kein Würfel. Zuschüsse und Widerrufe wurden noch repliziert.

Weitere Untersuchungen in den Dokumenten zu Replikationsänderungen in der MySQL-Tabelle ergaben

Anweisungen, die die MySQL-Datenbank indirekt ändern, werden unabhängig vom Wert von binlog_format als Anweisungen protokolliert. Dies betrifft Anweisungen wie GRANT, REVOKE, SET PASSWORD, RENAME USER, CREATE (alle Formulare außer CREATE TABLE ... SELECT), ALTER (alle Formulare) und DROP (alle Formulare).

Gah! Ok, also habe ich das Binlog mit überprüft mysqlbinlogund meine GRANTAnweisung hat keinen USE mysqlDatenbankaufruf ausgegeben (warum sollte es?). So replicate-ignore-dbkonnte man die Aussage nicht guten Gewissens ignorieren.

Meine Lösung bestand darin, die Änderungen an der MySQL- Tabelle vollständig aus dem Binärprotokoll herauszuschneiden, indem ich sie binlog-ignore-db=mysqlzu my.cnf hinzufügte und den Server neu startete. Lief wie am Schnürchen.

Derek Downey
quelle
Studieren Sie den Algorithmus sorgfältig, wenn Sie beide _do_und _ignore_Klauseln haben. Es wird schwierig.
Rick James
4

Das Problem mit Derek Downeys Antwort auf diesen Beitrag ist, dass es immer auf die gleiche Weise funktioniert (ein oder aus).

Wenn Sie sich in einer Situation befinden, in der die meisten Zuschüsse repliziert werden sollen, diese jedoch nicht - oder wenn Sie MySQL nicht abrufen möchten (erforderlich zum Laden der geänderten Datei my.conf), können Sie dies folgendermaßen tun:

SET session sql_log_bin = 0;

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

SET session sql_log_bin = 1;

Bitte denken Sie daran - dass die Einstellung der letzten Zeile sql_log_bin = 1sehr wichtig ist, da Sie ohne sie nichts replizieren werden.

user13170
quelle
2
Wenn Sie auf andere Antworten verweisen, sollten Sie auf den Namen des Benutzers verweisen, der die Antwort hinzugefügt hat, anstatt auf "die Antwort oben". Die Reihenfolge der Antworten ändert sich, wenn die Antworten nach oben und unten abgestimmt werden usw.
Max Vernon