MySQL Replikation einrichten

In diesem Beispiel verwende ich zwei Linux-Server:

  • uranus, wird als MASTER konfiguriert
Gentoo-Linux, mysqld Ver 5.0.70-log for pc-linux-gnu on x86_64 (Gentoo Linux mysql-5.0.70-r1)
  • shiva, wird als SLAVE konfiguriert
Debian-Linux, mysqld Ver 5.0.51a-24+lenny3 for debian-linux-gnu on i486 ((Debian))

Auf dem MASTER (uranus) befinden sich mehrere seit mehreren Jahren kontinuiertlich gewachsene Datenbanken mit mehreren Millionen Datensätzen, welche nun vollständig auf den neu installierten SLAVE (shiva) repliziert werden soll. Das bedeutet wir erstellen eine neue Replikation eines bestehenden Systems.


Zuerst wird auf dem MASTER (uranus) in der Datei /etc/mysql/my.cnf das binäre Logging eingeschaltet werden und die Server-ID konfiguriert werden. Dazu muss in der [mysqld] Sektion folgende Ergänzung gemacht werden:

[mysqld]
log-bin                 = uranus-log-bin
server-id               = 1

Anschließend muss der MySQL-Server neu gestartet werden:

uranus ~ # /etc/init.d/mysql restart
 * Stopping mysql ...
 * Stopping mysqld (0)                                [ ok ]
 * Starting mysql ...
 * Starting mysql (/etc/mysql/my.cnf)                 [ ok ]
uranus ~ #

Erklärung der Parameter:
Die Server-ID kann eine nahezu beliebige Zahl sein (von 1 bis (232)–1) – in diesem Beispiel wähle ich die ‚1‘ – der SLAVE erhält später die ‚2‘. Wird die Server-ID nicht konfiguriert oder explizit auf den Defaultwert ‚0‘ gesetzt, weist der MASTER sämtliche Verbindungswünsche von SLAVES ab. Um das binäre Logging einzuschalten, habe ich in diesem Beispiel den Namen der Maschine (uranus) und die Bezeichnung ‚log-bin‘ als Anfang des Dateinamens konfiguriert. Achtung! Dieser Teil des Dateinamens darf keinen Punkt (.) enthalten! Die im /var/lib/mysql Verzeichnis angelegten Dateien heissen in diesem Beispiel:

-rw-rw---- 1 mysql mysql       24 Jun  5 18:30 uranus-log-bin.index
-rw-rw---- 1 mysql mysql       98 Jun  5 18:30 uranus-log-bin.000001

Achtung! Bitte darauf achten, dass skip-networking nicht auf dem MASTER aktiv ist, sonst kann der SLAVE nicht mit dem MASTER kommunizieren und eine Replikation ist unmöglich! Seit einiger Zeit ist statt skip-networking die Angabe bind-address = 127.0.0.1 in der my.cnf Konfigurationsdatei eingetragen, welche bedeutet, dass nur auf der internen Netzadresse 127.0.0.1 Verbindungen angenommen werden – das Ergebnis ist das gleiche: Keine Verbindung von anderen Servern sind möglich, also muss diese Zeile auskommentiert werden. Neustart nicht vergessen.


Auch beim SLAVE (shiva) muss die Server-ID in der Konfigurationsdatei /etc/mysql/my.cnf gesetzt werden. Im meinem Beispiel verwende ich hier die ‚2‘:

[mysqld]
server-id               = 2

Sollten mehrere SLAVES konfiguriert werden, so wird für jeden eine eindeutige Server-ID benötigt (ähnlich wie bei IP-Adressen). Auch hier muss der MySQL-Server restartet werden:

shiva:~# /etc/init.d/mysql restart
Stopping MySQL database server: mysqld.
Starting MySQL database server: mysqld.
Checking for corrupt, not cleanly closed and upgrade needing tables..
shiva:~#

Als nächstes muß auf dem MASTER ein Benutzer für die Replikation eingerichtet werden. Eigentlich könnte jeder beliebige Benutzerkennung dafür verwendet werden, solange die Berechtigung REPLICATION_SLAVE zugewiesen wurde. Allerdings ist zu berücksichtigen, dass diese Benutzerkennung und auch das dazu gehörende Passwort auf dem SLAVE in einer Datei im Klartext hinterlegt werden muss. Daher bietet es sich an eine neue Benutzerkennung auf dem MASTER anzulegen, der dann ausschließlich die Berechtigung REPLICATION_SLAVE zugewiesen bekommt.

uranus ~ # mysql -uroot -pxxxxxxxxxxx
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 137
Server version: 5.0.70-log Gentoo Linux mysql-5.0.70-r1

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE USER 'repl'@'145.253.64.%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'145.253.64.%';
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
uranus ~ #

Um die Replikation auf dem SLAVE konfigurieren zu können, wird die aktuelle Position im binären Logfile benötigt, ab wann der SLAVE die Änderungen der MASTER Datenbank replizieren soll. Dafür müssen auf dem MASTER sämtliche Tabellen gelockt und ein Datenbankdump erzeugt werden. Werden beide Datenbanken nicht auf diese Weise synchronisiert, ist es fast unvermeidbar daß inkonsistente Tabellen und Datenbankfehler entstehen.

Wir beginnen also mit einer Client-Session auf dem MASTER (uranus):

uranus ~ # mysql -uroot -pxxxxxxxxxx
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 363
Server version: 5.0.70-log Gentoo Linux mysql-5.0.70-r1

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)

mysql>

Bitte unbedingt diese Client-Session aktiv halten und eine zweite Client-Session starten um die Binlog-Position zu ermitteln:

uranus ~ # mysql -uroot -pxxxxxxxxxx
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 367
Server version: 5.0.70-log Gentoo Linux mysql-5.0.70-r1

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SHOW MASTER STATUS;
+-----------------------+----------+--------------+------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------------+----------+--------------+------------------+
| uranus-log-bin.000001 |    60936 |              |                  |
+-----------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

mysql> quit
Bye
uranus ~ #

Nun muss ein Snapshot der Datenbank auf dem MASTER erzeugt werden.

uranus ~ # mysqldump -uroot -pxxxxxxxxxx --all-databases --master-data > MASTER.dump.db
uranus ~ #

In der ersten Client-Session können nun die Tabellen wieder freigegeben werden. Der Befehl ‚UNLOCK TABLES‘ ist eigentlich nicht notwendig, es kann auch einfach nur die Session beendet werden. Trotzdem bin ich lieber gründlich und führe den Befehl sicherheitshalber explizit aus:

mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
uranus ~ #

Anschließend muß der Datenbank-Dump vom MASTER auf den SLAVE übertragen werden und dort in die MySQL-Datenbank importiert werden:

shiva:~# ftp uranus.dmsp.de
Connected to uranus.dmsp.de.
220 ProFTPD 1.3.2 Server (DMSP IT-Services & ANNUNA.Net) [145.253.64.238]
Name (uranus.dmsp.de:root): pom
331 Password required for pom
Password:
230 User pom logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get MASTER.dump.db
local: MASTER.dump.db remote: MASTER.dump.db
200 PORT command successful
150 Opening BINARY mode data connection for MASTER.dump.db (284058595 bytes)
226 Transfer complete
284058595 bytes received in 13.07 secs (21225.1 kB/s)
ftp> quit
221 Goodbye.
shiva:~# mysql -uroot -pxxxxxxxxxxxx < MASTER.dump.db
shiva:~#

Nun muss der SLAVE (shiva) über die für die Replikation notwendigen Daten des MASTERs (uranus) informiert und die Replikationsprozesse auf dem SLAVE (shiva) gestartet werden.

shiva:~# mysql -uroot -pxxxxxxxxxxx
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.0.51a-24+lenny3 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CHANGE MASTER TO
    -> MASTER_HOST='uranus.dmsp.de',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='password',
    -> MASTER_LOG_FILE='uranus-log-bin.000001',
    -> MASTER_LOG_POS=60936;
Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
shiva:~#

Nach diesen Kommandos kann der SLAVE (shiva) eine Verbindung zum MASTER (uranus) aufbauen und sämtliche seit dem TABLE LOCK Kommando (Stand des Datenbank-Dumps) erfolgten Updates replizieren.


Überprüfung der Replikation (auf dem SLAVE / shiva): Im Verzeichnis /var/lib/mysql sollten sich bei erfolgreicher Replikation die folgenden zwei Dateien befinden:

shiva:/var/lib/mysql# ls -l master* relay*
-rw-rw---- 1 mysql mysql 84  5. Jun 20:15 master.info
-rw-rw---- 1 mysql mysql 61  5. Jun 20:15 relay-log.info

In der Datei master.info befinden sich die für die Verbindungsaufbau zum MASTER notwendigen Daten, welche vorher mit dem CHANGE MASTER TO Kommando eingegeben wurden. Hier befindet sich auch das Passwort des für die Replikation eingerichteten Benutzers im Klartext!
Beide Dateien zusammen werden vom MySQL-SLAVE benötigt um die Änderungen auf der MASTER-Datenbank zu verfolgen und replizieren zu können. Daher dürfen diese Dateien auf keinen Fall manuell geändert werden!

Eine deutliche Erfolgsmeldung erhält man (unter Debian Linux) über die Logdatei /var/log/daemon.log:

Jun  5 20:08:35 shiva mysqld[6585]: 100605 20:08:35 [Note] Slave SQL thread initialized, starting replication in log 'uranus-log-bin.000001' at position 60936, relay log './mysqld-relay-bin.000001' position: 4
Jun  5 20:08:35 shiva mysqld[6585]: 100605 20:08:35 [Note] Slave I/O thread: connected to master 'repl@uranus.dmsp.de:3306',  replication started in log 'uranus-log-bin.000001' at position 60936

Um diese Fehlermeldung

Jun  8 13:42:13 shiva mysqld[31967]: 100608 13:42:13 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=mysqld-relay-bin' to avoid this problem.

zu vermeiden, sollte nachfolgende Ergänzung im [mysqld] Teil der Konfigurationsdatei /etc/mysql/my.cnf auf dem SLAVE (shiva) eingetragen werden:

relay_log               = mysqld-relay-bin
relay_log_index         = mysqld-relay-bin.index
max_relay_log_size      = 100M
relay_log_purge         = 1
relay_log_info_file     = relay-log.info
relay_log_space_limit   = 200M

Weitere Links zum Thema