
| (SQL-)Dump Datei, die sämtliche Informationen einer Datenbank oder Tabelle in ASCII-form beinhaltet. |
| DML Data Modifcation Language. Über DML-Kommandos werden Daten eingefügt, gelöscht oder geändert. |
| DDL Data Defnition Language. Über DDL-Kommandos werden Datenstrukturen gepflegt (z. B. Tabellen angelegt oder gelöscht). |
Bereits seit der MySQL-Version 3.23.33 verfügt die Open Source Datenbank über die Möglichkeit der Replikation. Die Einrichtung ist dabei recht einfach. Im Weiteren gehen wir von einer typischen Einweg-Replikation eines Produktivsystems (im Folgenden Master genannt) auf ein Backup-System (im Folgenden Slave genannt) aus. Um den Master einzurichten, muss die Konfguration lediglich um zwei Konfgurationsparameter (je nach Betriebssystem in der my.ini bzw. my.cnf) erweitert werden.
Der Parameter "server-id" dient der eindeutigen Identifzierung der an einer Replikation beteiligten Datenbankserver und muss auf allen beteiligten Systemen eindeutig sein. Über den Parameter "log-bin" wird der Master veranlasst, sämtliche DML- und DDL-Kommandos binär in einem Logfle zu protokollieren.
Abb. 1: So wird repliziert. Der Master loggt alle DDL- und DML-Kommandos in einem binären Format. Der Slave liest die Informationen aus dem "bin-log" und legt sie lokal in einem eigenen Logfle ab. Anschließend werden die Änderungen in die Slave-Datenbank übertragen. | |
Der Slave nutzt dieses Logfle für ein Logmining. Er muss ja schließlich in Erfahrung bringen, welche Änderungen auf der Produktivseite vorgenommen wurden (siehe Abbildung 1). Damit der Slave das Logfle fndet, müssen in seiner Konfguration die folgenden Informationen hinterlegt werden.
Der Slave wird sich mittels des eingetragenen Useraccounts beim Master anmelden. Voraussetzung ist natürlich, dass der User auf dem Master mit den entsprechenden Rechten angelegt wurde. Ist dies der Fall, so kopiert der Slave sämtliche, auf dem Master protokollierten Aktionen in ein eigenes Logfle (relay-log). Aus diesem relay-log liest ein weiterer Slave-Prozess (SQL-Thread) die SQL-Kommandos ein und führt sie aus. Sollte es während der Replikation zu einer Störung kommen (z. B. Netzwerkausfall), so versucht der Slave periodisch eine neue Verbindung aufzubauen und seine unterbrochene Replikation fortzusetzen.
Neben den bereits oben beschriebenen Konfgurationsparametern, die für eine "Standard"-Replikation völlig ausreichend sind, gibt es weitere Optionen, um die Replikation zu modifzieren (siehe Abbildung 2). So kann man z. B. auf Slave- und/oder Master-Seite die Replikation für bestimmte Datenbanken oder Tabellen einschränken (z. B. auch durch die Verwendung komplexer, regulärer Ausdrücke). Sinnvoll ist auf jeden Fall der Einsatz des Parameters "read-only", der die Slave-Seite vor DML- und DDL-Kommandos schützt.
|
// ID des Slaves: |
Bevor die Replikation erstmalig gestartet werden kann, muss sichergestellt werden, dass die Datenbasis auf Master und Slave identisch ist. Dazu genügt es in der Regel, das Datenverzeichnis des Masters entweder komplett oder auszugsweise - wenn nur bestimmte Datenbanken repliziert werden sollen - auf den Slave zu kopieren.
Dabei ist es nicht relevant, ob auf dem Master und Slave unterschiedliche Betriebssysteme laufen. Die Datendateien von MySQL sind plattformunabhängig. Alternativ kann auch ein Dump von den gewünschten Datenbanken erstellt werden. Dazu kann das von MySQL mitgelieferte Tool "mysqldump" genutzt werden.
Für den Master ist es unerheblich, wie viele Slaves von ihm repliziert werden. Alle Slaves lesen ihre Informationen direkt aus dem Logfle und verursachen damit auf der Master-Datenbank keine direkte Last, wie sie beispielsweise durch SELECT-Kommandos entstehen würde.
Dementsprechend kann der Replikationsstatus auch nicht auf der Master-Seite überwacht werden. Bricht die Verbindung eines Slaves zu seinem Master ab, so werden die "Fehler" im ErrorLog des Slaves protokolliert. Einen Auszug aus dem ErrorLog fnden Sie in Abbildung 3.
|
050610 13:08:24 [ERROR] Slave I/O thread: error reconnecting to master |
Auch in der aktuellen Version von MySQL (4.1.X) gibt es noch keine einfache Möglichkeit, wirklich konsistente Online Backups zu erzeugen. Aus diesem Grund greifen viele Administratoren sehr häufg auf die sehr bequeme und schnelle Möglichkeit des "Cold Backup" zurück. Zu diesem Zweck wird der Server heruntergefahren und sämtliche Daten- und Logdateien werden durch Copy-Befehle gesichert. Dies widerspricht natürlich der immer häufgeren Anforderung nach dauerhaft verfügbaren Anwendungen.
Hier kann unser Master-Slave-Szenario helfen. Während der Master wie gewohnt produktiv arbeitet, wird die Replikation auf dem Slave für kurze Zeit gestoppt und der Server heruntergefahren. Anschließend wird vom Slave ein "Cold-Backup" erzeugt. Nach dem erneuten Start des Slave setzt dieser seine Replikation fort und holt die "verpassten" SQL-Kommandos nach und ist damit für den nächsten Backup-Zyklus bereit.
|
Das für die Replikation genutzte "bin-log" kann zusätzlich auch für eine Art Point-in-time-Recovery genutzt werden. MySQL liefert mit seiner Datenbank das Tool "mysqlbinlog" aus, mit dessen Hilfe aus den binären Log-Informationen die SQL-Kommandos in ASCII-form extrahiert werden können. Besonders hilfreich ist dabei die Möglichkeit, die Logfles nach Zeitstempeln, Datenbanken und/oder Transaktions-IDs durchsuchen zu können.
Stellen wir uns einmal folgendes Szenario vor: Nach dem Backup von letzter Nacht hat ein User eine wichtige Tabelle gelöscht. Wir möchten unsere Datenbank jetzt gezielt in den Zustand vor dieser Aktion bringen. Dazu spielen wir das letzte Backup ein und extrahieren aus den archivierten "bin-logs" alle Kommandos bis zu diesem Zeitpunkt (siehe Abbildungen 4 und 5). Die extrahierten Informationen werden anschließend in Form eines SQL-Skriptes in das wiederhergestellte Backup eingespielt.
bash > mysqlbinlog -start-datetime=2005-06-10_00:00:00 -stop-datetime=2005-06-10_07:59:59 ../logs/master-bin.000001 ../logs/master-bin.000002 ../logs/master-bin.00000 /*!40019 SET @@session.max_insert_delayed_threads=0*/; # at 4 #050610 03:35:01 server id 1 log_pos 4 Start: binlog v 3, server v 4.1.12a-nt-log created #050610 14:35:01 at startup # at 79 #050610 04:02:18 server id 1 log_pos 79 Query thread_id=2 exec_time=1 #error_code=0 use repl; SET TIMESTAMP=1118408538; insert into kunden values (3000, 'Müller'); # at 190 #050610 04:04:10 server id 1 log_pos 190 Query thread_id=2 exec_time=0 #error_code=0 SET TIMESTAMP=1118408650; insert into kunden values (1000, 'Meier'); # at 323 #050610 07:05:24 server id 1 log_pos 323 Query thread_id=2 exec_time=0 #error_code=0 SET TIMESTAMP=1118408724; delete from kunden where nr = 1356; # at 456 #050610 07:55:43 server id 1 log_pos 456 Query thread_id=2 exec_time=1 #error_code=0 SET TIMESTAMP=1118408743; update kunden set kreditlimit = kreditlimit * 1.05 where plz = 65205; |
Ganz nebenbei kann unser "Sklave" natürlich auch die Rolle eines Standby-Systems übernehmen. Für den Fall, dass unser Master ausfällt, kann der Slave den Betrieb aufrechterhalten, da er in der Regel einen identischen Datenbestand haben wird. Leider gibt es für MySQL noch keine automatischen Fail-Over-Lösungen. Durch geschickte Applikationsentwicklung oder eine kreative Netzwerkkonfguration können die Ausfallzeiten jedoch auf dieser Basis stark minimiert werden.
Nehmen wir für unser Szenario einmal an, dass sich eine Web-Applikation auf unsere Masterdatenbank (master.ordix.de) stützt. Unser Slave (slave.ordix.de) repliziert permanent alle Änderungen und wird periodisch (1 x pro Tag) für Backups genutzt. In der Anwendung wurde für den Datenbankhost der CNAME (Alias) n db.ordix.de hinterlegt, der normalerweise auf den Master-Server bzw. seine IP-Adresse verweist. Kommt es zu einem Ausfall des Masters, wird der DNS-Eintrag einfach so verändert, dass der Alias nun auf den Sklaven zeigt. Die Web-Applikation kann weiter arbeiten.
Auch eine Lastverteilung über die beiden Server ist denkbar. Allerdings ist hier zu beachten, dass Datenänderungen (DML-Kommandos) nur auf der Master-Seite vollzogen werden dürfen. Bei reinen Datawarehouse-Anwendungen oder anderen Applikationen, bei denen Abfragen (SELECTs) überwiegen (z. B. Content-Management-System), können die Anfragen z. B. in einem Round-Robin-Verfahren auf Master und Slave verteilt werden. Steigen die Anforderungen an die Applikation weiter an, so haben Sie jederzeit die Möglichkeit, einen weiteren Slave vom Master replizieren zu lassen.
Natürlich lassen sich nicht alle Probleme mittels einer Replikation lösen. Gerade bei sehr zeitkritischen Applikationen (Börsenkurse, Auktionen) ist sehr genau zu prüfen, ob die Replikationsgeschwindigkeit von MySQL ausreichend ist.
Problematisch ist derzeit auch noch die Lastverteilung von Queries innerhalb längerer Transaktionen. Die Daten einer Transaktion werden derzeit erst in dem Moment binär geloggt, in dem die Transaktion abgeschlossen wurde. Besteht eine Transaktion z. B. aus der folgenden Befehlskette (INSERT-SELECT-UPDATE-SELECT-COMMIT), so muss durch die Applikation sichergestellt werden, dass alle Kommandos auf der Master-Seite ausgeführt werden.
Die modifzierten Datensätze (INSERT, UPDATE) werden schließlich erst nach dem Ende der Transaktion auf den/die Slave(s) verteilt, so dass die SELECTS innerhalb der Transaktion auf der Slave-Seite falsche Informationen ermitteln würden.
Replikation unter MySQL ist eine einfach einzurichtende Funktion, die in vielen Anwendungsbereichen (Backup, Performance) eine echte Hilfe darstellt. Es ist daher um so unverständlicher, dass Replikationen unter MySQL derzeit ein Schattendasein fristen.
Matthias Jung (info@ordix.de).