Comment pouvez-vous empêcher l'esclave MySQL de répliquer les modifications apportées à la base de données 'mysql'?

9

J'ai mon esclave configuré pour ne pas répliquer la base de données 'mysql' comme décrit dans ce 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

Maintenant, si je vais sur le serveur MASTER et émets un GRANTet FLUSH PRIVILEGES:

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

Je retourne ensuite au serveur SLAVE et émets:

SHOW GRANTS FOR `foo`@`localhost`;

et recevez la réponse:

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

Comment puis-je empêcher l'esclave de répliquer les modifications de la base de données mysql? J'ai pensé que 'replicate_ignore_db' aurait suffi.

Derek Downey
la source

Réponses:

8

D'accord, après quelques heures de recherche supplémentaires, je pense que je l'ai compris. Ajout de ma réponse au cas où cela serait utile à d'autres.

Selon les documents sur replicate-ignore-db :

Réplication basée sur des instructions. Indique au thread SQL esclave de ne répliquer aucune instruction dans laquelle la base de données par défaut (c'est-à-dire celle sélectionnée par USE) est db_name.

Bien sûr, la réplication basée sur les instructions est la valeur par défaut et ce que j'utilisais. J'ai donc tenté de changer le format en redémarrant le master avec binlog_format=rowpour voir ce qui allait se passer. Pas de dé. Les SUBVENTIONS et RÉVOCATIONS étaient toujours reproduites.

Une enquête plus approfondie sur les documents sur les changements de réplication sur la table mysql a révélé

Les instructions qui modifient indirectement la base de données mysql sont enregistrées en tant qu'instructions, quelle que soit la valeur de binlog_format. Cela concerne les instructions telles que GRANT, REVOKE, SET PASSWORD, RENAME USER, CREATE (tous les formulaires sauf CREATE TABLE ... SELECT), ALTER (tous les formulaires) et DROP (tous les formulaires).

Gah! Ok, j'ai donc vérifié le binlog à l'aide mysqlbinloget ma GRANTdéclaration n'émettait pas d' USE mysqlappel de base de données (pourquoi devrait-il le faire?). Donc, replicate-ignore-dbne pouvait pas en toute conscience ignorer la déclaration.

Ma solution a été de supprimer complètement les modifications apportées à la table mysql du journal binaire en ajoutant binlog-ignore-db=mysqlà my.cnf et en redémarrant le serveur. A fonctionné comme un charme.

Derek Downey
la source
Étudiez attentivement l'algorithme si vous avez les deux clauses _do_et _ignore_. Cela devient difficile.
Rick James
4

Le problème avec la réponse de Derek Downey sur ce post est qu'il fonctionnera toujours de la même manière (on ou off).

Si vous êtes dans une situation où vous souhaitez que la plupart des subventions soient répliquées mais pas celle-ci - ou si vous ne voulez pas rebondir mysql (nécessaire pour charger le fichier my.conf modifié), vous pouvez le faire de cette façon:

SET session sql_log_bin = 0;

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

SET session sql_log_bin = 1;

N'oubliez pas que ce paramètre de dernière ligne sql_log_bin = 1est très important car sans lui, vous ne reproduirez rien.

user13170
la source
2
lorsque vous référencez d'autres réponses, vous devez faire référence par le nom de l'utilisateur qui a ajouté la réponse au lieu de "la réponse ci-dessus". L'ordre des réponses change à mesure que les réponses sont votées de haut en bas, etc.
Max Vernon