Est-il correct de répliquer la base de données `mysql`?

15

Lorsque j'ai initialement configuré ma réplication de maître à maître, j'ai utilisé:

binlog-ignore-db=mysql

et ont synchronisé les comptes d'utilisateurs et les octrois manuellement. C'est simplement comment cela a été fait dans le mode d'emploi que j'utilisais à l'époque. Mais y a-t-il une raison pour laquelle je ne devrais pas supprimer cette ligne et permettre à la mysqlbase de données de se répliquer également?

Si oui: avant de faire le changement, en plus de vous assurer que toutes les subventions sont les mêmes sur les deux (ou mieux, que la base de données mysql entière est identique), y a-t-il autre chose que je devrais vérifier ou être au courant?

dlo
la source
Au cours des 4,5 dernières années, j'ai constamment eu des problèmes de réplication lors de la mise à niveau de mysql, même sur des mises à niveau mineures. La raison en est que apt-get upgrade(en fait, le script postinst de mysql-server .deb) exécute des ALTER TABLE userinstructions qui ne peuvent pas être répliquées. J'ai posté une solution de travail sur serverfault.com/questions/686025/…
dlo

Réponses:

12

Il est tout à fait possible de vous accorder des autorisations mysql sans connaître les commandes SQL GRANT .

Exemple: voici pour créer votre propre utilisateur avec des privilèges complets en utilisant SQL GRANT de n'importe où appelé superdba avec un mot de passe de ClarkKent:

GRANT ALL PRIVILEGES ON *.* TO superdba@'%' IDENTIFIED BY 'ClarkKent' WITH GRANT OPTION; 

Voici comment procéder sans la commande GRANT:

Tout d'abord, voici mysql.user pour MySQL 5.1.51

mysql> desc mysql.user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
39 rows in set (0.00 sec)

Exécutez simplement ces commandes SQL:

INSERT INTO mysql.user SET
Host='%',User='superdba',Password=PASSWORD('ClarkKent'),
Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',
Create_priv='Y',Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',
Process_priv='Y',File_priv='Y',Grant_priv='Y',References_priv='Y',
Index_priv='Y',Alter_priv='Y',Show_db_priv='Y',Super_priv='Y',
Create_tmp_table_priv='Y',Lock_tables_priv='Y',Execute_priv='Y',
Repl_slave_priv='Y',Repl_client_priv='Y',Create_view_priv='Y',
Show_view_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y',
Create_user_priv='Y',Event_priv='Y',Trigger_priv='Y';
FLUSH PRIVILEGES;

Cet INSERT est une instruction SQL légale qui peut atterrir dans un journal binaire. Voulez-vous que quelqu'un exécute cela et ait un mot de passe visible sur le réseau? s'asseoir dans un journal binaire sur le maître? s'asseoir dans un journal de relais sur l'esclave?

Avoir cette directive

binlog-ignore-db=mysql       

empêche de donner des autorisations mysql en utilisant un tel SQL. Cependant, les subventions ne peuvent pas être arrêtées de cette façon. Par conséquent, assurez-vous d'effectuer des subventions comme celle-ci:

SET SQL_LOG_BIN=0;
GRANT ...

pour empêcher les GRANT de passer du maître à l'esclave.

RolandoMySQLDBA
la source
Oh, attendez ... Je suis confus: Êtes-vous en train de dire que les instructions GRANT se répliquent, peu importe ce que dit la conf binlog-ignore-db? Je sais que si je crée un nouvel utilisateur sur un serveur, cet utilisateur n'apparaît pas sur l'autre. Alors peut-être que vous voulez dire que le GRANT est transmis et stocké mais simplement pas appliqué sur l'esclave?
dlo
LES SUBVENTIONS sont appliquées sans aucun obstacle. C'est pourquoi vous devez exécuter SET SQL_LOG_BIN = 0; dans la session mysql pour empêcher toute commande GRANT d'entrer dans les journaux binaires.
RolandoMySQLDBA
Les subventions sont appliquées sans aucun obstacle sur le maître et l'esclave. C'est pourquoi vous devez exécuter SET SQL_LOG_BIN = 0; dans la session mysql pour empêcher toute commande GRANT d'entrer dans les journaux binaires et de parcourir les journaux de relais de l'esclave.
RolandoMySQLDBA
1
D'accord. Juste pour être clair pour les autres, je pense que vous m'avertissez que GRANT expose des mots de passe en transit (qui peuvent être traités avec la suggestion SSL de Scott) et est stocké en texte clair dans le binlog. Vous suggérez que si cela me préoccupe, je devrais utiliser à la fois binlog-ignore-db = mysql et SET SQL_LOG_BIN = 0 ;. Mais si je suis d'accord avec ces conditions, il n'y a pas de problème particulier avec la réplication de GRANT en supprimant la ligne binlog-ignore-db. Corrigez-moi s'il s'agit d'un résumé inexact.
dlo
@dlo - Affirmatif !!!
RolandoMySQLDBA
4

Je n'ai eu aucun problème à répliquer la base de données mysql, mais là encore, mon infrastructure offre un niveau de sécurité supplémentaire avec des pare-feu et des appliances proxy où il est impossible pour quiconque autre que les gens de l'infrastructure de se connecter même sur l'un des ports utilisés par MySQL . Il ajoute un niveau de commodité supplémentaire sachant que vous ne devez accorder des autorisations qu'une seule fois et le faire répliquer. Quand cela se résume à cela, tant que vous avez correctement configuré l'hôte pour ne pas l'exposer à quelqu'un d'autre que celui prévu (par exemple, vous, l'esclave, etc.), tout va bien.

Si vous êtes trop préoccupé par l'homme au milieu des interceptions, il y a toujours la possibilité d'envoyer une réplication via SSL .

Scott
la source