Einrichten von Master-Master Replikation mit MySQL 5 auf Debian Etch

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>

Seit Version 5 ist bei MySQL eine eingebaute Unterstützung für eine Master-Master Replikation dabei, womit das Problem mit selbst-erzeugten Schlüsseln gelöst wird. In früheren MySQL Versionen bestand das Problem mit der Master-Master Replikation darin, dass Konflikte sofort auftraten, wenn beide, Node A und Node B, einen auto-incrementing key in die gleiche Tabelle eingefügt haben. Die Vorteile einer Master-Master Replikation gegenüber der traditionellen Master-Slave Replikation bestehen darin, dass Du Deine Programme nicht ändern musst, damit nur der Master Schreibzugriff erhält und dass es einfacher ist, eine hohe Verfügbarkeit zu gewährleisten, denn wenn der Master ausfällt, hast Du immer noch den anderen Master.

Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Vorbemerkung

In dieser Anleitung werde ich veranschaulichen, wie man die Datenbank exampledb des Servers server1.example.com mit der IP Adresse 192.168.0.100 auf den Server server2.example.com mit der IP Adresse 192.168.0.101 repliziert und umgekehrt. Jedes einzelne System ist zur gleichen Zeit Master und Slave. Beide Systeme laufen auf Debian Etch; jedoch sollte die Konfiguration mit geringfügigen oder keinen Änderungen für fast jede Distribution gelten.

2 Installation von MySQL 5.0

Falls MySQL 5.0 noch nicht auf server1 und server2 installiert ist, dann installiere es jetzt:

server1/server2:

apt-get install mysql-server-5.0 mysql-client-5.0

Um sicher zu stellen, dass die Replikation funkioniert, müssen wir MySQL veranlassen, auf allen Interfaces zu hören. Daher kommentieren wir die Zeile bind-address = 127.0.0.1 in /etc/mysql/my.cnf aus:

server1/server2:

vi /etc/mysql/my.cnf

[...]
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           = 127.0.0.1
[...]

Starte danach MySQL neu:

server1/server2:

/etc/init.d/mysql restart

Überprüfe dann mit

server1/server2:

netstat -tap | grep mysql

ob MySQL wirklich auf allen Interfaces hört:

server1:~# netstat -tap | grep mysql
tcp 0 0 *:mysql *:* LISTEN 2671/mysqld
server1:~#

Richte danach ein MySQL Passwort für den Benutzer root@localhost ein:

server1/server2:

mysqladmin -u root password yourrootsqlpassword

Als Nächstes erstellen wir ein MySQL Passwort für root@server1.example.com:

server1:

mysqladmin -h server1.example.com -u root password yourrootsqlpassword

Nun richten wir einen Replikations-Benutzer slave2_user ein, der von server2 verwendet werden kann, um auf die MySQL Datenbank auf server1 zugreifen zu können:

server1:

mysql -u root -p

Führe in der MySQL Kommandozeile folgende Befehle aus:

server1:

GRANT REPLICATION SLAVE ON *.* TO ’slave2_user’@’%‘ IDENTIFIED BY ’slave2_password‘;
FLUSH PRIVILEGES;
quit;

Nun führen wir die letzten beiden Schritte noch einmal auf server2 aus:

server2:

mysqladmin -h server2.example.com -u root password yourrootsqlpassword

mysql -u root -p

GRANT REPLICATION SLAVE ON *.* TO ’slave1_user’@’%‘ IDENTIFIED BY ’slave1_password‘;
FLUSH PRIVILEGES;
quit;

3 Einige Notizen

Im Folgenden gehe ich davon aus, dass die Datenbank exampledb auf server1 bereits existiert und dass Tabellen mit Einträgen vorhanden sind. Nun setzen wir die Replikation exampledb zu server2 auf und danach setzen wir die Replikation von exampledb von server2 zu server1 auf.

Bevor wir anfangen die Replikation aufzusetzen, erstellen wir eine leere Datenbank exampledb auf server2:

server2:

mysql -u root -p

CREATE DATABASE exampledb;
quit;

4 Replikation aufsetzen

Nun setzen wir eine Master-Master Replikation in /etc/mysql/my.cnf auf. Entscheidende Konfigurationsoptionen für die Master-Master Replikation sind auto_increment_increment und auto_increment_offset:

  • auto_increment_increment kontrolliert das Inkrement zwischen aufeinanderfolgenden AUTO_INCREMENT Werten.
  • auto_increment_offset legt den Startpunkt für AUTO_INCREMENT Spaltenwerte fest.

Lass uns davon ausgehen, dass wir N MySQL Nodes (N=2 in diesem Beispiel) haben, dann hat auto_increment_increment den Wert N auf allen Nodes und jede Node muss einen anderen Wert für auto_increment_offset (1, 2, …, N) haben.

Lass uns nun unsere zwei MySQL Nodes konfigurieren:

server1:

vi /etc/mysql/my.cnf

Suche den Abschnitt, der mit [mysqld] beginnt und setze folgende Optionen ein (indem Du alle vorhandenen widersprüchlichen Optionen auskommentierst):

[...]
[mysqld]
server-id = 1
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 1

master-host = 192.168.0.101
master-user = slave1_user
master-password = slave1_password
master-connect-retry = 60
replicate-do-db = exampledb

log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db = exampledb

relay-log = /var/lib/mysql/slave-relay.log
relay-log-index = /var/lib/mysql/slave-relay-log.index

expire_logs_days        = 10
max_binlog_size         = 500M
[...]

Dann starte MySQL neu:

server1:

/etc/init.d/mysql restart

Führe nun das Gleiche auf server2 aus:

server2:

vi /etc/mysql/my.cnf

[...]
server-id = 2
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 2

master-host = 192.168.0.100
master-user = slave2_user
master-password = slave2_password
master-connect-retry = 60
replicate-do-db = exampledb

log-bin= /var/log/mysql/mysql-bin.log
binlog-do-db = exampledb

relay-log = /var/lib/mysql/slave-relay.log
relay-log-index = /var/lib/mysql/slave-relay-log.index

expire_logs_days        = 10
max_binlog_size         = 500M
[...]

server2:

/etc/init.d/mysql restart

Das könnte dich auch interessieren …