Datenbankreplikation mit MySQL

Bei einer Replikation, werden alle Queries eines sogn. „Master“ an weitere MySQL-Server übertragen. Dabei müssen aber die gleichen Datenbestände zu Grunde liegen. Es gibt verschiedene Strukturen. Hier werden nur die 2 wichtigsten besprochen. Das wären „Master – Slave“ und „Master – Master“.

Einfache Replikation: Master – Slave

Für eine asynchrone Replikation werden mindestens 2 MySQL-Server benötigt, von denen einer als Master und mindestens einer als Slave agiert. Bei dieser Art von Replikation schreibt der Master die Updates (alle Statements, die Datensätze verändern) in eine Binärlog-Datei. Diese dient als Datenspeicher, von welchem aus die Informationen über Datenänderungen an die Slave-Server gesendet werden.

Sobald sich ein Slave mit dem Master verbindet, übermittelt dieser die Position der letzten, erfolgreich empfangenen Änderungen, und empfängt daraufhin vom Master alle Updates seit der übermittelten Position. Nachdem der Slave die Änderungen übernommen hat, schaltet er so zu sagen in den Leerlauf und wartet auf die Übermittlung weiterer Änderungen vom Master.

Konfiguration eines Master

Für den später einzurichtenden Slave muss man auf dem Master einen Account anlegen. Dies erledigt man mit einen GRANT-Befehl, welcher allgemein dazu da ist Benutzer anzulegen. „GRANT SUPER,REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO ReplikationsUser@slavehost IDENTIFIED BY ‚PWD‘ ; Flush Privileges;“. Wobei hier dann „@slavehost“ die IP oder der Hostname des Slave ist. Man sollte dann noch in der „my.cnf“ nachsehen ob eine „server-id“ vergeben ist. Ohne diese geht es nicht. Jeder Server, der an einer Replikation beteiligt ist, braucht eine eindeutige „server-id“. Dabei sind nur Zahlen erlaubt. Man sollte dann auch noch einen Verbindungstest durchführen, indem man sich vom Slave aus auf den Master verbindet. „mysql -h masterhost -u ReplikationsUser -p“. Sollte diese Verbindung nicht aufgebaut werden können, sollte man beim Master kontrollieren ob in der Konfig evtl. „bind-address = 127.0.0.1“ steht oder ob das Passwort richtig gesetzt ist. Im folgenden Schritt erstellt man dann eine Kopie aller zu replizierenden Daten. Im Regelfall ist das meist alles. Dafür sperrt man den kompletten Server mit einer Schreib-Sperre.

FLUSH TABLES WITH READLOCK ;“. Die Konsole in der man dies Kommando eingegeben hat muss für die Dauer der folgenden Vorgänge geöffnet bleiben, da sonst der Readlock erlischt. Um dem Slave die genaue Position und den Namen der Binärlogdatei mitzuteilen, führt man noch folgendes Kommando aus: „SHOW MASTER STATUS;“. Die Ausgabe sollte dabei dieser ähneln:

File Position Binlog_Do_DB Binlog_Ignore_DB
mysqld-bin.000023 50958306

 

[ Mit den letzten beiden Feldern kann man in der „my.cnf“ explizit festlegen, welche einzelnen Datenbanken repliziert werden sollen und welche nicht. Dieses sollte man aber im Regelfall nie auf dem Master festlegen. Sondern eher auf dem Slave filtern. Dort kann man auch wieder in der „my.cnf“ festlegen was alles repliziert werden soll und was nicht. ]

Man notiert sich nun den Namen des „binlog“ und die Position, danach kann man mit dem Kopieren der Daten beginnen. Hat man nur MyISAM-Datenbanken macht man dies am besten auf Dateiebene. „tar -cvz -f /backup/mysql/snapshot_DATUM.tar.gz /var/lib/mysql“. Um die DB nicht all zu lange zu sperren kann man auch erst nur die Daten kopieren und dann später komprimieren. Ist man dann fertig, kann man sich aus der MySQL-Konsole ausloggen und somit die Sperre wieder aufheben.

Konfiguration eines Slave

Die MySQL-Version auf dem Slave sollte mindestens der des Masters entsprechen. Sie darf neuer sein, aber nicht älter. Auf dem Slave stoppt man dann erstmal den laufenden MySQL-Server und editiert die „my.cnf“. Dort setzt man auch wieder die Variablen für die Server-ID. Zu beachten ist hier nur, dass die Server-ID sich von der des Masters und aller bestehenden Slaves unterscheiden muss. Will man, das dieser Slave noch Master für weitere untergeordnete Slaves ist, muss man auch darauf achten das hier das binlog aktiviert ist. Hat man dann die Daten, welche man auf dem Master kopiert hat übertragen, kopiert man diese auf dem Slave nach „/var/lib/mysql“. Zu beachten sei, das man sich nicht die Datenbank „mysql“ überschreibt. Diese sollte man auch in der „my.cnf“ von der Replikation ausnehmen. Dies macht man mit den Optionen:

replicate-ignore-db= mysql
replicate-wild-ignore-table = mysql.%

Hat man dann die Daten kopiert, kontrolliert man noch mal, ob alle Dateien unterhalb von „/var/lib/mysql“ auch dem Benutzer und der Gruppe „mysql“ gehören. Jetzt kann man den MySQL-Server wieder starten. Um nun die Replikation zu aktiveren müssen wir dem Slave noch mitteilen, wer der Master ist und an welcher Stelle im binlog er anfangen soll zu lesen. Dies macht man mit dem „CHANGE MASTER“ Kommando:

CHANGE MASTER TO
MASTER_HOST = 'master_host',
MASTER_USER = 'ReplikationsUser',
MASTER_PASSWORD = 'PWD',
MASTER_LOG_FILE = 'log file name',
MASTER_LOG_POS = log_offset;

 

Wurde das Statement erfolgreich ausgeführt, wurden alle Änderungen übernommen und der Slave ist soweit bereit die Replikation zu starten. Gestartet wird dann einfach mit „SLAVE START;“ (gestoppt mit „SLAVE STOP;“). Nach dem Start sollte man mit „SHOW SLAVE STATUS;“ den Status der Replikation überprüfen. Steht „Slave_IO_Running“ auf „Yes“ läuft die Replikation. Dann ist immer noch der Wert „Seconds_Behind_Master“ interessant. Er gibt an, wie viel der Slave dem Master hinterher hängt. Am Anfang steht hier eine mehr oder weniger große Zahl, in endlicher Zeit sollte hier dann aber nur noch „0“ stehen. Steht dort „NULL“ gibt es ein Problem mit der Replikation, dann ist aber auch „Slave_IO_Running“ meisten auf „No“. Unter „Last_Error“ kann man dann noch nachlesen, wieso es zu einer Unterbrechung kam.

Reparieren der Replikation

Sollte die Replikation einmal unterbrochen werden, sollte man mit „slave stop“ erst mal den Replikations Prozess beenden. Mit „slave show status\G“ kann man sich dann den Status ausgeben lassen. Hierbei sollte man jetzt auf die Zeile „Last_Error:“ achten. Die dort ausgegebene Fehlermeldung sollte man nun genauer untersuchen und versuchen festzustellen warum es zu diesen Fehler kam. Hat man diesen dann beseitigt kann man mit „SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;“ MySQL anweisen, dieses Query zu überspringen. Anschließend kann man mit „slave start“ die Replikation wieder starten. Wenn alles gut läuft und dies der einzigste Fehler war, müsste diese nun auch wieder laufen.

Master – Master

Bei einer Master-Master-Replikation, gibt es, wie der Name schon sagt, 2 Master. Beide sind sich gegenseitig aber noch Slave. Sodas Änderungen auf einen Master direkt auch auf dem 2. Verfügbar sind und umgekehrt. Bei Master Slave kommen Update immer nur von einer Seite, vom Master. Hier kann jeder der beiden Änderungen machen. Dies führt natürlich auch zu Probleme. Was ist, wenn beide den gleichen Datensatz Ändern wollen? Deswegen muss man hier sehr auf die Daten-Integrität achten und am besten immer nur einen der Beiden Master schreiben lassen.

Aufbau einer Master-Master-Replikation

Es muss hier auch wieder auf beiden Server von den Gleichen Daten ausgegangen werden. Auf beiden das „binlog“ aktiviert sein. Dann kann man auf beiden jeweils einen Slave-Prozess einrichten, welcher den anderen Als Master nimmt.