Table of Contents
Ziel
Dieser Blogeintrag beschäftigt sich mit den Replikationsfunktionen eines MySQL Servers. Es wird gezeigt wie eine asynchrone Replikation zwischen zwei MySQL Server eingerichtet werden kann. Der Datenbankserver, dessen Daten repliziert werden sollen, wird als MASTER bezeichnet. Der Datenbankserver, der das Ziel der Replikation darstellt, wird als SLAVE bezeichnet. Es besteht die Möglichkeit mehrere SLAVES zu besitzen, auch eine Verkettung, das heißt das ein SLAVE als MASTER für einen weiteren SLAVE dient, ist möglich.
Vorausetzungen
Ich verwende in diesem Tutorial zwei virtuelle Server (verwendet wird VirtualBox), auf denen jeweils CentOS 5.6 in der 64-bit Version installiert ist.
Name | Beschreibung | MySQL Replikation | MySQL Server ID |
ifrit | Host der Produktivdatenbank | MASTER | 1 |
shiva | Ziel der Replikation | SLAVE | 2 |
Der MySQL Server wurde mithilfe des REMI Repsitories installiert und liegt in der folgenden Version vor.
mysql> select @@version AS VERSION, @@version_compile_machine AS ARCHITECTURE; +------------+--------------+ | VERSION | ARCHITECTURE | +------------+--------------+ | 5.5.13-log | x86_64 | +------------+--------------+
Die MySQL Server Installation wurde mit dem Skript /usr/bin/mysql_secure_installation abgesichert. Dieses Skript sorgt zum Beispiel dafür, dass ein root Passwort gesetzt wird, oder das der Anonyme Zugriff gesperrt wird.
Anlegen der Beispieldatenbank SAKILA
Dieses Tutorial simuliert die Konfiguration der Replikation mit einer bestehenden “Produktivdatenbank”. Als Produktivdatenbank wird die Beispieldatenbank SAKILA verwendet, die hier heruntergeladen werden kann.
[root@ifrit ~]# cd /tmp [root@ifrit tmp]# wget http://downloads.mysql.com/docs/sakila-db.zip [root@ifrit tmp]# unzip sakila-db.zip [root@ifrit tmp]# cd sakila-db
Nachdem entpacken meldet man sich am MySQL Server mit dem Benutzer root an und führt die beiden SQL Skripte aus, die zuerst die Datenbankstruktur anlegen und dann die Daten importieren.
[root@ifrit sakila-db]# mysql -u root -p mysql> SOURCE /tmp/sakila-db/sakila-schema.sql mysql> SOURCE /tmp/sakila-db/sakila-data.sql
Es findet sich nun, neben den Standarddatenbanken, die Datenbank SAKILA im MySQL Server.
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | sakila | +--------------------+
Konfiguration der Replikation
Die Konfiguration der Replikation umfasst mehrere Schritt, sowohl auf der MASTER, als auch auf der SLAVE Seite. Während der Replikation ist es notwendig, den MySQL Server neuzustarten. Dies muss vor allem in Produktivumgebungen beachtet werden, da es zu einem Ausfall des Systems kommt.
1. MASTER: Setzen der Server ID und Aktivieren des Binary Loggings
Jeder Server in der Repkilation benötigt eine eindeutige Server ID. Auf dem MASTER Server muss zusätzlich das Binary Logging aktiviert werden. Das Binary Logging stellt die Grundlage für die Replikation dar.
[root@ifrit ~]# vi /etc/my.cnf
Unter dem Punkt [mysqld] müssen die beiden folgenden Parameter hinzugefügt werden.
log-bin=mysql-bin server-id=1
Hinweis: Der Wert mysql-bin ist das Prefix für das Binary Log und kann frei gewählt werden.
Nach der Änderung an der MySQL Konfiguration, muss der Dienst neugestartet werden, damit die Änderungen greifen.
[root@ifrit ~]# /etc/init.d/mysqld restart mysqld beenden: [ OK ] mysqld starten: [ OK ]
2. SLAVE: Setzen der Server ID
Wie schon der MASTER Server, muss auch der SLAVE Server eine eindeutige ID besitzen.
[root@shiva ~]# vi /etc/my.cnf server-id=2
Anschließend wird der Dienst neugestartet.
[root@shiva ~]# /etc/init.d/mysqld restart mysqld beenden: [ OK ] mysqld starten: [ OK ]
3. MASTER: Anlegen eines separaten Benutzers für die Replikation
Dieser Schritt ist optional. Für die Replikation könnte theoretisch jeder Benutzer, der das Privileg REPLICATION SLAVE besitzt, verwendet werden. Ich empfehle aber einen extra Benutzer für die Replikation anzulegen, der nur dieses Privileg besitzt. Der Benutzername und das Passwort werden im Klartext auf dem SLAVE Server in der Datei master.info abgelegt.
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Durch das % Zeichen wird der Zugriff von jedem Host aus ermöglicht. In Produktivumgebungen sollte der Zugriff nur von dem SLAVE Server ermöglicht werden.
4. MASTER: Schreibzugriffe auf Tabellen unterbinden
Für die spätere Erstellung eines konsistenten Datenbank Snapshots müssen die Schreibzugriff auf die Tabellen gesperrt werden. Dafür baut man eine neue Sitzung mit dem root Benutzer auf und führt das folgende Kommando aus.
mysql> FLUSH TABLES WITH READ LOCK;
Hinweis: Die Sitzung muss offen bleiben. Alle weiteren Schritte müssen in einer neuen Sitzung durchgeführt werden.
5. MASTER: Ermitteln der Binary Log Koordinaten
Damit der SLAVE Server weiß, an welcher Stelle des Binary Logs er beginnen soll, die Änderungen nachzupflegen, müssen die aktuellen Binary Log Koordinaten ausgeleasen werden, während der Schreibzugriff auf die Datenbank gesperrt ist.
mysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 355 | | | +------------------+----------+--------------+------------------+
Wie man sieht befindet sich das Binary Log mysql-bin.000001 momentan an der Position 355. Diese Informationen werden später benötigt und müssen notiert werden.
6. MASTER: Datenbank Snapshot erstellen
In diesem Schritt wird nun ein Datenbank Snapshot der Datenbank SAKILA erzeugt. Dieser wird später in die Datenbank auf dem SLAVE Server eingespielt.
[root@ifrit ~]# mysqldump -u root -p sakila --lock-all-tables > /tmp/sakila_dump.sql
Hinweis: In dem resultierenden Dumpfiles befindet sich keine CREATE DATABASE Anweisung. Die Datenbank muss auf dem SLAVE Server zuvor manuell angelegt werden, bevor der Import gestartet werden kann.
Das Dumpfile wird auf den SLAVE Server kopiert.
[root@ifrit ~]# scp /tmp/sakila_dump.sql root@shiva:/tmp
7. MASTER: Schreibzugriff wieder aktivieren
Nachdem der Datenbank Snapshot erstellt wurde, kann der Schreibzugriff wieder aktiviert werden. Dafür führt man in der Session, die in Schritt 4 geöffnet wurde, den folgenden Befehl aus.
mysql> UNLOCK TABLES;
Alternativ kann die Session auch einfach geschlossen werden.
8. SLAVE: Import des Datenbank Dumpfiles
In diesem Schritt wird die Ziel Datenbank mithilfe des Dumpfiles aus Schritt 6 angelegt. Zuvor wird eine leere Datenbank im MySQL Server angelegt. Als Benutzer wird root verwendet.
mysql> CREATE DATABASE sakila;
Anschließend wird das Dumpfile importiert.
[root@ifrit ~]# mysql -u root -p sakila < /tmp/sakila_dump.sql
9. SLAVE: Konfiguration der Replikation
Nun muss auf dem SLAVE Server die Verbindung mit dem MASTER Server hergestellt werden. Dafür verwendet man die folgende CHANGE MASTER TO Anweisung. Es muss sich mit dem root Benutzer an der Datenbank angemeldet werden.
mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.200.210', -> MASTER_USER='repl', -> MASTER_PASSWORD='slavepass', -> MASTER_LOG_FILE='mysql-bin.000001', -> MASTER_LOG_POS=355;
Es kann nun der Replikationsprozess gestartet werden.
START SLAVE;
Die Konfiguration der Replikation ist abgeschlossen.
10. SLAVE: Überprüfung des Replikationsstatus
Zum Abschluss kann der Status der Replikation mit dem folgenden Befehl überprüft werden. Die Anmeldung erfolgt wiederum als root.
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.200.210 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 1173 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 1319 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: 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: 1173 Relay_Log_Space: 1476 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1