Ist es in Ordnung, die mysql-Datenbank zu replizieren?

15

Als ich meine Master-to-Master-Replikation ursprünglich eingerichtet habe, habe ich Folgendes verwendet:

binlog-ignore-db=mysql

und haben die Benutzerkonten und Berechtigungen manuell synchronisiert. Dies ist einfach so, wie es in der Anleitung gemacht wurde, die ich zu der Zeit benutzte . Aber gibt es einen Grund, warum ich diese Zeile nicht entfernen und die mysqlDatenbank selbst auch replizieren lassen sollte?

Wenn ja: Bevor ich die Änderung vornehme, sollte ich nicht nur sicherstellen, dass alle Berechtigungen für beide gleich sind (oder besser gesagt, dass die gesamte MySQL-Datenbank identisch ist), sondern auch noch etwas überprüfen oder beachten?

dlo
quelle
In den letzten 4,5 Jahren hatte ich beim Upgrade von MySQL ständig mit Replikationsproblemen zu kämpfen, auch bei kleineren Upgrades. Der Grund dafür ist, dass apt-get upgrade(eigentlich das mysql-server .deb postinst-Skript) ALTER TABLE userAnweisungen ausführt , die nicht repliziert werden können. Ich habe eine funktionierende Lösung unter serverfault.com/questions/686025/…
dlo

Antworten:

12

Es ist durchaus möglich, sich selbst MySQL-Berechtigungen zu geben, ohne die SQL GRANT-Befehle zu kennen .

Beispiel: Hier ist das Erstellen eines eigenen Benutzers mit vollständigen Rechten unter Verwendung von SQL GRANT von einem beliebigen Ort mit dem Namen superdba und dem Kennwort ClarkKent:

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

So können Sie dies ohne den Befehl GRANT ausführen:

Hier ist zunächst mysql.user für 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)

Führen Sie einfach diese SQL-Befehle aus:

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;

Diese INSERT-Anweisung ist eine zulässige SQL-Anweisung, die in einem Binärprotokoll landen kann. Möchten Sie, dass jemand diese Funktion ausführt und ein sichtbares Kennwort im Netzwerk verwendet? in einem binären Protokoll auf dem Master sitzen? in einem Relais-Log auf dem Slave sitzen?

Mit dieser Richtlinie

binlog-ignore-db=mysql       

verhindert die Weitergabe von MySQL-Berechtigungen mit solchen SQL. GRANTs können jedoch nicht auf diese Weise gestoppt werden. Stellen Sie daher sicher, dass Sie Zuschüsse wie folgt durchführen:

SET SQL_LOG_BIN=0;
GRANT ...

um zu verhindern, dass die GRANTs von Master zu Slave gelangen.

RolandoMySQLDBA
quelle
Oh, warte ... Ich bin verwirrt: Wollen Sie damit sagen, dass GRANT-Anweisungen replizieren, egal was die binlog-ignore-db conf sagt? Ich weiß, dass ein neuer Benutzer auf einem Server nicht auf dem anderen angezeigt wird. Vielleicht meinst du also, dass der GRANT übertragen und gespeichert wird, aber einfach nicht auf den Slave angewendet wird ?
12.
GRANTS werden ohne Straßensperren beantragt. Aus diesem Grund müssen Sie SET SQL_LOG_BIN = 0 ausführen. in der Mysql-Sitzung, um zu verhindern, dass GRANT-Befehle in die Binärprotokolle gelangen.
RolandoMySQLDBA
GRANTS werden ohne Straßensperren auf Master und Slave angewendet. Aus diesem Grund müssen Sie SET SQL_LOG_BIN = 0 ausführen. in der Mysql-Sitzung, um zu verhindern, dass GRANT-Befehle in die Binärprotokolle eintreten und zu den Relay-Protokollen des Slaves übergehen.
RolandoMySQLDBA
1
In Ordnung. Um für andere klar zu sein, ich glaube, Sie warnen mich davor, dass GRANTS Passwörter während der Übertragung (die mit dem SSL-Vorschlag von Scott adressiert werden können) offenlegt und Klartext im Binlog speichert. Sie schlagen vor, dass ich, wenn dies für mich von Belang ist, sowohl binlog-ignore-db = mysql als auch SET SQL_LOG_BIN = 0; verwenden sollte. Aber wenn ich mit diesen Bedingungen einverstanden bin, gibt es kein besonderes Problem beim Replizieren von GRANTs, indem die Zeile binlog-ignore-db entfernt wird. Korrigieren Sie mich, wenn dies eine ungenaue Zusammenfassung ist.
12.
@dlo - Bejahend !!!
RolandoMySQLDBA
4

Ich hatte keine Probleme mit der Replikation der MySQL-Datenbank, aber andererseits verleiht meine Infrastruktur mit Firewalls und Proxy-Appliances eine zusätzliche Sicherheitsstufe, bei der es nur den Infrastruktur-Leuten möglich ist, eine Verbindung über einen der von MySQL verwendeten Ports herzustellen . Dies erhöht die Benutzerfreundlichkeit, da Sie Berechtigungen nur einmal erteilen und sie replizieren müssen. Wenn es darauf ankommt, sollte es Ihnen gut gehen, solange Sie den Host so eingestellt haben, dass er niemand anderem als dem beabsichtigten (z. B. Ihnen, dem Sklaven usw.) ausgesetzt wird.

Wenn Sie sich zu sehr mit Menschen in der Mitte des Abhörens beschäftigen, besteht immer die Möglichkeit, Replikationen über SSL zu senden .

Scott
quelle