Inhaltsverzeichnis
Dieses Kapitel beschreibt die verschiedenen Replikationsfunktionen in MySQL. Es stellt Replikationskonzepte vor, erläutert die Konfiguration von Replikationsservern und dient als Referenz der verfügbaren Replikationsoptionen. Ferner vorhanden ist eine Liste mit häufig gestellten Fragen (und den zugehörigen Antworten) sowie Hilfestellung zur Behebung von Replikationsproblemen.
Eine Beschreibung der Syntax replikationsspezifischer SQL-Anweisungen finden Sie in Abschnitt 13.6, „SQL-Befehle in Bezug auf Replikation“.
MySQL unterstützt die unidirektionale, asynchrone Replikation, bei der ein Server als Master agiert, während mehrere andere Server die Rolle der Slaves erfüllen. Dies steht im Gegensatz zur synchronen Replikation, die ein Kennzeichen von MySQL Cluster ist (siehe auch Kapitel 16, MySQL Cluster).
Bei der Single-Master-Replikation schreibt der Master-Server Updates in seine Binärlogdateien und führt zudem einen Index dieser Dateien, um den Überblick über die Logrotation zu behalten. Die Binärlogdateien dienen als Datenspeicher für Updates, die an alle Slave-Server gesendet werden. Wenn ein Slave eine Verbindung zu seinem Master herstellt, nennt er dem Master die Position, bis zu der er die Logdateien beim letzten erfolgreichen Update gelesen hat. Der Slave empfängt daraufhin alle Änderungen, die seit jenem Zeitpunkt durchgeführt wurden. Nachfolgend wechselt er in den Leerlauf und wartet darauf, dass der Master ihn über neue Aktualisierungen in Kenntnis setzt.
Ein Slave-Server kann seinerseits als Master agieren, um beispielsweise eine Verkettung von Replikationsservern realisieren zu können.
Die Multi-Master-Replikation ist zwar auch möglich, aber hierbei können Probleme auftreten, die bei der Single-Master-Replikation ausgeschlossen sind. Siehe auch Abschnitt 6.15, „Auto-Increment in der Multi-Master-Replikation“.
Sofern Sie die Replikation verwenden, sollten alle Änderungen an Tabellen, die repliziert werden, auf dem Master-Server durchgeführt werden. Andernfalls müssen Sie nämlich immer sorgfältig darauf achten, Konflikte zwischen von Benutzern vorgenommenen Änderungen an den Tabellen auf dem Master und solchen Änderungen zu vermeiden, die an Tabellen auf dem Slave vorgenommen werden. Beachten Sie ferner, dass Updates auf der Slave-Seite abhängig davon, ob Sie eine anweisungs- oder eine datensatzbasierte Replikation verwenden, unterschiedlich verarbeitet werden können. Betrachten Sie einmal das folgende Szenario, bei dem ein Datensatz auf dem Slave eingefügt wird, gefolgt von einer Anweisung auf Master-Seite, die die Tabelle leert:
slave>INSERT INTO tbl VALUES (1);
master>DELETE FROM tbl;
Der Master weiß nichts über die
INSERT
-Operation auf dem Slave-Server. Bei der
anweisungsbasierten Replikation wird tbl
auf
dem Master und dem Slave geleert, sobald der Slave auf den Stand
des Masters gebracht wird, weil der Master seine
DELETE
-Anweisung dann an den Slave sendet.
Infolgedessen hat tbl
nachfolgend auf beiden
Servern den gleichen Inhalt. Bei der datensatzbasierten
Replikation ist die Wirkung von DELETE
auf den
Slave eine andere. Der Master schreibt nämlich jeden aus der
Tabelle zu löschenden Datensatz in sein Binärlog. Der Slave
löscht daraufhin nur diejenigen Datensätze, die dort erscheinen
– und nicht denjenigen, der direkt auf dem Slave eingefügt
worden war. Hieraus ergeben sich unterschiedliche Inhalte der
Tabellen auf dem Master und dem Slave, was zu
Replikationsproblemen führen kann.
Informationen zur datensatzbasierten Replikation finden Sie in Abschnitt 6.3, „Zeilenbasierte Replikation“.
Die Replikation bietet Vorteile in puncto Robustheit, Geschwindigkeit und Systemadministration:
Die Robustheit wird durch eine Master/Slave-Konfiguration erhöht. Im Fall von Problemen auf dem Master können Sie auf den Slave als Sicherungskopie umschalten.
Eine verbesserte Reaktionszeit lässt sich für Clients
erzielen, indem die Last bei der Verarbeitung von
Clientabfragen auf die Master- und Slave-Server verteilt wird.
SELECT
-Abfragen können an einen Slave
geschickt werden, um die Verarbeitungsbelastung des Masters zu
senken. Allerdings sollten Anweisungen, die Daten verändern,
in jedem Fall an den Master geschickt werden, damit die
Synchronisation zwischen Master und Slaves erhalten bleibt.
Die Lastverteilungsstrategie ist effizient, wenn in erster
Linie nichtändernde Abfragen abgesetzt werden – aber dies
ist auch der Normalfall.
Ein weiterer Vorteil der Replikation besteht darin, dass Sie Datenbanksicherungen über einen Slave-Server durchführen können, ohne den Master zu stören. Der Master verarbeitet dann weiterhin alle Aktualisierungen auch während der Erstellung des Backups. Siehe auch Abschnitt 5.10.1, „Datenbank-Datensicherungen“.
Die MySQL-Replikation basiert darauf, dass der Master-Server alle Änderungen an Ihren Datenbanken (Updates, Löschvorgänge usw.) in seinen Binärlogs vermerkt. Aus diesem Grund müssen Sie das binäre Loggen auf dem Master-Server aktivieren. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.
Alle Slave-Server erhalten vom Master die gespeicherten Änderungen, die der Master in seinem Binärlog vermerkt hat, sodass jeder Slave dieselben Änderungen an seiner Kopie der Daten vornehmen kann.
Es ist extrem wichtig, sich klar zu machen, dass das Binärlog nichts anderes als eine Aufzeichnung darstellt, die zu genau dem Zeitpunkt beginnt, an dem Sie das binäre Loggen aktivieren. Insofern benötigen alle zu konfigurierenden Slaves Kopien der Master-Datenbank mit ihrem Aussehen zum Zeitpunkt der Aktivierung der Binärlogs auf dem Master. Wenn Sie Ihre Slaves mit Datenbanken starten, die nicht hundertprozentig denselben Status haben wie der Master beim Aktivieren der Binärlogs, dann werden höchstwahrscheinlich Probleme auftreten.
Eine Möglichkeit, die Daten des Masters auf den Slave zu
kopieren, besteht im Absetzen der LOAD DATA FROM
MASTER
-Anweisung. Allerdings funktioniert LOAD
DATA FROM MASTER
nur, wenn alle Tabellen auf dem Master
die MyISAM
-Speicher-Engine verwenden. Ferner
erwirkt die Anweisung eine globale Lesesperre, d. h., während
die Tabellen auf den Slave übertragen werden, sind keine Updates
auf dem Master möglich. Sobald wir die Funktion für sperrenfreie
Tabellenbackups im laufenden Betrieb implementiert haben, wird
diese globale Lesesperre nicht mehr erforderlich sein.
Aufgrund dieser Einschränkungen empfehlen wir Ihnen bis auf
weiteres, LOAD DATA FROM MASTER
nur dann zu
verwenden, wenn die Datenmenge auf dem Master relativ gering oder
eine längere Lesesperre auf dem Master hinnehmbar ist. Zwar kann
die tatsächliche Geschwindigkeit von LOAD DATA FROM
MASTER
von System zu System variieren, aber als
Faustregel können Sie eine Übertragungsrate von 1 Mbyte
Daten/Sekunde erwarten. Dies ist ein grober Anhaltspunkt, der aber
recht genau sein sollte, wenn sowohl Master als auch Slave über
700-MHz-Pentium-Prozessoren verfügen und über ein Netzwerk mit
einer Übertragungsrate von 100 Mbit/s miteinander verbunden
sind.
Nachdem auf dem Slave eine Kopie der Master-Daten installiert
wurde, stellt er eine Verbindung zum Master her und wartet auf
Updates, die er verarbeiten kann. Fällt der Master aus oder
verliert der Slave die Verbindung zu ihm, dann versucht er in
regelmäßigen Abständen, die Verbindung neu herzustellen, bis
der Empfang von Updates wieder möglich ist. Die Option
--master-connect-retry
steuert das Intervall, in
dem die Neuverbindung versucht wird. Voreingestellt sind 60
Sekunden.
Jeder Slave vermerkt die Position, an der das Lesen beim letzten Update vom Master-Server beendet wurde. Der Master selbst weiß nicht, wie viele Slaves an ihn angeschlossen sind oder welche Slaves zu einem gegebenen Zeitpunkt aktuell sind.
Die Replikationsfunktionen in MySQL basierten ursprünglich auf der Weitergabe von SQL-Anweisungen vom Master an den Slave. Dies bezeichnete man als anweisungsbasierte Replikation (Statement-Based Replication, SBR). Seit MySQL 5.1.5 gibt es noch eine andere Basis für die Replikation: die datensatzbasierte Replikation (Row-Based Replication, RBR). Statt die SQL-Anweisungen an den Slave zu senden, schreibt der Master alle Ereignisse, die angeben, wie einzelne Datensätze in der Tabelle geändert werden, in sein Binärlog.
Bei der klassischen anweisungsbasierten Replikation kann es Probleme mit der Replikation gespeicherter Routinen geben. Diese Probleme können Sie umgehen, indem Sie stattdessen die datensatzbasierte Replikation benutzen. Eine umfassende Liste möglicher Probleme finden Sie unter Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“.
Wenn Sie MySQL aus dem Quellcode erstellen, steht die
datensatzbasierte Replikation nur dann zur Verfügung, wenn Sie
configure mit der Option
--with-row-based-replication
aufrufen.
MySQL Server verwendet standardmäßig auch dann die
anweisungsbasierte Replikation, wenn MySQL mit Unterstützung der
datensatzbasierten Replikation konfiguriert wurde. Wenn Sie die
datensatzbasierte Replikation verwenden wollen, starten Sie den
Server mit der Option --binlog-format=row
, um die
datensatzbasierte Replikation global (d. h. für alle
Clientverbindungen) zu aktivieren. Die Option aktiviert
automatisch auch
innodb_locks_unsafe_for_binlog
, was bei der
datensatzbasierten Replikation sicher zu verwenden ist.
Die anweisungsbasierte Replikation kann beim Serverstart entweder
durch Angabe von --binlog-format=statement
oder
durch vollständiges Weglassen der Option
--binlog-format
ausgewählt werden.
Die datensatzbasierte Replikation bewirkt, dass die meisten Änderungen unter Verwendung des datensatzbasierten Formats in das Binärlog geschrieben werden. Allerdings müssen einige Änderungen auch als Anweisungen in das Binärlog geschrieben werden:
ANALYZE TABLE
REPAIR TABLE
OPTIMIZE TABLE
Die Option --binlog-row-event-max-size
ist für
Server verfügbar, die die datensatzbasierte Replikation
unterstützen. Datensätze werden in Blöcken von einer Größe in
das Binärlog geschrieben, die den Wert dieser Option nicht
übersteigt. Der Wert muss ein Vielfaches von 256 sein, Standard
ist 1024.
Die MySQL-Replikation wird unter Verwendung von drei Threads
implementiert: einem auf dem Master und zweien auf dem Slave. Wenn
eine START SLAVE
-Anweisung auf einem
Slave-Server abgesetzt wird, erstellt der Slave einen I/O-Thread,
der eine Verbindung zum Master herstellt und ihn auffordert, die
in seinen Binärlogs aufgezeichneten Änderungen zu senden. Der
Master erstellt daraufhin einen Thread, um die Inhalte des
Binärlogs an den Slave zu senden. Dieser Thread erscheint als
Binlog Dump
in der Ausgabe von SHOW
PROCESSLIST
auf dem Master. Der Slave-I/O-Thread liest
die Aktualisierungen, die der Binlog
Dump
-Thread des Masters sendet, und kopiert diese in
lokale Dateien, die Relay-Logs heißen und
sich im Datenverzeichnis des Slaves befinden. Der dritte Thread
ist der SQL-Thread, den der Slave erstellt, um die Relay-Logs zu
lesen und die enthaltenen Aktualisierungen auszuführen.
In der vorhergehenden Beschreibung wurden drei Threads pro Master/Slave-Verbindung beschrieben. Ein Master, der mehrere Slaves hat, erstellt einen Thread pro aktuell angeschlossenem Slave, und jeder Slave hat seine eigenen I/O- und SQL-Threads.
Der Slave verwendet zwei Threads, d. h., das Lesen der Updates vom Master und ihre Ausführung können auf zwei unabhängige Tasks verteilt werden. Auf diese Weise wird der Task zum Lesen der Anweisungen auch dann nicht verlangsamt, wenn die Anweisungsausführung selbst langsam erfolgt. Wenn beispielsweise der Slave-Server eine Zeit lang nicht ausgeführt wurde und dann gestartet wird, kann sein I/O-Thread schnell alle Inhalte des Binärlogs vom Master holen – und zwar auch dann, wenn der SQL-Thread nicht mitkommt. Sollte der Slave beendet werden, bevor der SQL-Thread alle erhaltenen Anweisungen ausgeführt hat, so hat der I/O-Thread zumindest alles abgerufen, d. h., eine sichere Kopie der Anweisungen ist lokal in den Relay-Logs auf dem Slave gespeichert und kann beim nächsten Start des Servers direkt ausgeführt werden. Auf diese Weise kann der Master-Server seine Binärlogs schneller bereinigen, da er nicht mehr warten muss, bis der Slave die Inhalte abgerufen hat.
Die SHOW PROCESSLIST
-Anweisung vermittelt
Informationen dazu, welche replikationsbezogenen Vorgänge auf
Master und Slave ablaufen. Das folgende Beispiel veranschaulicht,
wie die drei Threads in der Ausgabe von SHOW
PROCESSLIST
erscheinen.
Auf dem Master-Server sieht die Ausgabe von SHOW
PROCESSLIST
wie folgt aus:
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 2
User: root
Host: localhost:32931
db: NULL
Command: Binlog Dump
Time: 94
State: Has sent all binlog to slave; waiting for binlog to
be updated
Info: NULL
Hierbei ist Thread 2 ein Binlog
Dump
-Replikations-Thread für einen angeschlossenen
Slave. State
gibt an, dass alle anhängigen
Aktualisierungen an den Slave gesendet wurden und der Master
darauf wartet, dass neue Änderungen stattfinden. Wenn keine
Binlog Dump
-Threads auf einem Master vorhanden
sind, bedeutet dies, dass die Replikation nicht ausgeführt wird,
d. h., es sind derzeit keine Slaves angebunden.
Auf dem Slave-Server sieht die Ausgabe von SHOW
PROCESSLIST
wie folgt aus:
*************************** 1. row *************************** Id: 10 User: system user Host: db: NULL Command: Connect Time: 11 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 11 User: system user Host: db: NULL Command: Connect Time: 11 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL
Hieraus ist ersichtlich, dass Thread 10 der I/O-Thread ist, der
mit dem Master-Server kommuniziert. Thread 11 ist der SQL-Thread,
der die Updates verarbeitet, die in den Relay-Logs gespeichert
sind. Zum Zeitpunkt der Ausführung von SHOW
PROCESSLIST
waren beide Threads beschäftigungslos und
warteten auf weitere Aktualisierungen.
Der Wert in der Spalte Time
zeigt ggf., wie
groß der Rückstand zwischen Slave und Master ist. Siehe auch
Abschnitt 6.11, „Replikation: häufig gestellte Fragen“.
Die folgende Liste zeigt die häufigsten Statusangaben, die in
der Spalte State
für den Binlog
Dump
-Thread des Masters erscheinen können. Wenn keine
Binlog Dump
-Threads auf einem Master
vorhanden sind, bedeutet dies, dass die Replikation nicht
ausgeführt wird, d. h., es sind derzeit keine Slaves
angebunden.
Sending binlog event to slave
Binärlogs enthalten Ereignisse, wobei ein Ereignis normalerweise eine Änderung sowie zugehörige Informationen umfasst. Der Thread hat ein Ereignis aus dem Binärlog gelesen und sendet dieses nun an den Slave.
Finished reading one binlog; switching to next
binlog
Der Thread hat das Lesen einer Binärlogdatei beendet und öffnet die nächste, um sie an den Slave zu senden.
Has sent all binlog to slave; waiting for binlog to
be updated
Der Thread hat alle anhängigen Updates aus den Binärlogs gelesen und an den Slave gesendet. Er ist nun untätig und wartet auf neue Ereignisse, die aufgrund von Änderungen am Master in das Binärlog geschrieben werden.
Waiting to finalize termination
Eine nur ganz kurz angezeigte Statusangabe, die besagt, dass der Thread gerade beendet wird.
Die folgende Liste zeigt die häufigsten Statusangaben, die in
der Spalte State
für den I/O-Thread auf dem
Slave-Server erscheinen können. Dieser Status erscheint auch in
der Spalte Slave_IO_State
, die von
SHOW SLAVE STATUS
angezeigt wird. Sie können
also mit dieser Anweisung einen guten Eindruck davon erhalten,
was gerade passiert.
Connecting to master
Der Thread versucht, eine Verbindung zum Master herzustellen.
Checking master version
Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte.
Registering slave on master
Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte.
Requesting binlog dump
Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte. Der Thread fordert beim Master die Inhalte der Binärlogs beginnend bei der angegebenen Binärlogdatei und Position an.
Waiting to reconnect after a failed binlog dump
request
Wenn die Anforderung des Binärlogs fehlgeschlagen ist (etwa
aufgrund eines Verbindungsabbruchs), dann wechselt der
Thread in diesen Status, solange er schläft, versucht aber
in regelmäßigen Abständen, die Verbindung
wiederherzustellen. Das Intervall zwischen den
Verbindungsversuchen kann mit der Option
--master-connect-retry
angegeben werden.
Reconnecting after a failed binlog dump
request
Der Thread versucht, erneut eine Verbindung zum Master herzustellen.
Waiting for master to send event
Der Thread hat die Verbindung zum Master hergestellt und
wartet auf das Eintreffen von Binärlogereignissen. Dies
kann recht lange dauern, wenn der Master untätig ist.
Dauert der Wartevorgang länger als
slave_read_timeout
Sekunden, dann tritt
eine Zeitüberschreitung auf. Der Thread geht dann davon
aus, dass die Verbindung abgebrochen ist, und versucht, sie
neu herzustellen.
Queueing master event to the relay log
Der Thread hat ein Ereignis gelesen und kopiert es in sein Relay-Log, damit der SQL-Thread es verarbeiten kann.
Waiting to reconnect after a failed master event
read
Ein Lesefehler ist aufgetreten (aufgrund eines
Verbindungsabbruchs). Der Thread schläft für
master-connect-retry
Sekunden und
versucht dann, die Verbindung neu herzustellen.
Reconnecting after a failed master event
read
Der Thread versucht, erneut eine Verbindung zum Master
herzustellen. Wenn die Verbindung wiederhergestellt werden
konnte, wechselt der Status zu Waiting for master
to send event
.
Waiting for the slave SQL thread to free enough
relay log space
Sie verwenden einen
relay_log_space_limit
-Wert ungleich null.
Die Relay-Logs sind in ihrer Summe auf eine Größe
angewachsen, die diesen Wert überschreitet. Der I/O-Thread
wartet, bis der SQL-Thread durch die Verarbeitung von
Relay-Log-Inhalten genug Speicher freigegeben hat, sodass
Relay-Logs gelöscht werden können.
Waiting for slave mutex on exit
Eine Statusangabe, die beim Beenden des Threads ganz kurz angezeigt wird.
Die folgende Liste zeigt die häufigsten Statusangaben, die in
der Spalte State
für den SQL-Thread auf dem
Slave-Server erscheinen können.
Reading event from the relay log
Der Thread hat ein Ereignis aus dem Relay-Log gelesen, sodass dieses Ereignis verarbeitet werden kann.
Has read all relay log; waiting for the slave I/O
thread to update it
Der Thread hat alle Ereignisse in den Relay-Log-Dateien verarbeitet und wartet nun darauf, dass der I/O-Thread neue Ereignisse in das Relay-Log schreibt.
Waiting for slave mutex on exit
Eine nur ganz kurz angezeigte Statusangabe, die besagt, dass der Thread gerade beendet wird.
Die Spalte State
für den I/O-Thread kann
auch den Text einer Anweisung anzeigen. Das bedeutet, dass der
Thread ein Ereignis aus dem Relay-Log gelesen und die Anweisung
daraus extrahiert hat und diese nun ausführt.
Standardmäßig haben Dateinamen von Relay-Logs die Form
.
Hierbei ist host_name
-relay-bin.nnnnnn
host_name
der Name des
Slave-Serverhosts und nnnnnn
eine
Sequenznummer. Aufeinander folgende Relay-Log-Dateien werden mit
laufenden Sequenznummern beginnend bei 000001
erstellt. Der Slave verwendet eine Indexdatei, um die Übersicht
über die derzeit verwendeten Relay-Log-Dateien zu behalten. Der
Standardname der Relay-Log-Indexdatei lautet
.
Standardmäßig erstellt der Slave-Server die Relay-Log-Dateien
in seinem Datenverzeichnis. Die Standarddateinamen können mit
den Serveroptionen host_name
-relay-bin.index--relay-log
und
--relay-log-index
außer Kraft gesetzt werden.
Siehe auch Abschnitt 6.9, „Replikationsoptionen in my.cnf“.
Relay-Logs haben dasselbe Format wie Binärlogs und können mit
mysqlbinlog gelesen werden. Der SQL-Thread
löscht eine Relay-Log-Datei automatisch, sobald er alle
Ereignisse in dieser Datei ausgeführt hat und sie nicht mehr
benötigt. Es gibt keine dedizierte Methode zum Löschen von
Relay-Logs – der SQL-Thread kümmert sich selbst darum.
Allerdings rotiert FLUSH LOGS
die Relay-Logs,
was Auswirkungen darauf hat, wann der SQL-Thread sie löscht.
Ein Slave-Server erstellt unter den folgenden Bedingungen eine neue Relay-Log-Datei:
bei jedem Start des I/O-Threads
wenn die Logs – beispielsweise mit FLUSH
LOGS
oder mysqladmin flush-logs
– synchronisiert werden
wenn die aktuelle Relay-Log-Datei zu groß wird. Die Bedeutung von „zu groß“ ermitteln Sie wie folgt:
Wenn der Wert von max_relay_log_size
größer als 0 ist, gibt er die maximale Größe einer
Relay-Log-Datei an.
Wenn der Wert von max_relay_log_size
0 ist, bestimmt max_binlog_size
die
maximale Größe einer Relay-Log-Datei.
Ein Slave-Replikationsserver erstellt zwei weitere kleine
Dateien im Datenverzeichnis. Diese
Statusdateien heißen standardmäßig
master.info
und
relay-log.info
. Die Namen können mit den
Optionen --master-info-file
und
--relay-log-info-file
geändert werden. Siehe
auch Abschnitt 6.9, „Replikationsoptionen in my.cnf“.
Die beiden Statusdateien enthalten Informationen wie die in der
Ausgabe der Anweisung SHOW SLAVE STATUS
gezeigte (siehe auch Abschnitt 13.6.2, „SQL-Anweisungen für die Steuerung von Slave-Servern“).
Weil die Statusdateien auf der Festplatte gespeichert sind,
überdauern sie das Herunterfahren des Slave-Servers. Beim
nächsten Start des Servers liest er die beiden Dateien dann
aus, um zu ermitteln, wie weit er beim Lesen der Binärlogs vom
Master und bei der Verarbeitung der eigenen Relay-Logs gekommen
ist.
Der I/O-Thread aktualisiert die Datei
master.info
. Die folgende Tabelle zeigt die
Entsprechungen zwischen den Zeilen in der Datei und den von
SHOW SLAVE STATUS
angezeigten Spalten.
Zeile | Beschreibung |
1 | Anzahl der Zeilen in der Datei |
2 | Master_Log_File |
3 | Read_Master_Log_Pos |
4 | Master_Host |
5 | Master_User |
6 | Passwort (wird von SHOW SLAVE STATUS nicht angezeigt) |
7 | Master_Port |
8 | Connect_Retry |
9 | Master_SSL_Allowed |
10 | Master_SSL_CA_File |
11 | Master_SSL_CA_Path |
12 | Master_SSL_Cert |
13 | Master_SSL_Cipher |
14 | Master_SSL_Key |
Der SQL-Thread aktualisiert die Datei
relay-log.info
. Die folgende Tabelle zeigt
die Entsprechungen zwischen den Zeilen in der Datei und den von
SHOW SLAVE STATUS
angezeigten Spalten.
Zeile | Beschreibung |
1 | Relay_Log_File |
2 | Relay_Log_Pos |
3 | Relay_Master_Log_File |
4 | Exec_Master_Log_Pos |
Wenn Sie die Daten des Slaves sichern, sollten Sie neben den
Relay-Log-Dateien auch diese beiden Statusdateien sichern. Sie
werden stets benötigt, um die Replikation nach
Wiederherstellung der Daten auf dem Slave fortzusetzen. Wenn Sie
die Relay-Logs verlieren, aber noch über die Datei
relay-log.info
verfügen, können Sie
ermitteln, wie weit der SQL-Thread die Binärlogs des Masters
bereits ausgeführt hatte. Dann können Sie den Slave durch
Absetzen von CHANGE MASTER TO
mit den
Optionen MASTER_LOG_FILE
und
MASTER_LOG_POS
anweisen, die Binärlogs von
diesem Punkt an erneut zu lesen. (Dies setzt natürlich voraus,
dass die Binärlogs noch auf dem Master-Server vorhanden sind.)
Wenn Ihr Slave Gegenstand der Replikation von LOAD DATA
INFILE
-Anweisungen ist, sollten Sie auch alle
SQL_LOAD-*
-Dateien sichern, die in dem vom
Slave zu diesem Zweck verwendeten Verzeichnis vorhanden sind.
Der Slave benötigt diese Dateien, um die Replikation
unterbrochener LOAD DATA INFILE
-Operationen
fortzusetzen. Die Verzeichnisposition wird mit der Option
--slave-load-tmpdir
angegeben. Wird die Option
nicht angegeben, dann bezeichnet der Wert der Systemvariablen
tmpdir
die Verzeichnisposition.
Dieser Abschnitt beschreibt kurz, wie man die vollständige Replikation eines MySQL Servers konfiguriert. Es wird angenommen, dass Sie alle Datenbanken auf dem Master replizieren wollen und die Replikation zuvor noch nicht konfiguriert haben. Sie müssen Ihren Master-Server kurz herunterfahren, um die beschriebenen Schritte vollständig durchführen zu können.
Beschrieben wird der Vorgang für die Konfiguration eines einzelnen Slaves; mehrere Slaves können Sie konfigurieren, indem Sie die entsprechenden Schritte wiederholen.
Zwar ist diese Vorgehensweise die direkteste zur Konfiguration eines Slaves, sie ist aber nicht die einzige. Wenn Sie beispielsweise eine Momentaufnahme der Daten auf dem Master haben und auf diesem bereits die Serverkennung eingestellt und das binäre Loggen aktiviert ist, dann können Sie einen Slave konfigurieren, ohne den Master herunterzufahren oder auch nur Aktualisierungen zu unterbinden. Weitere Informationen finden Sie unter Abschnitt 6.11, „Replikation: häufig gestellte Fragen“.
Wenn Sie eine MySQL-Replikationskonfiguration administrieren wollen, sollten Sie dieses Kapitel vollständig lesen und alle Anweisungen ausprobieren, die in Abschnitt 13.6.1, „SQL-Anweisungen für die Steuerung von Master-Servern“, und Abschnitt 13.6.2, „SQL-Anweisungen für die Steuerung von Slave-Servern“, beschrieben sind. Ferner sollten Sie sich mit den Replikationsstartoptionen vertraut machen, die in Abschnitt 6.9, „Replikationsoptionen in my.cnf“, erläutert werden.
Hinweis: Diese Methode und einige
der replikationsspezifischen SQL-Anweisungen, die in späteren
Abschnitten beschrieben werden, erfordern die Berechtigung
SUPER
.
Vergewissern Sie sich, dass die auf dem Master und dem Slave installierten MySQL-Versionen kompatibel im Sinne der in Abschnitt 6.6, „Replikation: Kompatibilität zwischen MySQL-Versionen“, aufgeführten Tabelle sind. Im Idealfall sollten Sie die jeweils aktuellste MySQL-Version sowohl auf dem Master als auch auf dem Slave verwenden.
Wenn Sie auf ein Problem stoßen, melden Sie dieses bitte erst als Bug, nachdem Sie sich vergewissert haben, dass es auch im aktuellen MySQL-Release vorhanden ist.
Konfigurieren Sie ein Konto auf dem Master-Server, über das
der Slave eine Verbindung herstellen kann. Dieses Konto
benötigt die Berechtigung REPLICATION
SLAVE
. Wenn das Konto ausschließlich zur
Replikation verwendet wird (was wir empfehlen), dann brauchen
Sie keine weiteren Berechtigungen zu gewähren.
Nehmen wir nun an, dass Ihre Domäne
mydomain.com
heißt und dass Sie ein Konto
mit dem Benutzernamen repl
erstellen
wollen, das Slave-Server unter Angabe des Passworts
slavepass
von einem beliebigen Host in
Ihrer Domäne aus für den Zugriff auf den Master verwenden
kann. Dieses Konto erstellen Sie mit folgender
GRANT
-Anweisung:
mysql>GRANT REPLICATION SLAVE ON *.*
->TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';
Beabsichtigen Sie, die Anweisungen LOAD TABLE FROM
MASTER
oder LOAD DATA FROM MASTER
auf dem Slave-Host zu verwenden, dann müssen Sie diesem Konto
weitere Berechtigungen gewähren:
Gewähren Sie dem Konto die globalen Berechtigungen
SUPER
und RELOAD
.
Gewähren Sie die Berechtigung SELECT
für alle Tabellen, die Sie laden wollen. Alle
Master-Tabellen, für die das Konto keine
SELECT
-Berechtigung hat, werden von
LOAD DATA FROM MASTER
ignoriert.
Weitere Informationen zur Konfiguration von Benutzerkonten und Berechtigungen finden Sie in Abschnitt 5.9, „MySQL-Benutzerkontenverwaltung“.
Synchronisieren Sie alle Tabellen und unterbinden Sie
Schreibanweisungen, indem Sie eine FLUSH TABLES WITH
READ LOCK
-Anweisung ausführen:
mysql> FLUSH TABLES WITH READ LOCK;
Beachten Sie, dass FLUSH TABLES WITH READ
LOCK
bei InnoDB
-Tabellen auch
COMMIT
-Operationen sperrt. Wenn Sie eine
globale Lesesperre erwirkt haben, können Sie eine
Dateisystem-Momentaufnahme Ihrer
InnoDB
-Tabellen erstellen. Intern (d. h.
innerhalb der InnoDB
-Speicher-Engine) ist
diese Momentaufnahme nicht konsistent, weil die
InnoDB
-Caches nicht synchronisiert wurden,
aber dies ist nicht weiter problematisch, weil
InnoDB
dieses Problem beim Start beseitigt
und ein konsistentes Ergebnis abliefert. Das bedeutet, dass
bei InnoDB
die Wiederherstellung von Daten
nach einem Absturz verlustfrei möglich ist, wenn der Neustart
auf der Basis dieser Momentaufnahme erfolgt. Allerdings gibt
es keine Möglichkeit, den MySQL Server zu beenden und
gleichzeitig eine konsistente Momentaufnahme Ihrer
InnoDB
-Tabellen zu gewährleisten.
Lassen Sie den Client laufen, von dem aus Sie die
FLUSH TABLES
-Anweisung absetzen, damit die
Lesesperre aktiv bleibt. (Wenn Sie den Client beenden, wird
die Sperre aufgehoben.) Erstellen Sie nun eine Momentaufnahme
der Daten auf Ihrem Master-Server.
Die einfachste Möglichkeit zur Erstellung einer Momentaufnahme ist die Verwendung eines Archivierungsprogramms: Hiermit erstellen Sie eine binäre Sicherung der Datenbanken im Datenverzeichnis Ihres Master-Servers. Sie können beispielsweise tar unter Unix oder PowerArchiver, WinRAR, WinZip oder eine ähnliche Software unter Windows verwenden. Um mit tar ein Archiv zu erstellen, das alle Datenbanken enthält, wechseln Sie in das Datenverzeichnis des Master-Servers und führen dann folgenden Befehl aus:
shell> tar -cvf /tmp/mysql-snapshot.tar .
Wollen Sie, dass das Archiv nur eine Datenbank namens
this_db
enthält, dann verwenden Sie
stattdessen folgenden Befehl:
shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db
Danach kopieren Sie die Archivdatei in das Verzeichnis
/tmp
auf dem Slave-Serverhost. Auf diesem
System wechseln Sie nun in das Datenverzeichnis des Slaves und
entpacken die Archivdatei mithilfe des folgenden Befehls:
shell> tar -xvf /tmp/mysql-snapshot.tar
Wenn auf dem Slave-Server andere Benutzerkonten als auf dem
Master vorhanden sind, sollten Sie die Datenbank
mysql
unter Umständen nicht replizieren.
In diesem Fall sollten Sie sie aus dem Archiv ausschließen.
Ferner sollten Sie weder Logdateien noch die Dateien
master.info
oder
relay-log.info
in das Archiv einfügen.
Während die mit FLUSH TABLES WITH READ
LOCK
erwirkte Lesesperre gültig ist, lesen Sie den
Namen des aktuellen Binärlogs und den Versatz auf dem Master
aus:
mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73 | test | manual,mysql |
+---------------+----------+--------------+------------------+
Die Spalte File
zeigt den Namen der
Logdatei an, Position
den Versatz innerhalb
der Datei. In diesem Beispiel heißt die Binärlogdatei
mysql-bin.003
, der Versatz ist 73. Notieren
Sie diese Werte. Sie benötigen sie später beim Konfigurieren
des Slaves. Die Werte stellen die Replikationskoordinaten dar,
bei denen der Slave die Verarbeitung neuer Updates vom Master
startet.
Wenn der Master zuvor ohne aktiviertes Binärloggen
ausgeführt wurde, sind die von SHOW MASTER
STATUS
oder mysqldump
--master-data angezeigten Werte für Lognamen und
Position leer. In diesem Fall lauten die Werte, die Sie
später als Logdateinamen und Position auf dem Slave angeben
müssen, ''
(Leer-String) und
4
.
Nachdem Sie die Momentaufnahme erstellt und Lognamen und Versatz aufgezeichnet haben, können Sie die Schreibaktivitäten auf dem Master neu starten:
mysql> UNLOCK TABLES;
Wenn Sie InnoDB
-Tabellen einsetzen, sollten
Sie im Idealfall das Tool InnoDB
Hot Backup verwenden, welches ohne Sperre auf dem
Master-Server eine konsistente Momentaufnahme erstellt und
Lognamen und Versatz passend für die Momentaufnahme
speichert, sodass die Angaben später auf dem Slave benutzt
werden können. Hot Backup ist ein
kommerzielles (d. h. nicht kostenloses) Zusatztool, das nicht
Bestandteil der MySQL-Standarddistribution ist. Weitere
Informationen finden Sie auf der Homepage von
InnoDB
Hot Backup unter
http://www.innodb.com/manual.php.
Wenn Sie Hot Backup nicht einsetzen,
besteht die schnellste Methode zur Erstellung einer binären
Momentaufnahme der InnoDB
-Tabellen darin,
den Master-Server herunterzufahren und die Datendateien,
Logdateien und Tabellenformatdateien
(.frm
) von InnoDB
zu
kopieren. Um den aktuellen Logdateinamen und den Versatz
aufzuzeichnen, sollten Sie folgende Anweisungen absetzen,
bevor Sie den Server herunterfahren:
mysql>FLUSH TABLES WITH READ LOCK;
mysql>SHOW MASTER STATUS;
Dann notieren Sie Lognamen und Versatz aus der Ausgabe von
SHOW MASTER STATUS
wie oben beschrieben.
Danach fahren Sie den Server herunter,
ohne die Tabellen zu entsperren;
hierdurch ist sicherstellt, dass der Server mit einem Status
beendet wird, der den Angaben zu Logdatei und Versatz
entspricht:
shell> mysqladmin -u root shutdown
Eine Alternative, die sowohl bei MyISAM
-
als auch bei InnoDB
-Tabellen funktioniert,
besteht darin, einen SQL-Speicherauszug des Masters anstatt
– wie oben beschrieben – einer binären Kopie zu
erstellen. Hierzu führen Sie mysqldump
--master-data auf dem Master aus und laden die
SQL-Speicherauszugsdatei später in Ihren Slave. Allerdings
ist die Erstellung einer binären Kopie schneller.
Vergewissern Sie sich, dass der Abschnitt
[mysqld]
der Datei
my.cnf
auf dem Master-Host die Option
log-bin
enthält. Der Abschnitt sollte
ferner eine Option
server-id=
enthalten, wobei master_id
master_id
ein
positiver Integer zwischen 1 und
232 – 1 sein muss. Zum
Beispiel:
[mysqld] log-bin=mysql-bin server-id=1
Wenn diese Optionen nicht vorhanden sind, fügen Sie sie hinzu und starten den Server neu. Der Server kann erst als Replikationsmaster agieren, wenn das binäre Loggen aktiviert ist.
Hinweis: Um die größtmögliche Dauerhaftigkeit und
Konsistenz in einer Replikationskonfiguration für
InnoDB
mit Transaktionen zu erzielen,
sollten Sie
innodb_flush_log_at_trx_commit=1
und
sync_binlog=1
in der Datei
my.cnf
auf dem Master angeben.
Beenden Sie den Server, der als Slave vorgesehen ist, und
fügen Sie in seiner Datei my.cnf
die
folgenden Zeilen hinzu:
[mysqld]
server-id=slave_id
Der Wert slave_id
muss wie
master_id
auch ein positiver
Integer zwischen 1 und 232 –
1 sein. Ferner muss sich die Kennung des Slaves von der des
Masters unterscheiden. Zum Beispiel:
[mysqld] server-id=2
Wenn Sie mehrere Slaves konfigurieren, muss jeder einen
eindeutigen server-id
-Wert haben, der sich
von dem des Masters und von denen aller anderen Slaves
unterscheidet. Betrachten Sie
server-id
-Werte als etwas Ähnliches wie
IP-Adressen: Diese Kennungen identifizieren jede Serverinstanz
in der Gruppe der Replikationspartner eindeutig.
Wenn Sie keinen server-id
-Wert angeben,
wird er auf 1 gesetzt, sofern Sie
master-host
nicht definiert haben;
andernfalls wird der Wert auf 2 gesetzt. Beachten Sie, dass,
wenn Sie server-id
weglassen, ein Master
Verbindungen aller Slaves abweist und auch ein Slave sich
weigert, eine Verbindung mit einem Master herzustellen. Auf
diese Weise ist das Übergehen von
server-id
nur für ein Backup mit einem
Binärlog geeignet.
Wenn Sie eine binäre Sicherung der Daten auf dem Master-Server erstellt haben, kopieren Sie sie in das Datenverzeichnis des Slaves, bevor Sie diesen starten. Stellen Sie sicher, dass die Berechtigungen für Dateien und Verzeichnisse korrekt sind. Das Systemkonto, über das Sie den Slave-Server ausführen, muss die Dateien wie beim Master auch lesen und schreiben können.
Wenn Sie ein Backup mit mysqldump erstellen, starten Sie den Slave zuerst. Die Speicherauszugsdatei wird in einem späteren Schritt geladen.
Starten Sie den Slave-Server. Erfolgte bereits früher eine
Replikation, dann starten Sie den Slave mit der Option
--skip-slave-start
, damit er nicht sofort
versucht, eine Verbindung mit dem Master herzustellen. Sie
sollten den Slave-Server außerdem mit der Option
--log-warnings
starten, um im Falle von
Problemen (z. B. Netzwerk- oder Verbindungsproblemen) mehr
Meldungen im Fehlerlog zu erhalten. Die Option ist
standardmäßig aktiviert, aber abgebrochene Verbindungen
werden nicht im Fehlerlog vermerkt, sofern der Optionswert
nicht größer als 1 ist.
Wenn Sie mit mysqldump ein Backup der Daten auf dem Master-Server erstellt haben, laden Sie die Speicherauszugsdatei in den Slave-Server:
shell> mysql -u root -p < dump_file.sql
Führen Sie die folgende Anweisung auf dem Slave aus und ersetzen Sie dabei die Optionswerte durch die für Ihr System geeigneten Werte:
mysql>CHANGE MASTER TO
->MASTER_HOST='
->master_host_name
',MASTER_USER='
->replication_user_name
',MASTER_PASSWORD='
->replication_password
',MASTER_LOG_FILE='
->recorded_log_file_name
',MASTER_LOG_POS=
recorded_log_position
;
Die folgende Tabelle zeigt die maximal zulässige Länge bei Optionen, die String-Werte enthalten:
MASTER_HOST | 60 |
MASTER_USER | 16 |
MASTER_PASSWORD | 32 |
MASTER_LOG_FILE | 255 |
Starten Sie die Slave-Threads:
mysql> START SLAVE;
Nachdem Sie diesen Vorgang durchgeführt haben, sollte der Slave eine Verbindung mit dem Master herstellen und alle Updates nachholen, die seit Erstellung der Momentaufnahme erstellt wurden.
Wenn Sie es versäumt haben, die Option
server-id
für den Master einzustellen, dann
können Slaves keine Verbindung herstellen.
Wenn Sie es versäumt haben, die Option
server-id
für den Slave einzustellen, dann
erhalten Sie im Fehlerlog des Slaves die folgende Meldung:
Warning: You should set server-id to a non-0 value if master_host is set; we will force server id to 2, but this MySQL server will not act as a slave.
Ferner werden Sie Fehlermeldungen im Fehlerlog des Slaves vorfinden, wenn eine Replikation aus irgendeinem anderen Grund nicht möglich ist.
Sobald ein Slave mit der Replikation begonnen hat, finden Sie in
seinem Datenverzeichnis zwei Dateien namens
master.info
und
relay-log.info
. Der Slave verwendet diese
beiden Dateien, um zu vermerken, welcher Anteil des
Master-Binärlogs bereits verarbeitet wurde. Sie dürfen diese
Dateien keinesfalls entfernen oder
bearbeiten, sofern Sie nicht genau wissen, was Sie tun und welche
Auswirkungen dies haben kann. Und auch in diesem Fall sollten Sie
besser die CHANGE MASTER TO
-Anweisung
verwenden, um die Replikationsparameter zu ändern. Der Slave
aktualisiert die Statusdateien automatisch entsprechend den
Werten, die in dieser Anweisung angegeben sind.
Hinweis: Der Inhalt von
master.info
setzt einige der Serveroptionen,
die auf der Befehlszeile oder in der Datei
my.cnf
angegeben sind, außer Kraft. Weitere
Informationen finden Sie in
Abschnitt 6.9, „Replikationsoptionen in my.cnf“.
Sobald Sie über eine Momentaufnahme des Masters verfügen, können Sie diese zur Konfiguration weiterer Slaves verwenden. Folgen Sie dabei einfach der oben beschriebenen Anleitung. Sie müssen also keine neue Momentaufnahme erstellen, sondern können dieselbe auch für jeden weiteren Slave verwenden.
Das Binärlogformat, wie es in MySQL 5.1
implementiert ist, unterscheidet sich erheblich von dem vorheriger
Versionen. Dies gilt insbesondere für den Umgang mit
Zeichensätzen, LOAD DATA INFILE
und Zeitzonen.
Wir empfehlen die Verwendung der jeweils aktuellen MySQL-Version, weil die Replikationsfunktionen kontinuierlich verbessert werden. Ferner empfehlen wir die Verwendung derselben Version auf Master und Slave. Empfohlen wird außerdem die Aktualisierung von Mastern und Slaves, die unter Alpha- oder Betaversionen laufen, auf neue (Produktions-)Versionen. In vielen Fällen schlägt die Replikation von einem neueren Master auf einen älteren Slave fehl. Generell können Slaves, die unter MySQL 5.1.x laufen, mit älteren Mastern (sogar solchen unter MySQL 3.23, 4.0 oder 4.1) verwendet werden, nicht jedoch umgekehrt.
Hinweis: Sie dürfen keinesfalls eine Replikation von einem Master, der ein neueres Binärlogformat aufweist, auf einen Slave durchführen, der ein älteres Format benutzt (z. B. von MySQL 5.0 auf MySQL 4.1). Dies hat gravierende Auswirkungen auf die Aktualisierung von Replikationsservern (siehe auch Abschnitt 6.7, „Upgrade eines Replikationssetups“).
Diese Angaben beziehen sich auf die Replikationskompatibilität auf Protokollebene. Es gibt weitere Einschränkungen, z. B. bei Fragen der Kompatibilität auf SQL-Ebene. So kann etwa ein Master unter 5.1 keine Replikation auf einen Slave unter 5.0 durchführen, wenn die replizierten Anweisungen SQL-Funktionen verwenden, die zwar in 5.1, nicht aber in 5.0 vorhanden sind. Diese und andere Probleme werden in Abschnitt 6.8, „Replikation: Features und bekannte Probleme“, behandelt.
Wenn Sie Server aktualisieren, die Bestandteile einer Replikationskonfiguration sind, hängt die Vorgehensweise zur Aktualisierung von den aktuellen Serverversionen und der Version ab, auf die Sie aktualisieren.
Dieser Abschnitt betrifft die Aktualisierung der Replikation von MySQL 3.23, 4.0 oder 4.1 auf MySQL 5.1. Ein 4.0-Server sollte unter Version 4.0.3 oder höher laufen.
Wenn Sie einen Master von einer früheren MySQL-Release-Serie auf 5.1 aktualisieren, dann müssen Sie zuallererst einmal gewährleisten, dass alle Slaves dieses Masters denselben 5.1.x-Release verwenden. Ist dies nicht der Fall, dann sollten Sie zuerst die Slaves aktualisieren. Um einen Slave zu aktualisieren, fahren Sie ihn herunter, aktualisieren ihn auf die entsprechende Version 5.1.x und starten nachfolgend zunächst den Server und dann die Replikation neu. Der 5.1-Slave kann alte Relay-Logs, die vor dem Upgrade geschrieben wurden, lesen und die enthaltenen Anweisungen ausführen. Relay-Logs, die vom Slave nach dem Upgrade erstellt wurden, haben bereits das 5.1-Format.
Nachdem die Slaves aktualisiert wurden, fahren Sie den Master herunter, aktualisieren ihn auf denselben 5.1.x-Release wie die Slaves und starten ihn dann neu. Der 5.1-Master kann alte Binärlogs, die vor dem Upgrade geschrieben wurden, lesen und an die 5.1-Slaves schicken. Die Slaves erkennen das alte Format und verarbeiten es entsprechend. Binärlogs, die vom Master nach dem Upgrade erstellt wurden, haben bereits das 5.1-Format. Auch diese werden von den 5.1-Slaves erkannt.
Es sind also bei der Aktualisierung auf MySQL 5.1 keine weiteren Maßnahmen durchzuführen – Sie müssen lediglich beachten, dass Sie ggf. zuerst die Slaves auf MySQL 5.1 aktualisieren, bevor Sie dies beim Master tun. Beachten Sie, dass ein Downgrade von 5.1 auf ältere Versionen nicht so einfach ist: Sie müssen gewährleisten, dass alle Binär- und Relay-Logs im 5.1-Format vollständig verarbeitet wurden, damit Sie sie entfernen können, bevor Sie mit dem Downgrade fortfahren.
Das Downgrade einer Replikationskonfiguration auf eine ältere Version ist nicht mehr möglich, wenn Sie von der anweisungs- auf die datensatzbasierte Replikation umgestellt haben und die erste datensatzbasierte Anweisung in das Binärlog geschrieben wurde. Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“.
Generell erfordert die Replikationskompatibilität auf SQL-Ebene,
dass alle verwendeten Funktionen sowohl vom Master als auch vom
Slave unterstützt werden. Wenn Sie eine Funktion auf einem
Master-Server verwenden, die nur ab einer bestimmten MySQL-Version
verfügbar ist, dann können Sie keine Replikation auf einen Slave
vornehmen, der älter ist als diese Version. Derartige
Inkompatibilitäten treten häufig zwischen verschiedenen Serien
auf. So können Sie beispielsweise keine Replikation von MySQL
5.1 auf 5.0 durchführen. Allerdings
können solche Inkompatibilitäten auch innerhalb derselben Serie
auftreten. So ist beispielsweise die Funktion
SLEEP()
seit MySQL 5.0.12 verfügbar. Wenn Sie
diese Funktion auf dem Master-Server verwenden, können Sie sie
nicht auf einen Slave replizieren, der älter ist als MySQL
5.0.12.
Beabsichtigen Sie, die Replikation zwischen MySQL 5.1 und einer älteren Version durchzuführen, dann sollten Sie im MySQL-Referenzhandbuch zu dieser älteren Release-Serie nach Informationen zu den Replikationseigenschaften dieser Serie suchen.
Die folgende Liste enthält genauere Angaben dazu, was
unterstützt wird und was nicht. Zusätzliche
InnoDB
-spezifische Informationen zur
Replikation finden Sie in
Abschnitt 14.2.6.5, „InnoDB
und MySQL-Replikation“.
Bei der klassischen anweisungsbasierten Replikation kann es Probleme mit der Replikation gespeicherter Routinen geben. Diese Probleme können Sie umgehen, indem Sie stattdessen die datensatzbasierte Replikation benutzen. Eine umfassende Liste möglicher Probleme finden Sie unter Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“. Eine Beschreibung der datensatzbasierten Replikation finden Sie in Abschnitt 6.3, „Zeilenbasierte Replikation“.
Die Replikation von AUTO_INCREMENT
-,
LAST_INSERT_ID()
- und
TIMESTAMP
-Werten erfolgt korrekt.
Die Funktionen USER()
,
UUID()
und LOAD_FILE()
werden ohne Änderung repliziert und funktionieren daher nur
dann korrekt auf dem Slave, wenn die datensatzbasierte
Replikation aktiviert ist. (Siehe auch
Abschnitt 6.3, „Zeilenbasierte Replikation“.)
Die folgende Beschränkung gilt nur für die
anweisungsbasierte, nicht für die datensatzbasierte
Replikation. Die Funktionen
GET_LOCK()
,
RELEASE_LOCK()
,
IS_FREE_LOCK()
und
IS_USED_LOCK()
, die Sperren auf
Benutzerebene verwalten, werden repliziert, ohne dass der
Slave den zugehörigen Kontext auf dem Master kennt. Aus
diesem Grund sollten diese Funktionen nicht zum Einfügen in
eine Tabelle auf dem Master verwendet werde, da der Kontext
auf dem Slave ganz anders aussehen würde. (So sollten Sie
etwa keine Anweisung wie INSERT INTO mytable
VALUES(GET_LOCK(...))
absetzen.)
Die Variablen FOREIGN_KEY_CHECKS
,
SQL_MODE
, UNIQUE_CHECKS
und SQL_AUTO_IS_NULL
werden (ab MySQL 5.0)
alle repliziert. Die Systemvariable
storage_engine
(die auch
table_type
heißt) wird in MySQL 5.1 noch
nicht repliziert, was für die Replikation zwischen
verschiedenen Speicher-Engines von Vorteil ist.
Die Replikation funktioniert zwischen Mastern und Slaves unter MySQL 5.0 und 5.1 in beliebiger Kombination – auch dann, wenn Master und Slave unterschiedliche Werte für die Zeichensatz- und/oder die globalen Zeitzonenvariablen aufweisen. (Beachten Sie, dass dies nicht in Fällen zutrifft, in denen Master und/oder Slave unter MySQL 4.1 oder früher laufen.)
Folgendes gilt für die Replikation zwischen MySQL Servern, die unterschiedliche Zeichensätze benutzen:
Wenn der Master MySQL 4.1 verwendet, müssen Sie
immer dieselben
globalen Werte für Zeichensatz und
Sortierfolge auf dem Master und dem Slave verwenden –
unabhängig davon, welche MySQL-Version auf dem Slave
läuft. (Diese werden von den Optionen
--character-set-server
und
--collation-server
gesteuert.)
Andernfalls kann es Fehler aufgrund von
Schlüsseldubletten auf dem Slave geben, da ein
Schlüssel, der im Zeichensatz des Masters eindeutig ist,
dies im Zeichensatz des Slaves nicht unbedingt sein muss.
Beachten Sie, dass dies keine Rolle mehr spielt, wenn
Master und Slave beide unter MySQL 5.0 oder höher laufen.
Wenn der Master älter ist als MySQL 4.1.3, dann sollte
auf den beteiligten Clients kein anderer Zeichensatz als
der global angegebene verwendet werden, weil der Slave
eine solche Änderung des Zeichensatzes nicht bemerkt.
Clients sollten also SET NAMES
,
SET CHARACTER SET
usw. nicht benutzen.
Wenn sowohl Master als auch Slave unter 4.1.3 oder höher
laufen, können die Clients die zeichensatzbezogenen
Sitzungsvariablen frei einstellen, da diese Werte in das
Binärlog geschrieben und auf diese Weise dem Slave
mitgeteilt werden. Clients können also SET
NAMES
oder SET CHARACTER SET
verwenden oder Variablen wie
COLLATION_CLIENT
oder
COLLATION_SERVER
einstellen. Nicht
ändern können Clients hingegen den
globalen Wert dieser Variablen: Wie
bereits gesagt, Master und Slave müssen für den globalen
Zeichensatz immer identische Werte aufweisen.
Wenn sich auf dem Master Datenbanken mit Zeichensätzen
befinden, die sich vom globalen
character_set_server
-Wert
unterscheiden, dann sollten Sie Ihre CREATE
TABLE
-Anweisungen so formulieren, dass Tabellen
in diesen Datenbanken nicht implizit auf den
Standardzeichensatz der Datenbank angewiesen sind (siehe
auch Bug 2326). Ein guter Workaround hierfür besteht
darin, in der CREATE TABLE
-Anweisung
Zeichensatz und Sortierfolge explizit anzugeben.
Wenn der Master MySQL 4.1 verwendet, dann sollte auf Master
und Slave dieselbe Systemzeitzone eingestellt sein.
Andernfalls werden einige Anweisungen – wie etwa solche, die
die Funktionen NOW()
oder
FROM_UNIXTIME()
verwenden – nicht korrekt
repliziert. Sie können die Zeitzone, in der der MySQL Server
läuft, mit der Option
--timezone=
des Skripts timezone_name
mysqld_safe
oder durch
Einstellen der Umgebungsvariablen TZ
ändern. Master und Slave sollten ferner auch dieselbe
Standardeinstellung für die Verbindungszeitzone aufweisen,
d. h., der Wert des Parameters
--default-time-zone
sollte auf Master und
Slave gleich sein. Beachten Sie, dass dies nicht notwendig
ist, wenn der Master unter MySQL 5.0 oder höher läuft.
CONVERT_TZ(...,...,@session.time_zone)
wird
nur dann korrekt repliziert, wenn Master und Slave unter MySQL
5.0.4 oder höher laufen.
Sitzungsvariablen werden nicht korrekt repliziert, wenn sie in
Anweisungen verwendet werden, die Tabellen aktualisieren. So
fügt SET MAX_JOIN_SIZE=1000
gefolgt von
INSERT INTO mytable VALUES(@MAX_JOIN_SIZE)
auf dem Master nicht dieselben Daten ein wie auf dem Slave.
Dies betrifft allerdings nicht die gängige Sequenz aus
SET TIME_ZONE=...
gefolgt von
INSERT INTO mytable
VALUES(CONVERT_TZ(...,...,@time_zone))
.
Die Replikation von Sitzungsvariablen ist kein Problem, wenn die datensatzbasierte Replikation benutzt wird. Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“.
Es ist auch möglich, transaktionssichere Tabellen auf dem
Master in nichttransaktionssichere Tabellen auf dem Slave zu
replizieren. Sie können beispielsweise eine
InnoDB
-Tabelle auf dem Master als
MyISAM
-Tabelle auf dem Slave replizieren.
Allerdings kommt es, wenn Sie dies tun, zu Problemen, wenn der
Slave mitten in einem
BEGIN
/COMMIT
-Block
angehalten wird, weil er nachfolgend am Anfang des
BEGIN
-Blocks neu einstartet. Dieses Problem
steht auf unserer Aufgabenliste und wird in Bälde behoben
sein.
Änderungsanweisungen, die benutzerdefinierte Variablen (also
Variablen des Typs
@
)
referenzieren, werden korrekt repliziert. (Dies gilt jedoch
nicht für Versionen vor 4.1.) Beachten Sie, dass beginnend
mit MySQL 5.0 bei den Namen von Benutzervariablen die
Groß-/Kleinschreibung unterschieden wird, wenn Sie die
Replikation zwischen MySQL 5.0 und älteren Versionen
einrichten.
var_name
Slaves können unter Verwendung von SSL eine Verbindung zum Master herstellen.
Die globale Systemvariable
slave_transaction_retries
wirkt sich wie
folgt auf die Replikation aus: Wenn ein SQL-Thread auf einem
Replikationsslave eine Transaktion nicht ausführen kann, weil
eine InnoDB
-Blockade aufgetreten ist oder
die Werte innodb_lock_wait_timeout
von
InnoDB
bzw.
TransactionDeadlockDetectionTimeout
oder
TransactionInactiveTimeout
von
NDBCluster
überschritten wurden, erfolgt
die durch slave_transaction_retries
angegebene Anzahl von Neuversuchen, bevor der Vorgang mit
einer Fehlermeldung beendet wird. Der Standardwert ist 10. Die
Gesamtzahl der Neuversuche finden Sie in der Ausgabe von
SHOW STATUS
. (Siehe auch
Abschnitt 5.2.4, „Server-Statusvariablen“.)
Wenn eine der Tabellenoptionen DATA
DIRECTORY
oder INDEX DIRECTORY
in
einer CREATE TABLE
-Anweisung auf dem
Master-Server verwendet wird, wird dieselbe Option auch auf
dem Slave umgesetzt. Dies kann zu Problemen führen, wenn im
Dateisystem des Slave-Hosts kein entsprechendes Verzeichnis
vorhanden ist, oder wenn es zwar vorhanden ist, aber der
Slave-Server nicht darauf zugreifen kann. MySQL unterstützt
eine sql_mode
-Option namens
NO_DIR_IN_CREATE
. Wenn dieser SQL-Modus am
Slave-Server aktiviert ist, ignoriert der Slave die
Tabellenoptionen DATA DIRECTORY
und
INDEX DIRECTORY
beim Replizieren von
CREATE TABLE
-Anweisungen. Infolgedessen
werden die MyISAM
-Daten- und Indexdateien
im Datenbankverzeichnis der Tabelle erstellt.
Die folgende Beschränkung betrifft nur die anweisungsbasierte Replikation, nicht die datensatzbasierte Replikation: Die Daten auf dem Master und dem Slave können verschieden werden, wenn eine Abfrage so formuliert wird, dass die Datenänderung nichtdeterministisch ist, d. h. dem Gutdünken des Abfrageoptimierers überlassen wird. (Dies ist auch abgesehen von der Replikation nicht zu empfehlen.) Eine umfassende Erläuterung dieses Problems finden Sie unter Abschnitt A.8.1, „Offene Probleme in MySQL“.
FLUSH LOGS
, FLUSH
MASTER
, FLUSH SLAVE
und
FLUSH TABLES WITH READ LOCK
werden nicht
geloggt, weil dies bei der Replikation auf einen Slave
Probleme verursachen würde. Ein Syntaxbeispiel finden Sie in
Abschnitt 13.5.5.2, „FLUSH
“. Die Anweisungen FLUSH
TABLES
, ANALYZE TABLE
,
OPTIMIZE TABLE
und REPAIR
TABLE
werden in das Binärlog geschrieben und
infolgedessen auf die Slaves repliziert. Dies ist
normalerweise unproblematisch, weil diese Anweisungen die
Tabellendaten nicht verändern. Allerdings kann dies unter
bestimmten Umständen trotzdem Probleme verursachen. Wenn Sie
die Berechtigungstabellen in der
mysql
-Datenbank replizieren und diese
Tabellen direkt und ohne Verwendung von
GRANT
aktualisieren, müssen Sie eine
FLUSH PRIVILEGES
-Anweisung auf den Slaves
absetzen, damit die neuen Berechtigungen gültig werden.
Ferner müssen Sie, wenn Sie FLUSH TABLES
beim Umbenennen einer MyISAM
-Tabelle
absetzen, die Teil einer MERGE
-Tabelle ist,
auf den Slaves eine FLUSH TABLES
-Anweisung
manuell absetzen. Diese Anweisungen werden in das Binärlog
geschrieben, sofern Sie nicht
NO_WRITE_TO_BINLOG
oder den Alias
LOCAL
angegeben haben.
MySQL unterstützt genau einen Master und mehrere Slaves.
Zukünftig beabsichtigen wir, einen Votieralgorithmus
hinzuzufügen, der den Master automatisch wechselt, falls
Probleme in Verbindung mit dem aktuellen Master auftreten.
Ferner werden wir Agentenprozesse zur Durchführung einer
Lastverteilung implementieren, indem
SELECT
-Anweisungen an verschiedene Slaves
gesendet werden.
Wenn ein Server heruntergefahren wird und neu startet, werden
seine MEMORY
-Tabellen geleert. Der Master
repliziert diesen Effekt wie folgt auf seine Slaves: Wenn der
Master eine MEMORY
-Tabelle nach dem Start
zum ersten Mal verwendet, loggt er ein Ereignis, welches den
Slaves angibt, dass die Tabelle geleert werden muss, indem
eine DELETE
-Anweisung für die betreffende
Tabelle in das Binärlog geschrieben wird. Weitere
Informationen finden Sie in
Abschnitt 14.4, „Die MEMORY
-Speicher-Engine“.
Beachten Sie, dass das Folgende nicht gilt, wenn die datensatzbasierte Replikation verwendet wird, denn diese erfordert überhaupt keine Replikation von Temporärtabellen. (Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“.)
Temporärtabellen werden normalerweise repliziert. Eine Ausnahme liegt vor, wenn Sie den Slave-Server (und nicht nur die Slave-Threads) heruntergefahren und Temporärtabellen repliziert haben, die in Updates verwendet werden, welche noch nicht auf dem Slave ausgeführt wurden. Haben Sie den Slave-Server heruntergefahren, dann stehen die Temporärtabellen, die von diesen Aktualisierungen benötigt werden, beim Neustart des Servers nicht mehr zur Verfügung. Um dieses Problem zu umgehen, fahren Sie den Slave nicht herunter, solange Temporärtabellen geöffnet sind. Stattdessen wenden Sie folgende Vorgehensweise an:
Setzen Sie eine STOP SLAVE
-Anweisung
ab.
Überprüfen Sie mit SHOW STATUS
den
Wert der Variablen
Slave_open_temp_tables
.
Wenn der Wert 0 ist, beenden Sie den Slave mit einem mysqladmin shutdown-Befehl.
Ist der Wert nicht 0, dann starten Sie die Slave-Threads
mit START SLAVE
neu.
Wiederholen Sie den Vorgang nachfolgend so oft, bis die
Variable Slave_open_temp_tables
0 ist
und Sie den Slave beenden können.
Die Verbindung mit Servern in einer
Master/Slave-Zirkelbeziehung ist sicher, wenn Sie die Option
--log-slave-updates
benutzen. Das bedeutet,
dass Sie eine Konfiguration wie die folgende erstellen
können:
A -> B -> C -> A
Allerdings funktionieren viele Anweisungen in einer solchen Konfiguration nicht einwandfrei, sofern Ihr Code nicht so formuliert ist, dass potenzielle Probleme berücksichtigt werden, die aufgrund von auf verschiedenen Servern in unterschiedlicher Reihenfolge durchgeführten Updates entstehen können.
Serverkennungen werden in Binärlogereignisse kodiert, d. h.,
Server A erkennt, wenn ein Ereignis, das er liest,
ursprünglich von ihm selbst erstellt worden ist, und führt
es dann nicht aus (es sei denn, Server A wurde mit der Option
--replicate-same-server-id
gestartet, die
aber nur in wenigen Fällen wichtig ist). Es kommt also nicht
zu Endlosschleifen. Eine solche Zirkelkonfiguration
funktioniert nur, wenn Sie keine Updates durchführen, durch
die es zu Konflikten zwischen Tabellen kommt: Wenn Sie Daten
sowohl auf A als auch auf C einfügen, sollten Sie keinesfalls
einen Datensatz auf A einfügen, dessen Schlüssel unter
Umständen mit einem Datensatz auf C kollidiert. Ebenso wenig
sollten Sie dieselben Datensätze auf zwei Servern
aktualisieren, wenn die Reihenfolge, in der die Updates
durchgeführt werden, von Bedeutung ist.
Wenn eine Anweisung auf einem Slave einen Fehler erzeugt, wird
der Slave-SQL-Thread terminiert, und der Slave schreibt eine
Meldung in sein Fehlerlog. In diesem Fall sollten Sie manuell
eine Verbindung zum Slave herstellen und die Ursache des
Problems bestimmen. (Hierfür ist SHOW SLAVE
STATUS
recht praktisch.) Danach beheben Sie das
Problem (z. B. durch Erstellen einer nichtvorhandenen
Tabelle) und führen dann START SLAVE
aus.
Einen Master-Server herunterzufahren und später neu zu
starten ist sicher. Wenn ein Slave seine Verbindung zum Master
verliert, versucht er sofort eine Neuverbindung und wiederholt
diesen Versuch in regelmäßigen Abständen, bis er
erfolgreich ist. Standardmäßig erfolgt alle 60 Sekunden ein
Versuch zur Neuverbindung. Dies lässt sich mit der Option
--master-connect-retry
ändern. Ein Slave
kann auch mit Ausfällen der Netzwerkkonnektivität
zurechtkommen. Allerdings bemerkt er einen solchen Ausfall
erst, wenn er für slave_net_timeout
Sekunden keine Daten vom Master empfangen hat. Sind die
Ausfälle kurz, dann sollten Sie den Wert von
slave_net_timeout
verringern. Siehe auch
Abschnitt 5.2.2, „Server-Systemvariablen“.
Das (saubere) Herunterfahren des Slaves ist auch sicher, weil
er vermerkt, an welcher Stelle er beendet wurde. Unsauberes
Herunterfahren hingegen kann insbesondere dann Probleme
verursachen, wenn der Festplatten-Cache vor Terminierung des
Systems nicht auf die Festplatte geschrieben worden war. Ihre
Systemfehlertoleranz erhöht sich erheblich, wenn Sie eine
gute unterbrechungsfreie Stromversorgung verwenden. Eine
unsaubere Beendigung des Masters kann Inkonsistenzen zwischen
dem Inhalt der Tabellen und dem Binärlog auf dem Master zur
Folge haben. Dies lässt sich durch Verwendung von
InnoDB
-Tabellen und der Option
--innodb-safe-binlog
auf dem Master
vermeiden. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.
Hinweis:
--innodb-safe-binlog
wird in MySQL 5.1 nicht
benötigt, weil es durch die in MySQL 5.0 eingeführte
Unterstützung von XA-Transaktionen obsolet geworden ist.
Siehe auch Abschnitt 13.4.7, „XA-Transaktionen“.
Aufgrund des nichttransaktionssicheren Wesens von
MyISAM
-Tabellen kann es vorkommen, dass
eine Anweisung eine Tabelle nur teilweise aktualisiert und
dann einen Fehlercode zurückgibt. Dies kann beispielsweise
beim Einfügen mehrerer Datensätze geschehen, wenn einer
dieser Datensätze gegen einen Schlüssel-Constraint
verstößt, oder wenn eine lange Update-Anweisung nach
Aktualisierung einer Anzahl von Datensätzen terminiert wurde.
Wenn dies auf dem Master passiert, wird der Slave-Thread
beendet. Es liegt dann am Datenbankadministrator, zu
entscheiden, was zu tun ist, sofern der Fehlercode nicht
zulässig ist und die Ausführung der Anweisung auf dem Slave
denselben Fehlercode verursacht. Wenn dieses Verhalten der
Fehlercodeauswertung nicht gewünscht ist, können einige oder
alle Fehler mit der Option
--slave-skip-errors
maskiert (d. h.
ignoriert) werden.
Wenn Sie transaktionssichere Tabellen aus
nichttransaktionssicheren Tabellen in einer
BEGIN
/COMMIT
-Sequenz
aktualisieren, sind die Änderungen im Binärlog unter
Umständen nicht synchron zu den Tabellenzuständen, wenn die
nichttransaktionssichere Tabelle aktualisiert wird, bevor die
Transaktion übergeben wird. Die Ursache hierfür ist, dass
die Transaktion erst dann in das Binärlog geschrieben wird,
wenn sie übergeben wird.
In Situationen, in denen Transaktionen Updates für transaktionssichere und nichttransaktionssichere Tabellen vermischen, ist die Reihenfolge der Anweisungen im Binärlog korrekt, und alle erforderlichen Anweisungen werden – auch bei einem Rollback – in das Binärlog geschrieben. Aktualisiert allerdings eine zweite Verbindung die nichttransaktionssichere Tabelle, bevor die Transaktion der ersten Verbindung abgeschlossen ist, dann kann die geloggte Anweisungsreihenfolge falsch sein, weil die Änderung der zweiten Verbindung unmittelbar nach ihrer Ausführung geschrieben wird – unabhängig von dem Zustand der Transaktion, die von der ersten Verbindung durchgeführt wurde.
Dieser Abschnitt beschreibt die Optionen, die Sie auf Replikationsslaves verwenden können. Sie können diese Optionen wahlweise auf der Befehlszeile oder in einer Optionsdatei angeben.
Auf dem Master und jedem Slave müssen Sie die Option
server-id
angeben, um eine eindeutige
Replikationskennung zu erstellen. Wählen Sie auf jedem Server
eine eindeutige Zahl zwischen 1 und 232
– 1. Außerdem muss jede Kennung sich von jeder anderen
Kennung unterscheiden. Zum Beispiel:
server-id=3
Optionen, die Sie auf dem Master-Server zur Steuerung des binären Loggens verwenden können, sind in Abschnitt 5.12.3, „Die binäre Update-Logdatei“, beschrieben.
Einige Replikationsoptionen für Slave-Server werden in dem Sinne
speziell gehandhabt, dass sie ignoriert werden, wenn beim Start
des Slaves eine Datei master.info
vorhanden
ist und diese einen Wert für die betreffende Option enthält.
Dies betrifft die folgenden Optionen:
--master-host
--master-user
--master-password
--master-port
--master-connect-retry
--master-ssl
--master-ssl-ca
--master-ssl-capath
--master-ssl-cert
--master-ssl-cipher
--master-ssl-key
Die Datei master.info
in MySQL
5.1 enthält Werte, die den SSL-Optionen entsprechen.
Daneben sieht das Format dieser Datei in der ersten Zeile auch die
Nennung der Gesamtanzahl aller Zeilen in der Datei vor. Wenn Sie
einen älteren Server (vor MySQL 4.1.1) auf eine neuere Version
aktualisieren, setzt der neue Server die Datei
master.info
beim Start automatisch auf das
neue Format. Wenn Sie hingegen ein Downgrade auf einen älteren
Server durchführen, sollten Sie die erste Zeile manuell
entfernen, bevor Sie den älteren Server zum ersten Mal starten.
Ist beim Start des Slave-Servers keine Datei
master.info
vorhanden, dann werden für diese
Optionen die Werte verwendet, die in Optionsdateien oder auf der
Befehlszeile angegeben wurden. Dies ist etwa der Fall, wenn Sie
den Server zum ersten Mal als Replikationsslave starten, oder wenn
Sie RESET SLAVE
ausgeführt haben und den Slave
nun herunterfahren und neu starten.
Ist die Datei master.info
beim Start des
Slaves vorhanden, dann verarbeitet der Server ihren Inhalt und
ignoriert Werte, die für die in der Datei aufgeführten Optionen
übergeben wurden. Wenn Sie den Slave-Server also mit anderen
Werten für die Startoptionen starten als denen in der Datei
master.info
, dann haben die von Ihnen
übergebenen Werte keine Auswirkung, weil der Server die Angaben
der Datei master.info
entnimmt. Um andere
Werte verwenden zu können, müssen Sie entweder nach dem
Entfernen der Datei master.info
einen
Neustart durchführen oder die Werte bei laufendem Slave-Server
mit der Anweisung CHANGE MASTER TO
zurücksetzen (Letztere ist die empfohlene Methode).
Angenommen, Sie geben folgende Option in Ihrer Datei
my.cnf
an:
[mysqld]
master-host=some_host
Wenn Sie den Server zum ersten Mal als Replikationsslave starten,
liest und verwendet er diese Option aus der Datei
my.cnf
. Danach zeichnet der Server den Wert
in der Datei master.info
auf. Wenn Sie den
Server beim nächsten Mal starten, liest er den Master-Hostwert
nur aus der Datei master.info
und ignoriert
den Wert in der Optionsdatei. Wenn Sie später in der Datei
my.cnf
den anderen Master-Host
some_other_host
angeben, hat diese
Änderung keine Auswirkungen. Sie müssen stattdessen
CHANGE MASTER TO
verwenden.
Da der Server einer vorhandenen Datei
master.info
Vorrang vor den gerade
beschriebenen Startoptionen gewährt, sollten Sie diese Werte
unter Umständen überhaupt nicht mit Startoptionen angeben,
sondern sie stattdessen mit der CHANGE MASTER
TO
-Anweisung festlegen. Siehe auch
Abschnitt 13.6.2.1, „CHANGE MASTER TO
“.
Dieses Beispiel zeigt eine etwas umfangreichere Nutzung der Startoptionen zur Konfiguration eines Slave-Servers:
[mysqld] server-id=2 master-host=db-master.mycompany.com master-port=3306 master-user=pertinax master-password=freitag master-connect-retry=60 report-host=db-slave.mycompany.com
Die folgende Liste beschreibt die Startoptionen zur Steuerung der
Replikation. Viele dieser Optionen können bei laufendem Server
mit der Anweisung CHANGE MASTER TO
zurückgesetzt werden. Andere wie beispielsweise die
--replicate-*
-Optionen können nur beim Start des
Slave-Servers zurückgesetzt werden. Wir beabsichtigen dies zu
beheben.
--log-slave-updates
Normalerweise vermerkt ein Slave Updates, die er von einem
Master-Server erhalten hat, nicht in seinem eigenen Binärlog.
Diese Option weist den Slave jedoch an, Updates, die von
seinem SQL-Thread ausgeführt wurden, in sein eigenes
Binärlog zu schreiben. Damit diese Option Wirkung zeigt, muss
der Slave auch mit der Option --log-bin
gestartet werden, um das binäre Loggen zu aktivieren.
--log-slave-updates
wird verwendet, wenn Sie
Replikationsserver seriell verketten. Nehmen wir an, Sie
wollen die Replikationsserver wie folgt anordnen:
A -> B -> C
Hier dient A als Master von Slave B, und B agiert seinerseits
als Master von Slave C. Damit dies funktioniert, muss B
gleichermaßen Master und Slave sein. Sie
müssen A und B mit der Option --log-bin
starten, um das binäre Loggen zu aktivieren. Ferner muss B
auch mit der Option --log-slave-updates
gestartet werden, damit Änderungen, die von A empfangen
wurden, von B auch im eigenen Binärlog vermerkt werden.
--log-warnings
Mit dieser Option schreibt ein Server mehr Meldungen zu seinen
Aktionen in das Fehlerlog. In Hinsicht auf die Replikation
erzeugt der Server Warnungen, wenn er nach einem Netzwerk-
oder Verbindungsausfall eine Neuverbindung herstellen konnte,
und gibt auch an, wann die einzelnen Slave-Threads gestartet
wurden. Die Option ist standardmäßig aktiviert. Sie können
sie mithilfe von --skip-log-warnings
deaktivieren. Unterbrochene Verbindungen werden nicht in das
Fehlerlog protokolliert, sofern der Wert größer als 1 ist.
--master-connect-retry=
seconds
Die Anzahl von Sekunden, für die der Slave-Thread im Falle
eines Ausfalls der Verbindung oder des Master-Servers
schläft, bevor er eine Neuverbindung mit dem Master
herzustellen versucht. Der entsprechende Wert in der Datei
master.info
hat ggf. Vorrang. Ist der
Wert nicht angegeben, dann wird 60 als Vorgabe benutzt.
--master-host=
host_name
Hostname oder IP-Adresse des Master-Replikationsservers. Der
entsprechende Wert in der Datei
master.info
hat ggf. Vorrang. Ist kein
Master-Host angegeben, dann wird der Slave-Thread nicht
gestartet.
--master-info-file=
file_name
Der Name der Datei, in der der Slave Angaben zum Master
vermerkt. Der Standardname lautet
mysql.info
im Datenverzeichnis.
--master-password=
password
Das Passwort des Kontos, welches der Slave zur
Authentifizierung verwendet, wenn er sich beim Master
anmeldet. Der entsprechende Wert in der Datei
master.info
hat ggf. Vorrang. Sofern
nicht angegeben, wird ein leeres Passwort angenommen.
--master-port=
port_number
Die Nummer des TCP/IP-Ports, auf dem der Master horcht. Der
entsprechende Wert in der Datei
master.info
hat ggf. Vorrang. Sofern
nicht angegeben, wird der einkompilierte Wert (normalerweise
3306) als Vorgabe verwendet.
--master-retry-count=
count
Häufigkeit, mit der der Slave eine Neuverbindung mit dem Master probiert, bevor er aufgibt.
--master-ssl
,
--master-ssl-ca=
,
file_name
--master-ssl-capath=
,
directory_name
--master-ssl-cert=
,
file_name
--master-ssl-cipher=
,
cipher_list
--master-ssl-key=
file_name
Diese Optionen werden zur Einstellung einer sicheren,
SSL-verschlüsselten Replikationsverbindung zum Master-Server
benutzt. Die Bedeutungen sind mit denen der entsprechenden
Optionen --ssl
, --ssl-ca
,
--ssl-capath
, --ssl-cert
,
--ssl-cipher
und --ssl-key
identisch, die in Abschnitt 5.9.7.5, „SSL-Befehlsoptionen“, beschrieben
werden. Die entsprechenden Werte in der Datei
master.info
haben ggf. Vorrang.
--master-user=
user_name
Der Benutzername des Kontos, welches der Slave zur
Authentifizierung verwendet, wenn er sich beim Master
anmeldet. Dieses Konto benötigt die Berechtigung
REPLICATION SLAVE
. Der entsprechende Wert
in der Datei master.info
hat ggf.
Vorrang. Wenn der Master-Benutzername nicht angegeben ist,
wird der Name test
als Vorgabe verwendet.
--max-relay-log-size=
size
Größe, bei der der Server die Relay-Logs automatisch rotiert. Weitere Informationen finden Sie unter Abschnitt 6.4.4, „Relay- und Statusdateien bei der Replikation“.
--read-only
Bewirkt, dass der Slave keine Updates gestattet, sofern diese
nicht von Slave-Threads oder von Benutzern mit der
Berechtigung SUPER
stammen. Auf diese Weise
lässt sich sicherstellen, dass ein Slave-Server keine
Aktualisierungen von Clients akzeptiert. Diese Option gilt
nicht für TEMPORARY
-Tabellen.
--relay-log=
file_name
Der Name des Relay-Logs. Der Standardname lautet
,
wobei host_name
-relay-bin.nnnnnn
host_name
der Name des
Slave-Serverhosts ist und nnnnnn
angibt, dass Relay-Logs mit fortlaufender Nummerierung
erstellt werden. Sie können die Option angeben, um vom
Hostnamen unabhängige Namen für Relay-Logs zu erstellen.
Ferner ist sie praktisch, wenn Ihre Relay-Logs dazu tendieren,
sehr groß zu werden (und Sie
max_relay_log_size
nicht verringern
wollen), und Sie sie an einer anderen Position als im
Datenverzeichnis ablegen müssen, oder wenn Sie die
Geschwindigkeit durch eine Lastverteilung auf mehrere
Festplatten optimieren wollen.
--relay-log-index=
file_name
Der Name, der für die Indexdatei des Relay-Logs verwendet
wird. Der Standardname lautet
im Datenverzeichnis, wobei
host_name
-relay-bin.indexhost_name
der Name des
Slave-Servers ist.
--relay-log-info-file=
file_name
Der Name der Datei, in der der Slave Angaben zu den Relay-Logs
vermerkt. Der Standardname lautet
relay-log.info
im Datenverzeichnis.
--relay-log-purge={0|1}
Aktiviert oder deaktiviert das automatische Löschen von
Relay-Logs, wenn sie nicht mehr benötigt werden. Der
Vorgabewert ist 1 (aktiviert). Dies ist eine globale Variable,
die dynamisch mit SET GLOBAL relay_log_purge =
geändert werden kann.
N
--relay-log-space-limit=
size
Diese Option setzt eine Obergrenze für die Gesamtgröße
aller Relay-Logs auf dem Slave, angegeben in Byte. Der Wert 0
hat die Bedeutung „unbeschränkt“. Die Option ist
praktisch auf Slave-Servern, bei denen die
Festplattenkapazität begrenzt ist. Wenn der Grenzwert
erreicht wird, beendet der I/O-Thread das Auslesen von
Ereignissen aus dem Binärlog des Masters, bis der SQL-Thread
aufgeholt und eine Anzahl nicht mehr benötigter Relay-Logs
gelöscht hat. Beachten Sie, dass das Limit nicht absolut ist:
Es gibt Fälle, in denen der SQL-Thread mehr Ereignisse
benötigt, bevor er Relay-Logs löschen kann. In diesem Fall
überschreitet der I/O-Thread den Grenzwert so weit, wie es
notwendig ist, damit der SQL-Thread einige Relay-Logs löschen
kann (andernfalls würde der Slave nämlich blockiert). Sie
sollten --relay-log-space-limit
auf einen
Wert setzen, der mindestens zweimal so groß ist wie der Wert
von --max-relay-log-size
(oder
--max-binlog-size
, sofern
--max-relay-log-size
0 ist). In diesem Fall
besteht die Möglichkeit, dass der I/O-Thread auf freien
Speicher warten muss, weil
--relay-log-space-limit
überschritten wurde,
der SQL-Thread aber kein Relay-Log löschen und deswegen die
Anforderung des I/O-Threads nicht bearbeiten kann. Also ist
der I/O-Thread gezwungen,
--relay-log-space-limit
vorübergehend zu
ignorieren.
--replicate-do-db=
db_name
Weist den Slave an, die Replikation auf Anweisungen zu
beschränken, deren Standarddatenbank (also die von
USE
gewählte Datenbank)
db_name
ist. Um mehrere Datenbanken
anzugeben, verwenden Sie diese Option mehrfach (d. h. jeweils
einmal pro Datenbank). Beachten Sie, dass hierbei keine
datenbankübergreifenden Anweisungen wie UPDATE
repliziert werden, solange eine andere
Datenbank (oder gar keine Datenbank) gewählt ist.
some_db.some_table
SET
foo='bar'
Hier ein Beispiel für etwas, das nicht so funktioniert, wie
Sie es vielleicht erwarten: Wenn der Slave mit der Option
--replicate-do-db=sales
gestartet wird und
Sie die folgenden Anweisungen auf dem Master absetzen, wird
die UPDATE
-Anweisung
nicht repliziert:
USE prices; UPDATE sales.january SET amount=amount+1000;
Der wichtigste Grund für dieses Verhalten nach dem Motto
„Nur die Standarddatenbank überprüfen“ besteht
darin, dass es schwierig ist, allein der Anweisung zu
entnehmen, ob sie repliziert werden soll (wenn Sie
beispielsweise DELETE
-Anweisungen für
mehrere Tabellen oder UPDATE
-Anweisungen
für mehrere Tabellen verwenden, die datenbankübergreifend
agieren). Außerdem geht es schneller, wenn nur die
Standarddatenbank (statt aller Datenbanken) überprüft wird,
sofern es keinen Grund dafür gibt.
Wenn Sie datenbankübergreifende Aktualisierungen zum Laufen
bringen wollen, verwenden Sie stattdessen
--replicate-wild-do-table=
.
Siehe auch Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
db_name
.%
--replicate-do-table=
db_name.tbl_name
Weist den Slave-Thread an, die Replikation auf die angegebene
Tabelle zu beschränken. Um mehrere Tabellen anzugeben,
verwenden Sie diese Option mehrfach (d. h. jeweils einmal pro
Tabelle). Dies funktioniert – anders als
--replicate-do-db
– auch bei
datenbankübergreifenden Änderungen. Siehe auch
Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
--replicate-ignore-db=
db_name
Weist den Slave an, keine Anweisungen zu replizieren, deren
Standarddatenbank (also die von USE
gewählte Datenbank) db_name
ist.
Um mehrere zu ignorierende Datenbanken anzugeben, verwenden
Sie diese Option mehrfach (d. h. jeweils einmal pro
Datenbank). Sie sollten die Option allerdings nicht angeben,
wenn Sie datenbankübergreifende Änderungen ausführen, die
aber nicht repliziert werden sollen. Siehe auch
Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
Hier ein Beispiel für etwas, das nicht so funktioniert, wie
Sie es vielleicht erwarten: Wenn der Slave mit der Option
--replicate-ignore-db=sales
gestartet wird
und Sie die folgenden Anweisungen auf dem Master absetzen,
wird die UPDATE
-Anweisung
nicht repliziert:
USE prices; UPDATE sales.january SET amount=amount+1000;
Wenn Sie datenbankübergreifende Aktualisierungen zum Laufen
bringen wollen, verwenden Sie stattdessen
--replicate-wild-ignore-table=
.
Siehe auch Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
db_name
.%
--replicate-ignore-table=
db_name.tbl_name
Weist den Slave-Thread an, eine Anweisung, die die angegebene
Tabelle ändert, auch dann nicht zu replizieren, wenn andere
Tabellen von derselben Anweisung geändert werden könnten. Um
mehrere zu ignorierende Tabellen anzugeben, verwenden Sie
diese Option mehrfach (d. h. jeweils einmal pro Tabelle).
Dies funktioniert – anders als
--replicate-ignore-db
– auch bei
datenbankübergreifenden Änderungen. Siehe auch
Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
--replicate-rewrite-db=
from_name
->to_name
Weist den Slave an, die Standarddatenbank (also die von
USE
gewählte Datenbank) in
to_name
zu übersetzen, wenn sie
auf dem Master den Namen from_name
hatte. Hiervon sind nur tabellenbezogene Anweisungen betroffen
(also keine Anweisungen wie CREATE
DATABASE
, DROP DATABASE
und
ALTER DATABASE
), und diese auch nur dann,
wenn from_name
die
Standarddatenbank auf dem Master ist. Dies funktioniert bei
datenbankübergreifenden Änderungen nicht. Die Übersetzung
des Datenbanknamens erfolgt vor dem
Prüfen der --replicate-*
-Regeln.
Wenn Sie diese Option auf der Befehlszeile verwenden und das
Zeichen ‘>
’ für Ihren
Befehls-Interpreter ein Sonderzeichen ist, müssen Sie den
Optionswert in Anführungszeichen setzen. Zum Beispiel:
shell> mysqld --replicate-rewrite-db="olddb
->newdb
"
--replicate-same-server-id
Wird auf Slave-Servern verwendet. Normalerweise sollten Sie
die Standardeinstellung 0 verwenden, um durch eine
Kreisreplikation verursachte Endlosschleifen zu verhindern.
Wenn Sie den Wert 1 wählen, überspringt der Slave keine
Ereignisse, die seine eigene Serverkennung enthalten – dies
ist normalerweise nur in seltenen Fällen gewollt. Der Wert 1
kann bei Verwendung von --log-slave-updates
nicht gewählt werden. Beachten Sie, dass der Slave-I/O-Thread
standardmäßig noch nicht einmal dann Ereignisse aus dem
Binärlog in das Relay-Log schreibt, wenn diese die Kennung
des Slaves aufweisen (diese Optimierung hilft beim Einsparen
von Festplattenkapazität). Wenn Sie also
--replicate-same-server-id
verwenden wollen,
müssen Sie den Slave in jedem Fall mit dieser Option starten,
bevor Sie ihn dazu bringen, eigene Ereignisse zu lesen, die
der Slave-SQL-Thread ausführen soll.
--replicate-wild-do-table=
db_name.tbl_name
Weist den Slave-Thread an, die Replikation auf Anweisungen zu
beschränken, bei denen die aktualisierten Tabellen den
angegebenen Mustern für Datenbank- und Tabellennamen
entsprechen. Muster dürfen die Jokerzeichen
‘%
’ und
‘_
’ enthalten; diese haben
dieselbe Bedeutung wie beim Mustervergleichsoperator
LIKE
. Um mehrere Tabellen anzugeben,
verwenden Sie diese Option mehrfach (d. h. jeweils einmal pro
Tabelle). Dies funktioniert bei datenbankübergreifenden
Änderungen. Siehe auch
Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
Beispiel: --replicate-wild-do-table=foo%.bar%
repliziert nur Updates, die eine Tabelle betreffen, bei der
der Datenbankname mit foo
und der
Tabellenname mit bar
beginnt.
Wenn als Muster für den Tabellennamen %
angegeben wird, dann liegt eine Entsprechung für jeden
Tabellennamen vor, und die Option gilt auch für Anweisungen
auf Datenbankebene (CREATE DATABASE
,
DROP DATABASE
und ALTER
DATABASE
). Wenn Sie beispielsweise
--replicate-wild-do-table=foo%.%
angeben,
werden die Anweisungen auf Datenbankebene repliziert, wenn der
Datenbankname foo%
entspricht.
Um Jokerzeichen literal in den Mustern für Datenbank- oder
Tabellennamen zu verwenden, kennzeichnen Sie sie mit einem
Backslash. Um also beispielsweise alle Tabellen einer
Datenbank namens my_own%db
zu replizieren,
nicht aber Tabellen aus my1ownAABCdb
,
sollten Sie die Zeichen ‘_
’ und
‘%
’ wie folgt kennzeichnen:
--replicate-wild-do-table=my\_own\%db
. Wenn
Sie die Option auf der Befehlszeile angeben, müssen Sie unter
Umständen je nach Befehls-Interpreter die Backslashes
verdoppeln oder den Optionswert in Anführungszeichen setzen.
So müssen Sie bei der bash-Shell etwa
--replicate-wild-do-table=my\\_own\\%db
angeben.
--replicate-wild-ignore-table=
db_name.tbl_name
Weist den Slave-Thread an, eine Anweisung nicht zu replizieren, bei der eine beliebige Tabelle dem angegebenen Jokerzeichenmuster entspricht. Um mehrere zu ignorierende Tabellen anzugeben, verwenden Sie diese Option mehrfach (d. h. jeweils einmal pro Tabelle). Dies funktioniert bei datenbankübergreifenden Änderungen. Siehe auch Abschnitt 6.10, „Wie Server Replikationsregeln auswerten“.
Beispiel:
--replicate-wild-ignore-table=foo%.bar%
repliziert keine Updates, die eine Tabelle betreffen, bei der
der Datenbankname mit foo
und der
Tabellenname mit bar
beginnt.
Informationen zur Funktionsweise von Mustervergleichen
entnehmen Sie der Beschreibung zur Option
--replicate-wild-do-table
. Die Regeln zur
Verwendung literaler Jokerzeichen im Optionswert sind
dieselben wie bei
--replicate-wild-ignore-table
.
--report-host=
slave_name
Hostname oder IP-Adresse des Slaves, der oder die bei der
Slave-Registrierung an den Master gemeldet wurde. Dieser Wert
erscheint in der Ausgabe von SHOW SLAVE
HOSTS
auf dem Master-Server. Lassen Sie den Wert
ungesetzt, wenn Sie nicht wollen, dass der Slave sich
selbstständig beim Master registriert. Beachten Sie, dass es
für den Master nicht ausreichend ist, die IP-Adresse des
Slaves bei dessen Verbindungsherstellung einfach dem
TCP/IP-Socket zu entnehmen. Aufgrund der
Netzadressübersetzung (NAT) und anderer Routing-relevanter
Probleme kann diese IP-Adresse unter Umständen nicht
verwendet werden, um den Slave vom Master oder anderen Hosts
aus zu kontaktieren.
--report-port=
slave_port_num
Die Nummer des TCP/IP-Ports zur Verbindung mit dem Slave, die bei der Slave-Registrierung an den Master gemeldet wurde. Nehmen Sie die Einstellung nur vor, wenn der Slave nicht auch einem Standardport lauscht oder Sie einen speziellen Tunnel vom Master oder anderen Clients zum Slave verwenden. Wenn Sie sich nicht sicher sind, verwenden Sie die Option nicht.
--skip-slave-start
Weist den Slave-Server an, die Slave-Threads nicht zu starten,
wenn der Server startet. Um die Threads später zu starten,
können Sie die Anweisung START SLAVE
verwenden.
--slave_compressed_protocol={0|1}
Wenn diese Option auf 1 gesetzt ist, wird eine Komprimierung des Slave/Master-Protokolls verwendet, wenn sowohl Slave als auch Master diese unterstützen.
--slave-load-tmpdir=
file_name
Der Name des Verzeichnisses, in dem der Slave Temporärdateien
erstellt. Diese Option entspricht standardmäßig dem Wert der
Systemvariablen tmpdir
. Wenn der
Slave-SQL-Thread eine LOAD DATA
INFILE
-Anweisung repliziert, extrahiert er die zu
ladende Datei aus dem Relay-Log in Temporärdateien und lädt
diese dann in die Tabelle. Wenn die auf dem Master geladene
Datei sehr groß ist, sind auch die Temporärdateien auf dem
Slave groß. Aus diesem Grund kann es sich empfehlen, den
Slave mit dieser Option anzuweisen, die Temporärdateien in
ein Verzeichnis auf einem Dateisystem zu speichern, auf dem
ausreichend viel Festplattenkapazität vorhanden ist. In
diesem Fall sind auch die Relay-Logs riesig, weswegen Sie auch
diese mit der Option --relay-log
gleichermaßen auf jenem Dateisystem ablegen sollten.
Das mit dieser Option angegebene Verzeichnis sollte auf einem
festplattenbasierten (d. h. nicht speicherresidenten)
Dateisystem liegen, da die Temporärdateien, die zur
Replikation von LOAD DATA INFILE
verwendet
werden, einen Systemneustart überdauern müssen. Das
Verzeichnis sollte außerdem nicht eines sein, welches beim
Systemstart vom Betriebssystem geleert wird.
--slave-net-timeout=
seconds
Anzahl der Sekunden, für die auf weitere Daten vom Master
gewartet wird, bevor der Slave die Verbindung als unterbrochen
betrachtet, den Lesevorgang abbricht und eine Neuverbindung
probiert. Der erste Versuch findet unmittelbar nach
Überschreiten dieses Werts statt. Die Abstände zwischen den
Neuversuchen werden von der Option
--master-connect-retry
gesteuert.
--slave-skip-errors=[
err_code1
,err_code2
,...|all]
Normalerweise wird die Replikation beendet, wenn ein Fehler auf dem Slave auftritt. Sie haben auf diese Weise die Möglichkeit, Inkonsistenzen in den Daten manuell zu beheben. Diese Option weist den Slave-SQL-Thread an, mit der Replikation fortzufahren, wenn eine Anweisung einen der im Optionswert aufgeführten Fehler zurückgibt.
Verwenden Sie diese Option nicht, sofern Sie nicht genau wissen, warum Sie Fehler erhalten. Sind in Ihrer Replikationskonfiguration und Clientprogrammen ebenso wenig Fehler vorhanden wie Bugs in MySQL, dann sollte eigentlich nie ein Fehler auftreten, der die Replikation beendet. Die unüberlegte Verwendung dieser Option hat zur Folge, dass die Synchronisation zwischen Master und Slave unwiederbringlich verloren geht, ohne dass Sie überhaupt wissen, warum dies so ist.
Die Fehlercodes sind als Zahlenangaben in den Fehlermeldungen
im Fehlerlog des Slaves und in der Ausgabe von SHOW
SLAVE STATUS
enthalten.
Anhang B, Fehlercodes und -meldungen, listet die Serverfehlercodes
auf.
Sie könnten theoretisch auch den nicht sehr empfehlenswerten
Wert all
angeben, damit der Slave alle
Fehlermeldungen ignoriert und weiterarbeitet – egal, was
auch passiert. Aber das sollten Sie besser lassen.
Selbstredend gibt es, wenn Sie all
verwenden, keine Garantie bezüglich der Datenintegrität.
Sollten die Daten auf dem Slave in einem solchen Fall auch
nicht annähernd denen auf dem Master entsprechen, so bitten
wir von Beschwerden (und der Meldung von Bugs) abzusehen.
Wir haben Sie gewarnt!
Ein paar Beispiele:
--slave-skip-errors=1062,1053 --slave-skip-errors=all
Wenn ein Master-Server keine Anweisung in sein Binärlog schreibt, wird die Anweisung auch nicht repliziert. Schreibt der Server die Anweisung hingegen in das Log, dann wird die Anweisung an alle Slaves geschickt, und jeder Slave bestimmt, ob er sie ausführt oder ignoriert.
Auf der Master-Seite basieren die Entscheidungen darüber, welche
Anweisungen zu loggen sind, auf den Optionen
--binlog-do-db
und
--binlog-ignore-db
, die das binäre Loggen
steuern. Eine Beschreibung der Regeln, die der Server bei der
Auswertung dieser Optionen verwendet, finden Sie in
Abschnitt 5.12.3, „Die binäre Update-Logdatei“.
Auf der Slave-Seite werden die Entscheidungen darüber, ob und
welche vom Master empfangenen Anweisungen ausgeführt oder
ignoriert werden, entsprechend den
--replicate-*
-Optionen getroffen, mit denen der
Slave gestartet wurde. Der Slave wertet diese Optionen
entsprechend der folgenden Vorgehensweise aus.
Sind --replicate-do-db
- oder
--replicate-ignore-db
-Optionen vorhanden?
Ja: Unter Verwendung derselben Regeln
testen wie bei den Optionen
--binlog-do-db
und
--binlog-ignore-db
. Welches Ergebnis hat
der Test?
Anweisung ignorieren: Ignorieren und beenden.
Anweisung zulassen: Anweisung nicht sofort ausführen, sondern die Entscheidung verschieben. Mit nächstem Schritt fortfahren.
Nein: Mit nächstem Schritt fortfahren.
Wird gerade eine gespeicherte Funktion ausgeführt?
Ja: Abfrage ausführen und beenden.
Nein: Mit nächstem Schritt fortfahren.
Sind --replicate-*-table
-Optionen vorhanden?
Nein: Abfrage ausführen und beenden.
Ja: In diesem Fall hängt das Verhalten davon ab, ob die anweisungsbasierte Replikation oder die datensatzbasierte Replikation verwendet wird:
Anweisungsbasierte Replikation:
Mit nächstem Schritt fortfahren und mit der
Auswertung der Tabellenregeln in der angegebenen
Reihenfolge (zuerst die Nicht-„wild“-,
dann die „wild“-Regeln) beginnen. Nur
Tabellen, die aktualisiert werden sollen, werden mit
den Regeln verglichen. Heißt die Anweisung etwa
INSERT INTO sales SELECT * FROM
prices
, dann wird nur
sales
mit den Regeln verglichen.
Wenn mehrere Tabellen durch eine entsprechende
Anweisung aktualisiert werden, gewinnt die erste
Tabelle, die „Do“ oder
„Ignore“ entspricht: Der Server
vergleicht die erste Tabelle also mit den Regeln.
Konnte keine Entscheidung getroffen werden, dann
überprüft er die zweite Tabelle usw.
Datensatzbasierte Replikation:
Alle Änderungen an Tabellendatensätzen werden
einzeln gefiltert. Bei Updates für mehrere Tabellen
wird jede Tabelle entsprechend den Regeln separat
gefiltert. Einige Änderungen werden ausgeführt,
andere unter Umständen nicht – dies hängt jeweils
von den Regeln und den vorgenommenen Änderungen ab.
Die datensatzbasierte Replikation verarbeitet Fälle,
die bei der anweisungsbasierten Replikation nicht
korrekt repliziert würden, ihrerseits korrekt.
Betrachten Sie folgendes Beispiel, welches davon
ausgeht, dass Tabellen in der Datenbank
foo
repliziert werden sollen:
mysql>USE bar;
mysql>INSERT INTO foo.sometable VALUES (1);
Gibt es --replicate-do-table
-Regeln?
Ja: Entspricht die Tabelle einer dieser Regeln?
Ja: Abfrage ausführen und beenden.
Nein: Mit nächstem Schritt fortfahren.
Nein: Mit nächstem Schritt fortfahren.
Gibt es --replicate-ignore-table
-Regeln?
Ja: Entspricht die Tabelle einer dieser Regeln?
Ja: Abfrage ignorieren und beenden.
Nein: Mit nächstem Schritt fortfahren.
Nein: Mit nächstem Schritt fortfahren.
Gibt es --replicate-wild-do-table
-Regeln?
Ja: Entspricht die Tabelle einer dieser Regeln?
Ja: Abfrage ausführen und beenden.
Nein: Mit nächstem Schritt fortfahren.
Nein: Mit nächstem Schritt fortfahren.
Gibt es --replicate-wild-ignore-table
-Regeln?
Ja: Entspricht die Tabelle einer dieser Regeln?
Ja: Abfrage ignorieren und beenden.
Nein: Mit nächstem Schritt fortfahren.
Nein: Mit nächstem Schritt fortfahren.
Es gab keine Entsprechung für eine
--replicate-*-table
-Regel. Gibt es noch eine
weitere Tabelle, die auf diese Regeln geprüft werden kann?
Ja: Schleife wiederholen.
Nein: Wir haben nun alle zu
aktualisierenden Tabellen getestet und konnten keine
Übereinstimmung mit einer Regel finden. Sind
--replicate-do-table
- oder
--replicate-wild-do-table
-Regeln
vorhanden?
Ja: Es gab „Do“-Regeln, aber keine Übereinstimmung. Abfrage ignorieren und beenden.
Nein: Abfrage ausführen und beenden.
Frage: Wie konfiguriere ich einen Slave, wenn der Master ausgeführt wird und ich ihn nicht anhalten will?
Antwort: Es gibt mehrere
Möglichkeiten. Wenn Sie zu einem bestimmten Zeitpunkt ein auf
einer Momentaufnahme basiertes Backup des Masters erstellt und den
Binärlognamen und den Versatz (aus der Ausgabe von SHOW
MASTER STATUS
) für die Momentaufnahme notiert haben,
gehen Sie wie folgt vor:
Stellen Sie sicher, dass der Slave eine eindeutige Serverkennung hat.
Führen Sie die folgende Anweisung auf dem Slave aus. Geben Sie dabei für jede Option die passenden Werte an:
mysql>CHANGE MASTER TO
->MASTER_HOST='
->master_host_name
',MASTER_USER='
->master_user_name
',MASTER_PASSWORD='
->master_pass
',MASTER_LOG_FILE='
->recorded_log_file_name
',MASTER_LOG_POS=
recorded_log_position
;
Führen Sie START SLAVE
auf dem Slave aus.
Wenn Sie über keine Sicherungskopie des Master-Servers verfügen, können Sie wie nachfolgend beschrieben ganz einfach eine solche erstellen. Alle Schritte sind dabei auf dem Master-Host durchzuführen.
Setzen Sie die folgende Anweisung ab, um eine globale Lesesperre zu erwirken:
mysql> FLUSH TABLES WITH READ LOCK;
Führen Sie bei weiterhin aktiver Sperre den folgenden Befehl (oder eine entsprechende Variante) aus:
shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
Setzen Sie nun folgende Anweisung ab und notieren Sie die Ausgabe (Sie werden sie später noch benötigen):
mysql> SHOW MASTER STATUS;
Heben Sie die Sperre auf:
mysql> UNLOCK TABLES;
Eine Alternative zu dieser Vorgehensweise zur Erstellung einer binären Kopie besteht darin, einen SQL-Speicherauszug des Masters zu erstellen. Hierzu führen Sie mysqldump --master-data auf dem Master aus und laden die SQL-Speicherauszugsdatei später in Ihren Slave. Allerdings ist die Erstellung einer binären Kopie schneller.
Unabhängig davon, welche der beiden Methoden Sie verwenden, befolgen Sie danach die Anleitung für den Fall, dass Sie eine Momentaufnahme erstellt und den Logdateinamen und den Offset vermerkt haben. Sie können dieselbe Momentaufnahme mehrfach verwenden. Wenn Sie die Momentaufnahme des Masters erst einmal haben, können Sie beliebig lang mit der Konfiguration des Slaves warten: Es müssen lediglich die Binärlogs auf dem Master intakt bleiben. Allerdings bestehen zwei praktische Beschränkungen, die Sie beachten müssen: Sie dürfen nicht länger als notwendig warten, um zu vermeiden, dass die zur Aufnahme der Binärlogs auf dem Master erforderliche Speichermenge zu groß wird und dass der Slave nicht schnell genug auf den Stand des Masters gebracht werden kann.
Sie können außerdem LOAD DATA FROM MASTER
verwenden. Dies ist eine praktische Anweisung, die eine
Momentaufnahme auf den Slave überträgt und gleichzeitig auch
noch den Logdateinamen und den Versatz automatisch einstellt.
Zukünftig wird LOAD DATA FROM MASTER
die
empfohlene Vorgehensweise zur Konfiguration eines Slaves werden.
Beachten Sie allerdings, dass die Anweisung nur bei
MyISAM
-Tabellen funktioniert und für einen
relativ langen Zeitraum eine Lesesperre setzt. Sie ist noch nicht
so effektiv implementiert, wie wir uns das wünschen. Wenn Sie
größere Tabellen haben, besteht die bevorzugte Methode also
derzeit noch darin, nach der Ausführung von FLUSH TABLES
WITH READ LOCK
eine binäre Momentaufnahme auf dem
Master-Server zu erstellen.
Frage: Muss der Slave fortlaufend mit dem Master verbunden sein?
Antwort: Nein. Der Slave kann stunden- oder sogar tagelang ausgeschaltet oder getrennt sein – erfolgt eine Neuverbindung, dann werden alle Aktualisierungen aufgeholt. Sie können beispielsweise eine Master/Slave-Beziehung über eine Wählverbindung konfigurieren, bei der die Verbindung nur sporadisch und nur für kurze Zeit hergestellt wird. Eine Auswirkung hiervon ist natürlich, dass man zu keinem Zeitpunkt die Synchronisation zwischen Slave und Master gewährleisten kann, sofern nicht bestimmte Maßnahmen ergriffen werden. Zukünftig wird eine Option eingeführt werden, mit der der Master blockiert wird, bis mindestens ein Slave synchronisiert wurde.
Frage: Wie erkenne ich, wie weit ein Slave im Vergleich zum Master im Rückstand ist? Anders formuliert: Wie ermittle ich den Zeitpunkt der letzten vom Slave replizierten Abfrage?
Antwort: Lesen Sie die Spalte
Seconds_Behind_Master
in der Ausgabe von
SHOW SLAVE STATUS
aus. Siehe auch
Abschnitt 6.4, „Replikation: Implementationsdetails“.
Wenn der Slave-SQL-Thread ein Ereignis ausführt, welches er vom
Master gelesen hat, dann setzt er seine eigene Zeit auf den
Zeitstempel des Ereignisses um. (Dies ist auch Voraussetzung
dafür, dass TIMESTAMP
korrekt repliziert
wird.) In der Spalte Time
der Ausgabe von
SHOW PROCESSLIST
beschreibt die angezeigte
Sekundenzahl für den Slave-SQL-Thread die Anzahl der Sekunden
zwischen dem Zeitstempel des letzten replizierten Ereignisses und
der Echtzeit des Slave-Systems. Auf diese Weise können Sie den
Zeitpunkt des letzten replizierten Ereignisses ermitteln. Beachten
Sie, dass, wenn Ihr Slave für eine Stunde vom Master getrennt
wurde und dann eine neue Verbindung herstellt, in der Spalte
Time
sofort Werte wie 3600 für den
Slave-SQL-Thread in der Ausgabe von SHOW
PROCESSLIST
erscheinen. Dies liegt daran, dass der Slave
Anweisungen ausführt, die eine Stunde alt sind.
Frage: Wie kann ich den Master zwingen, Updates zu sperren, bis der Slave den Rückstand aufgeholt hat?
Antwort: Gehen Sie wie folgt vor:
Führen Sie auf dem Master die folgenden Anweisungen aus:
mysql>FLUSH TABLES WITH READ LOCK;
mysql>SHOW MASTER STATUS;
Notieren Sie die Replikationskoordinaten (Logdateiname und
Versatz) in der Ausgabe der SHOW
-Anweisung.
Setzen Sie auf dem Slave folgende Anweisung ab. Die Argumente
für die Funktion MASTER_POS_WAIT()
sind
die Replikationskoordinaten, die Sie im vorherigen Schritt
ermittelt haben:
mysql> SELECT MASTER_POS_WAIT('log_name
', log_offset
);
Die SELECT
-Anweisung sperrt den Master, bis
der Slave die entsprechende Position in der angegebenen
Logdatei erreicht hat. An dieser Stelle läuft der Slave
synchron zum Master, und die Anweisung gibt ihre Werte
zurück.
Setzen Sie nun auf dem Master die folgende Anweisung ab, damit er wieder Updates verarbeiten kann:
mysql> UNLOCK TABLES;
Frage: Welche Aspekte muss ich bei der Konfiguration der 2-Wege-Replikation beachten?
Antwort: Die MySQL-Replikation unterstützt derzeit kein Sperrprotokoll zwischen Master und Server, mit dem die Atomizität eines verteilten (serverübergreifenden) Updates gewährleistet werden kann. Es ist also möglich, dass Client A ein Update auf dem Co-Master 1 vornimmt, während gleichzeitig (also bevor dieses Update an den Co-Master 2 weitergegeben wird) Client B ein Update auf dem Co-Master 2 durchführt, welches für das Update von Client A eine andere Wirkung hervorruft als auf Co-Master 1. Auf diese Weise erzeugt das Update von Client A nach der Ankunft auf dem Co-Master 2 Tabellen, die sich von denen auf dem Co-Master 1 unterscheiden – und zwar auch, nachdem alle Updates von Co-Master 2 ebenfalls weitergegeben wurden. Dies bedeutet, dass Sie niemals zwei Server in einer 2-Wege-Replikationsbeziehung miteinander verketten sollten, sofern Sie nicht sicher sind, dass Ihre Updates in beliebiger Reihenfolge erfolgen können, oder im Clientcode den Fall unterschiedlicher Updatereihenfolgen irgendwie berücksichtigen.
Sie sollten auch daran denken, dass, soweit es Updates betrifft, die 2-Wege-Replikation die Leistungsfähigkeit – sofern überhaupt – nicht allzu sehr optimiert. Jeder Server muss dieselbe Anzahl von Updates ausführen – ebenso wie es auch bei nur einem Server der Fall wäre. Der einzige Unterschied besteht darin, dass es zu weniger konkurrierenden Sperranforderungen kommt, weil die Updates, die von einem anderen Server kommen, in nur einem Slave-Thread serialisiert werden. Aber auch dieser Vorteil kann durch Netzwerklatenzen schon wieder aufgewogen werden.
Frage: Wie kann ich mit der Replikation die Leistung meines Systems verbessern?
Antwort: Sie sollten einen Server
als Master konfigurieren und alle Schreiboperationen an ihn
richten. Nachfolgend sollten Sie so viele Slaves einrichten, wie
es Budget und Platzverhältnisse zulassen, und Leseoperationen
dann auf Master und Slaves verteilen. Sie können die Slaves auch
mit den Optionen --skip-innodb
,
--skip-bdb
,
--low-priority-updates
und
--delay-key-write=ALL
starten, um Slave-seitig
Geschwindigkeitsvorteile erzielen zu können. In diesem Fall
verwendet der Slave nichttransaktionssichere
MyISAM
-Tabellen statt
InnoDB
- und BDB
-Tabellen, um
den transaktionsbedingten Mehraufwand zu umgehen und die
Geschwindigkeit so zu steigern.
Frage: Was kann ich tun, um den Clientcode in meinen eigenen Anwendungen so zu formulieren, dass eine leistungssteigernde Replikation verwendet wird?
Antwort: Wenn der Teil Ihres Codes, der für den Datenbankzugriff zuständig ist, einwandfrei abstrahiert bzw. modularisiert ist, sollte die Konvertierung in eine Form, die in einer Replikationskonfiguration läuft, schnell und einfach erfolgen. Ändern Sie die Implementierung Ihres Datenbankzugriffs so, dass alle Schreiboperationen an den Master gesendet werden, und senden Sie die Leseoperationen an den Master oder einen Slave. Wenn Ihr Code nicht derart abstrahierbar ist, bietet Ihnen die Konfiguration eines Replikationssystems vielleicht die Möglichkeit und die Motivation, ihn entsprechend zu bereinigen. Erstellen Sie zunächst eine Wrapper-Bibliothek oder ein Wrapper-Modul, das die folgenden Funktionen implementiert:
safe_writer_connect()
safe_reader_connect()
safe_reader_statement()
safe_writer_statement()
Der Namensteil safe_
in den Funktionsnamen
verweist darauf, dass die jeweilige Funktion alle
Fehlerbedingungen selbst abfängt. Sie können für die Funktionen
auch andere Namen verwenden. Wichtig ist lediglich, dass Sie über
eine einheitliche Schnittstelle verfügen, um Lese- und
Schreibverbindungen herzustellen und Lese- oder Schreiboperationen
auszuführen.
Nachfolgend konvertieren Sie Ihren Clientcode so, dass er die Wrapper-Bibliothek verwendet. Unter Umständen ist dies anfangs ein schmerzlicher und beängstigender Vorgang, der sich aber langfristig auszahlt. Alle Anwendungen, die den gerade beschriebenen Ansatz verfolgen, können von einer Master/Slave-Konfiguration profitieren, auch wenn diese mehrere Slaves umfasst. Der Code ist weitaus einfacher zu pflegen, und das Hinzufügen von Problembehandlungsoptionen ist trivial. Sie müssen nur ein oder zwei Funktionen modifizieren – beispielsweise, wie lang eine Anweisung zur Ausführung benötigte oder welche der abgesetzten Anweisungen den Fehler zurückgegeben hat.
Wenn Sie viel Code geschrieben haben, sollten Sie diese Konvertierungsarbeit mit dem Hilfsprogramm replace automatisieren, welches Bestandteil der MySQL-Standarddistributionen ist, oder Ihr eigenes Konvertierungsskript abfassen. Im Idealfall verwendet Ihr Code konsistent die gängigen Stilkonventionen bei der Programmierung. Andernfalls wird es ohnehin einfacher sein, ihn neu zu erstellen oder ihn zumindest durchzuarbeiten und dabei manuell so zu vereinheitlichen, dass der Stil konsistent ist.
Frage: Wie stark und unter welchen Umständen kann die MySQL-Replikation die Leistung meines Systems verbessern?
Antwort: Die MySQL-Replikation ist am vorteilhaftesten für Systeme, die häufig Leseoperationen und seltener Schreiboperationen verarbeiten müssen. Theoretisch können Sie Ihr System bei Implementierung einer Konfiguration mit einem Master und mehreren Slaves skalieren, indem Sie weitere Slaves hinzufügen, bis entweder Ihre Netzwerkbandbreite erschöpft ist oder Ihr Aktualisierungsaufkommen so stark zugenommen hat, dass es der Master nicht mehr verarbeiten kann.
Um zu ermitteln, wie viele Slaves Sie verwenden können, bevor die
Vorteile sich zu relativieren beginnen, und wie weit Sie die
Leistungsfähigkeit Ihres Standorts verbessern können, müssen
Sie Ihre Abfragemuster und das Verhältnis zwischen dem Durchsatz
für Leseoperationen (Leseoperationen/Sekunde oder
reads
) und Schreiboperationen
(writes
)
kennen auf einem typischen Master und einem typischen Slave durch
Benchmark-Tests in Erfahrung bringen. Das folgende Beispiel zeigt
eine relativ stark vereinfachte Berechnung der Auswirkungen der
Replikation auf einem hypothetischen System.
Angenommen, die Systemlast umfasst 10 Prozent Schreiboperationen
und 90 Prozent Leseoperationen. Durch ein Benchmarking haben wir
ermittelt, dass reads
1200 – 2 ×
writes
ist. Anders gesagt, kann das System 1200
Leseoperationen pro Sekunde ohne Schreiboperationen verarbeiten,
ein Schreibvorgang erfolgt durchschnittlich halb so schnell wie
ein Lesevorgang, und die Beziehung ist linear. Nehmen wir nun
ferner an, dass der Master und jeder Slave jeweils die gleiche
Kapazität aufweisen und dass wir einen Master und
N
Slaves haben. Daraus ergibt sich für
jeden Server (Master oder Slave):
reads = 1200 – 2 × writes
reads = 9 × writes / (
(Leseoperationen werden aufgeteilt, während
Schreiboperationen an alle Server gehen)
N
+ 1)
9 × writes / (
N
+ 1) + 2
× writes = 1200
writes = 1200 / (2 +
9/(
N
+1))
Die letzte Gleichung gibt die maximale Anzahl von
Schreibvorgängen für N
Slaves
basierend auf einer maximalen Leserate von 1200 pro Minute und
einem Verhältnis von neun Leseoperationen pro Schreiboperation
an.
Diese Analyse lässt die folgenden Rückschlüsse zu:
Wenn N
= 0 ist (d. h. keine
Replikation), dann kann unser System ca. 1200 ÷ 11 = 109
Schreiboperationen pro Sekunde verarbeiten.
Bei N
= 1 sind 184
Schreiboperationen pro Sekunde möglich.
Bei N
= 8 sind 400
Schreiboperationen pro Sekunde möglich.
Bei N
= 17 sind 480
Schreiboperationen pro Sekunde möglich.
Schließlich kommen wir, je mehr sich
N
der Unendlichkeit (und unserem
Budget der negativen Unendlichkeit) annähert, auf einen Wert
von 600 Schreiboperationen pro Sekunde, während wir unseren
Systemdurchsatz etwa auf das 5,5fache gesteigert haben. Bei
nur acht Servern beträgt die Steigerung hingegen knapp das
Vierfache.
Beachten Sie, dass diese Berechnungen eine uneingeschränkte
Netzwerkbandbreite voraussetzen und mehrere andere Faktoren
vernachlässigen, die für Ihr System von Bedeutung sein könnten.
In vielen Fällen können Sie keine Berechnung ähnlich der obigen
durchführen, mit der sich exakt voraussagen ließe, wie sich das
Hinzufügen von N
Replikationsslaves
auf Ihr System auswirken würde. Allerdings kann Ihnen die
Beantwortung der folgenden Fragen dabei helfen, zu bestimmen, ob
und inwieweit eine Replikation die Leistungsfähigkeit Ihres
Systems verbessern könnte:
Welches Verhältnis besteht zwischen Lese- und Schreiboperationen auf Ihrem System?
Wie viel mehr Schreiboperationen kann ein Server verarbeiten, wenn Sie die Anzahl der Leseoperationen verringern?
Wie viele Slaves unterstützt die Bandbreite in Ihrem Netzwerk?
Frage: Wie kann ich mithilfe der Replikation eine Redundanz oder Hochverfügbarkeit realisieren?
Antwort: Mit den derzeit verfügbaren Funktionen sollten Sie einen Master und einen Slave (oder mehrere Slaves) einrichten und ein Skript verfassen, welches den Master auf Verfügbarkeit prüft. Dann weisen Sie Ihre Anwendungen und die Slaves an, bei einem Ausfall des Masters einen anderen Master zu wählen. Hier ein paar Vorschläge:
Verwenden Sie die CHANGE MASTER
TO
-Anweisung, um einen Slave anzuweisen, den Master
zu wechseln.
Eine gute Möglichkeit, Ihre Anwendungen bezüglich des
Standorts des Masters auf dem aktuellen Stand zu halten, ist
die Verwendung eines dynamischen DNS-Eintrags für den Master.
Bei bind
können Sie
nsupdate
verwenden, um Ihr DNS dynamisch
zu aktualisieren.
Starten Sie Ihre Slaves mit der Option
--log-bin
und ohne die Option
--log-slave-updates
. Auf diese Weise ist ein
Slave in der Lage, zum Master zu werden, sobald Sie die
Anweisungen STOP SLAVE
, RESET
MASTER
und CHANGE MASTER TO
auf
anderen Slaves absetzen. Angenommen, wir hätten folgende
Konfiguration:
WC \ v WC----> M / | \ / | \ v v v S1 S2 S3
In diesem Diagramm bezeichnet M
den Master,
S
die Slaves und WC
die
Clients, die Schreib- und Lesevorgänge an die Datenbank
absetzen. (Clients, die nur aus der Datenbank lesen, sind
nicht vorhanden, da bei ihnen keine Änderungen erforderlich
sind.) S1
, S2
und
S3
sind Slaves, die mit der Option
--log-bin
und ohne
--log-slave-updates
laufen. Da die von einem
Slave empfangenen Updates nicht im Binärlog vermerkt werden,
sofern nicht die Option --log-slave-updates
angegeben ist, sind die Binärlogs auf den Slaves anfangs
leer. Fällt nun M
aus irgendeinem Grund
aus, dann können Sie einen der Slaves auswählen, der dann
der neue Master wird. Wenn Sie also etwa S1
auswählen, sollten alle WC
auf
S1
umgelenkt werden, der die Updates in
sein Binärlog schreibt. S2
und
S3
replizieren nachfolgend von
S1
.
Sinn der Ausführung des Slaves ohne
--log-slave-updates
ist es, zu verhindern,
dass Slaves Updates zweimal erhalten, was vorkommen kann, wenn
einer der Slaves zum neuen Master wird. Nehmen wir einmal an,
bei S1
wäre die Option
--log-slave-updates
aktiviert. Er schreibt
nun Updates, die er von M
empfängt, in
sein eigenes Binärlog. Wenn S2
von
M
auf S1
also
umschaltet, empfängt er Updates von S1
,
die er bereits von M
erhalten hat.
Stellen Sie sicher, dass alle Slaves alle Anweisungen im
jeweiligen Relay-Log verarbeitet haben. Setzen Sie auf jedem
Slave STOP SLAVE IO_THREAD
ab und suchen
Sie dann in der Ausgabe von SHOW
PROCESSLIST
die Angabe Has read all relay
log
. Wenn dieser Zustand von allen Slaves erreicht
wurde, können sie auf die neue Konfiguration umgestellt
werden. Auf dem Slave S1
, der neuer Master
werden soll, setzen Sie STOP SLAVE
und
RESET MASTER
ab.
Auf den anderen Slaves S2
und
S3
setzen Sie STOP SLAVE
und CHANGE MASTER TO MASTER_HOST='S1'
ab
(wobei 'S1'
den echten Hostnamen von
S1
darstellt). Zu CHANGE
MASTER
fügen Sie nun alle Informationen darüber
hinzu, wie von S2
oder
S3
aus eine Verbindung mit
S1
hergestellt wird (also
user
,
password
,
port
). Sie müssen in
CHANGE MASTER
den Namen des Binärlogs von
S1
oder der Binärlogposition, ab der
gelesen werden soll, nicht angeben. Wir wissen, dass es das
erste Binärlog und die Position 4 ist (dies sind die
Standardwerte von CHANGE MASTER
).
Abschließend setzen Sie START SLAVE
auf
S2
und S3
ab.
Nun weisen Sie alle WC
an, ihre Anweisung
an S1
zu leiten. Von diesem Punkt an werden
alle Updateanweisungen, die von WC
an
S1
gesendet werden, in das Binärlog von
S1
geschrieben, welches dann alle
Updateanweisungen enthält, die seit dem Ausfall von
M
an S1
gesendet wurden.
Das Ergebnis ist folgende Konfiguration:
WC / | WC | M(unavailable) \ | \ | v v S1<--S2 S3 ^ | +-------+
Wenn M
wieder betriebsbereit ist, müssen
Sie darauf dieselbe CHANGE MASTER
-Anweisung
absetzen, die Sie auf S2
und
S3
verwendet haben, damit
M
ein Slave von S1
wird
und alle WC
-Schreiboperationen empfängt,
die er seit dem Ausfall verpasst hat. Um M
wieder zum Master zu machen (etwa weil es sich dabei um das
leistungsfähigste System handelt), verwenden Sie die
beschriebene Methode erneut und tun dabei so, als ob
S1
nicht mehr verfügbar wäre und
M
nun zum neuen Master wird. Während
dieses Vorgangs dürfen Sie nicht vergessen, RESET
MASTER
auf M
auszuführen, bevor
Sie S1
, S2
und
S3
zu Slaves von M
machen. Andernfalls empfangen diese Server alte
WC
-Schreiboperationen, die abgesetzt
wurden, bevor M
ausfiel.
Frage: Woher weiß ich, ob ein Master-Server das anweisungsbasierte oder das datensatzbasierte Binärlogformat verwendet?
Antwort: Überprüfen Sie den
Wert der Systemvariablen binlog_format
:
mysql> SHOW VARIABLES LIKE 'binlog_format';
Dieser heißt entweder STATEMENT
(anweisungsbasierte Replikation) oder ROW
(datensatzbasierte Replikation).
Frage: Wie weise ich einen Slave an, die datensatzbasierte Replikation zu verwenden?
Antwort: Slaves wissen automatisch, welches Format sie verwenden müssen.
Jedes Binärlogformat hat seine Vor- und Nachteile. Dieser Abschnitt fasst diese zusammen, um Ihnen eine Einschätzung zu erlauben, welches Format in Ihrer speziellen Situation das geeignetere ist.
Vorteile der anweisungsbasierten Replikation:
Bewährte Technologie, seit MySQL 3.23 vorhanden.
Kleinere Logdateien. Wenn Änderungs- oder Löschvorgänge viele Datensätze betreffen, sind die Logdateien wesentlich kleiner. Kleinere Logdateien erfordern weniger Speicherplatz und sind schneller gesichert.
Logdateien enthalten alle Anweisungen, mit denen Änderungen vorgenommen wurden, d. h., sie können zur Überwachung der Datenbank verwendet werden.
Logdateien können nicht nur zu Replikationszwecken, sondern auch zur Point-in-Time-Wiederherstellung verwendet werden. Siehe auch Abschnitt 5.10.3, „Zeitpunktbezogene Wiederherstellung“.
Ein Slave kann eine neuere MySQL-Version mit einer anderen Datensatzstruktur verwenden.
Nachteile der anweisungsbasierten Replikation:
Nicht alle UPDATE
-Anweisungen können
repliziert werden: Jedes nichtdeterministische Verhalten
(z. B. bei der Verwendung von Zufallsfunktionen in einer
SQL-Anweisung) ist bei der anweisungsbasierten Replikation
schwer zu replizieren. Bei Anweisungen, die eine
nichtdeterministische benutzerdefinierte Funktion
(User-Defined Function, UDF) verwenden, ist die Replikation
des Ergebnisses bei der anweisungsbasierten Replikation
überhaupt nicht möglich (dagegen repliziert die
datensatzbasierte Replikation einfach den von der UDF
zurückgegebenen Wert).
Anweisungen können nicht korrekt repliziert werden, wenn sie eine UDF verwenden, die nichtdeterministisch ist (d. h. deren Wert von anderen Aspekten als den übergebenen Parametern abhängt).
Anweisungen können nicht korrekt repliziert werden, wenn sie eine der folgenden Funktionen enthalten:
LOAD_FILE()
UUID()
USER()
FOUND_ROWS()
Alle übrigen Funktionen (einschließlich
RAND()
, NOW()
,
LOAD DATA INFILE
usw.) werden korrekt
repliziert.
INSERT ... SELECT
erfordert eine höhere
Zahl von Sperren auf Datensatzebene als bei der
datensatzbasierten Replikation.
UPDATE
-Anweisungen, die einen Tabellenscan
erfordern (weil in der WHERE
-Klausel kein
Index verwendet wird), müssen eine höhere Anzahl von
Datensätzen sperren als bei der datensatzbasierten
Replikation.
(Nur bei InnoDB
) Eine
INSERT
-Anweisung, die
AUTO_INCREMENT
verwendet, blockiert andere,
nicht kollidierende INSERT
-Anweisungen.
Langsamere Umsetzung von Daten auf dem Slave bei komplexen Abfragen.
Gespeicherte Funktionen (nicht aber gespeicherte Prozeduren)
werden mit demselben NOW()
-Wert wie die
aufrufende Anweisung ausgeführt. (Dies kann abhängig von den
Umständen ein Vor- oder Nachteil sein.)
Deterministische UDFs müssen auf die Slaves angewendet werden.
Wenn am Slave etwas nicht stimmt, nehmen die Unterschiede zwischen Master und Slave im Laufe der Zeit zu.
Tabellen müssen auf dem Master und dem Slave (fast) identisch sein.
Vorteile der datensatzbasierten Replikation:
Alles kann repliziert werden. Dies ist die sicherste Form der
Replikation. Beachten Sie, dass zurzeit DDL-Anweisungen (Data
Definition Language) wie etwa CREATE TABLE
anweisungsbasiert repliziert werden, während bei
DML-Anweisungen (Data Manipulation Language) sowie bei
GRANT
- und
REVOKE
-Anweisungen die Replikation
datensatzbasiert erfolgt. Für Anweisungen wie CREATE
... SELECT
wird eine
CREATE
-Anweisung aus der Tabellendefinition
erstellt, die dann anweisungsbasiert repliziert wird, während
das Einfügen von Datensätzen datensatzbasiert repliziert
wird.
Die Technologie ist dieselbe wie bei den meisten anderen Datenbanksystemen – Kenntnisse anderer Systeme lassen sich einfach auf MySQL übertragen.
In vielen Fällen geht es bei Tabellen mit Primärschlüsseln schneller, wenn man die Daten auf den Slave anwendet.
Bei den folgenden Anweisungstypen werden weniger Sperren auf dem Master benötigt (was die Nebenläufigkeit erhöht):
INSERT ... SELECT
INSERT
-Anweisungen mit
AUTO_INCREMENT
UPDATE
- oder
DELETE
-Anweisungen mit
WHERE
-Klauseln, die keine Schlüssel
verwenden und die meisten der untersuchten Datensätze
unverändert lassen
Weniger Sperren auf dem Slave bei INSERT
-,
UPDATE
- oder
DELETE
-Anweisungen.
Es ist möglich, mehrere Threads hinzuzufügen, um Daten zukünftig auf den Slave anzuwenden (dies funktioniert bei SMP-Systemen besser).
Nachteile der datensatzbasierten Replikation:
Größere Logdateien (in manchen Fällen sogar wesentlich größer).
Das Binärlog enthält Daten für umfangreiche Anweisungen, die per Rollback rückgängig gemacht wurden.
Wenn Sie mit der datensatzbasierten Replikation eine Anweisung
(z. B. eine UPDATE
- oder
DELETE
-Anweisung) replizieren, muss jeder
geänderte Datensatz in das Binärlog geschrieben werden. Im
Gegensatz dazu wird bei Verwendung der anweisungsbasierten
Replikation nur die Anweisung in das Binärlog geschrieben.
Wenn die Anweisung viele Datensätze ändert, schreibt die
datensatzbasierte Replikation deutlich mehr Daten in das
Binärlog. In diesem Fall wird das Binärlog für eine
längere Zeit gesperrt, um die Daten schreiben zu können, was
Probleme mit der Nebenläufigkeit verursachen kann.
Deterministische UDFs, die große
BLOB
-Werte erzeugen, werden merklich
langsamer repliziert.
Sie können die Logs darauf überprüfen, welche Anweisungen ausgeführt wurden.
Sie können auf dem Slave nicht nachprüfen, welche Anweisungen vom Master empfangen und dann ausgeführt wurden.
Wenn Sie die Anleitung befolgt haben und Ihre Replikationskonfiguration trotzdem nicht funktioniert, sollten Sie zuallererst das Fehlerlog auf Meldungen überprüfen. Allzu viele Benutzer haben bei Auftreten eines Problems kostbare Zeit damit vergeudet, dies nicht gleich gemacht zu haben.
Wenn Sie aus dem Fehlerlog nicht ableiten können, welches Problem vorliegt, probieren Sie die folgenden Methoden aus:
Überprüfen Sie, ob am Master das binäre Loggen aktiviert
ist, indem Sie eine SHOW MASTER
STATUS
-Anweisung absetzen. Bei aktiviertem Loggen
ist Position
ungleich null. Sollte das
binäre Loggen nicht aktiviert sein, dann stellen Sie sicher,
dass der Master mit den Optionen --log-bin
und --server-id
läuft.
Überprüfen Sie, ob der Slave ausgeführt wird. Mit
SHOW SLAVE STATUS
können Sie feststellen,
ob die Werte von Slave_IO_Running
und
Slave_SQL_Running
jeweils
Yes
lauten. Andernfalls überprüfen Sie
die Optionen, die beim Start des Slave-Servers angegeben
waren. So verhindert etwa --skip-slave-start
,
dass die Slave-Threads gestartet werden, bis Sie eine
START SLAVE
-Anweisung absetzen.
Wird der Slave ausgeführt, dann prüfen Sie, ob er eine
Verbindung zum Master herstellen konnte. Setzen Sie
SHOW PROCESSLIST
ab, suchen Sie die I/O-
und SQL-Threads und überprüfen Sie die zugehörigen
State
-Spalten. Siehe auch
Abschnitt 6.4, „Replikation: Implementationsdetails“. Wenn
für den I/O-Thread als Status Connecting to
master
angegeben ist, überprüfen Sie die
Berechtigungen für den Replikationsbenutzer auf dem Master,
den Hostnamen des Masters und Ihre DNS-Konfiguration und
stellen Sie sicher, dass der Master ausgeführt wird und auch
vom Slave erreicht werden kann.
Wurde der Slave bereits vorher ausgeführt, dann aber beendet, dann liegt das in der Regel daran, dass irgendeine Anweisung, die auf dem Master erfolgreich verarbeitet wurde, auf dem Slave fehlgeschlagen ist. Dies sollte niemals passieren, wenn Sie eine korrekte Momentaufnahme auf dem Master erstellt und die Daten auf dem Slave niemals außerhalb des Slave-Threads modifiziert haben. Wird der Slave unerwartet beendet, dann liegt entweder ein Bug vor, oder Sie sind auf eine der bekannten Einschränkungen der Replikation gestoßen, die in Abschnitt 6.8, „Replikation: Features und bekannte Probleme“, beschrieben sind. Wenn es sich um einen Bug handelt, lesen Sie Abschnitt 6.14, „Berichten von Replikationsfehlern und -problemen“, um zu erfahren, wie Sie diesen melden.
Wenn eine Anweisung, die auf dem Master klaglos verarbeitet wurde, nicht auf dem Slave ausgeführt werden kann, probieren Sie folgende Vorgehensweise aus, sofern die Durchführung einer vollständigen Datenbankneusynchronisierung durch Löschen der Datenbanken auf dem Slave und Kopieren einer neuen Momentaufnahme vom Master nicht realisierbar ist:
Ermitteln Sie, ob die betreffende Tabelle auf dem Slave
sich von der auf dem Master unterscheidet. Versuchen Sie
zu ergründen, was geschehen ist. Dann machen Sie die
Tabelle auf dem Slave identisch zu der auf dem Master und
führen START SLAVE
aus.
Funktioniert der vorherige Schritt nicht oder ist er nicht durchführbar, dann prüfen Sie, ob es sicher ist, die Änderung (sofern erforderlich) manuell durchzuführen und die nächste Anweisung vom Master zu ignorieren.
Wenn Sie feststellen, dass Sie die nächste Anweisung vom Master übergehen können, setzen Sie die folgenden Anweisungen ab:
mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER =
mysql>N
;START SLAVE;
Der Wert von N
sollte 1 sein,
wenn die nächste Anweisung vom Master weder
AUTO_INCREMENT
noch
LAST_INSERT_ID()
verwendet. Andernfalls
wählen Sie den Wert 2. Grund hierfür ist die Tatsache,
dass Anweisungen, die AUTO_INCREMENT
oder LAST_INSERT_ID()
verwenden, zwei
Ereignisse in das Binärlog des Masters schreiben.
Wenn Sie ganz sicher sind, dass der Slave vollkommen synchron zum Master gestartet wurde und niemand die betreffenden Tabellen außerhalb des Slave-Threads modifiziert hat, dann ist die Diskrepanz mit hoher Wahrscheinlichkeit Ergebnis eines Bugs. Wenn Sie die aktuelle MySQL-Version verwenden, melden Sie dieses Problem bitte. Wenn Sie hingegen eine ältere Version einsetzen, aktualisieren Sie – sofern möglich – auf den aktuellen Produktions-Release, um festzustellen, ob das Problem fortbesteht.
Wenn Sie festgestellt haben, dass kein benutzerseitiger Fehler vorliegt und die Replikation trotzdem nicht stabil ist oder womöglich gar nicht funktioniert, ist es an der Zeit, uns einen Bugreport zu schicken. Wir benötigen von Ihnen so viele Informationen wie möglich, um den Bug aufzuspüren. Bitte nehmen Sie sich für die Vorbereitung des Bugreports Zeit und seien Sie sorgfältig bei Ihren Angaben.
Wenn Sie einen reproduzierbaren Testfall haben, der den Bug demonstriert, geben Sie diesen bitte in unsere Fehlerdatenbank ein. Eine Anleitung zur Vorgehensweise finden Sie in Abschnitt 1.8, „Wie man Bugs oder Probleme meldet“. Wenn Sie ein „Phantomproblem“ haben (d. h. eines, welches sich nicht gezielt reproduzieren lässt), dann gehen Sie wie folgt vor:
Stellen Sie sicher, dass kein Fehler vorhanden ist. Wenn Sie am Slave beispielsweise Änderungen außerhalb des Slave-Threads vornehmen, dann sind die Daten nicht mehr synchron, und es kann bei Updates zu Verstößen aufgrund von Dubletten eindeutiger Schlüssel kommen. In diesem Fall bleibt der Slave-Thread stehen und wartet, bis Sie die Tabellen manuell bereinigt und die Synchronisation auf diese Weise wiederhergestellt haben. Dies ist kein replikationsbezogenes Problem. Die Replikation schlägt vielmehr aufgrund eines äußeren Störeinflusses fehl.
Führen Sie den Slave mit den Optionen
--log-slave-updates
und
--log-bin
aus. Diese Optionen bewirken, dass
der Slave die Updates, die er vom Master erhält, in seine
eigenen Binärlogs schreibt.
Speichern Sie alle Beweismittel, bevor Sie den Replikationsstatus zurücksetzen. Wenn wir keine oder nur bruchstückhafte Informationen erhalten, wird es schwierig bis unmöglich, die Problemursache zu ermitteln. Folgende Beweisstücke sollten Sie übermitteln:
alle Binärlogs des Masters
alle Binärlogs des Slaves
Ausgabe von SHOW MASTER STATUS
auf dem
Master zum Zeitpunkt der Feststellung des Problems
Ausgabe von SHOW SLAVE STATUS
auf dem
Slave zum Zeitpunkt der Feststellung des Problems
Fehlerlogs von Master und Slave
Überprüfen Sie mit mysqlbinlog die
Binärlogs. Folgender Befehl sollte zur Ermittlung der
problematischen Abfrage hilfreich sein. Hierbei sind
log_pos
und
log_file
die Werte
Master_Log_File
bzw.
Read_Master_Log_Pos
in der Ausgabe von
SHOW SLAVE STATUS
.
shell>mysqlbinlog -j
log_pos
\
log_file
| head
Nachdem Sie alle Beweisstücke für das Problem gesammelt haben, versuchen Sie es zunächst als separaten Testfall zu extrahieren. Geben Sie das Problem danach mit möglichst vielen Informationen in unsere Bugdatenbank ein. Die Vorgehensweise ist in Abschnitt 1.8, „Wie man Bugs oder Probleme meldet“, beschrieben.
Wenn mehrere Server als Replikationsmaster konfiguriert sind,
müssen spezielle Schritte unternommen werden, um
Schlüsselkollisionen bei der Verwendung von
AUTO_INCREMENT
-Spalten zu verhindern;
andernfalls könnten mehrere Master beim Einfügen von
Datensätzen versuchen, denselben
AUTO_INCREMENT
-Wert zu verwenden.
Die Systemvariablen auto_increment_increment
und auto_increment_offset
ermöglichen die
Multi-Master-Replikation in Verbindung mit
AUTO_INCREMENT
-Spalten. Jede dieser Variablen
hat einen Standard- und Mindestwert von 1. Der Höchstwert
beträgt jeweils 65.535.
Diese beiden Variablen beeinflussen das Verhalten von
AUTO_INCREMENT
-Spalten wie folgt:
auto_increment_increment
steuert das
Intervall zwischen aufeinander folgenden
AUTO_INCREMENT
-Werten.
auto_increment_offset
bestimmt den
Startwert der Spalte AUTO_INCREMENT
.
Durch Auswahl nichtkollidierender Werte auf verschiedenen Mastern
wird dafür gesorgt, dass Server in einer Multimaster-Umgebung
beim Einfügen neuer Datensätze in dieselbe Tabelle keine
kollidierenden AUTO_INCREMENT
-Werte verwenden.
Stellen Sie die Variablen wie folgt ein, um
N
Master-Server zu konfigurieren:
Setzen Sie auto_increment_increment
auf
jedem Master auf N
.
Stellen Sie auf jedem der N
Master
einen unterschiedlichen Wert für
auto_increment_offset
ein (0, 1, 2,
… , N
– 1).
Weitere Informationen zu
auto_increment_increment
und
auto_increment_offset
finden Sie in
Abschnitt 5.2.2, „Server-Systemvariablen“.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.