Replikation mit MySQL 5.x

Master – Slave Replikation:

Szenario:

Replikation aller Datenbanken eines Server zu Backupzwecken auf einen weiteren Server. Achtung: Dies kann auch erreicht werden, indem wir eine zusätzliche Instanz auf unseren vorhanden Server einrichten. Zunächst müssen wir sicherstellen, dass in der my.cnf folgende Einträge wie folgt vorhanden sind:

#bind-address           = 127.0.0.1
muss auskommentiert werden, damit die MySQL Instanz auf den externen Interfaces erreichbar ist

log-bin = /var/log/mysql/mysql-bin.log
hiermit schalten wir das binlog ein, welches zwingen notwendig für die Einrichtung einer Replikation ist, auf dem Slave können wir die Binlogs ebenfalls anschalten. (Backup)

server-id=1
diese IDs müssen auf den an der Replikation beteiligten Servern eingerichtet und unterschiedlich sein

expire_logs_days        = 10
gibt an, ab wieviel Tagen die Logs gelöscht werden

max_binlog_size         = 500M
die maximale Größe eines Binlogs

Danach starten wir MySQL auf dem Server neu:

/etc/init.d/mysql restart

Überprüfe dann mit

netstat -tanp | grep mysql

ob MySQL wirklich auf allen Interfaces hört:

okami:~# netstat -antp | grep mysql
tcp 0 0 *:mysql *:* LISTEN 2671/mysqld

Auf dem Master Server richten wir anschliessend den Benutzer für die Replikation ein:

mysql -u root -p

Führe in der MySQL Kommandozeile folgende Befehle aus:

GRANT REPLICATION SLAVE ON *.* TO ’replikation_user’@'IP_SLAVE’ IDENTIFIED BY ’replikation_passwort’;
FLUSH PRIVILEGES;
quit;

Das weitere Vorgehen ist davon abhängig ob wir schon Daten in der Datenbank haben, oder ob wir die Datenbank erst jungfräulich aufgesetzt haben.

Wenn Master und Slave sozusagen frisch aufgesetzt sind, noch keine Daten existieren, notieren wir auf dem Master Binlog und Binlogposition weg.

SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000009 |      112 |              |                  |
+------------------+----------+--------------+------------------+

Auf dem Slave passen wir die my.cnf wie folgt an:

#bind-address           = 127.0.0.1
server-id = 2

log-bin= /var/log/mysql/mysql-bin.log

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

expire_logs_days        = 10
max_binlog_size         = 500M

Danach starten wir MySQL auf dem Server neu:

/etc/init.d/mysql restart

und richten die Replikation ein hier werden die Werte von dem Masterserver verwendet

mysql -u root -p

CHANGE MASTER TO MASTER_HOST='IP_MASTER', MASTER_USER='replikation_user', MASTER_PASSWORD='replikation_password', MASTER_LOG_FILE='mysql-bin.000009', MASTER_LOG_POS=113;
START SLAVE;

Den Status der Replikation überprüfen wir mit:

SHOW SLAVE STATUS\G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: IP_MASTER
                Master_User: replikation_user
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.000009
        Read_Master_Log_Pos: 130
             Relay_Log_File: slave-relay-bin.000001
              Relay_Log_Pos: 00000004
      Relay_Master_Log_File: mysql-bin.000001
           Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB:
        Replicate_Ignore_DB:
         Replicate_Do_Table:
     Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                 Last_Errno: 0
                 Last_Error:
               Skip_Counter: 0
        Exec_Master_Log_Pos: 2
            Relay_Log_Space: 690471192
            Until_Condition: None
             Until_Log_File:
              Until_Log_Pos: 0
         Master_SSL_Allowed: No
         Master_SSL_CA_File:
         Master_SSL_CA_Path:
            Master_SSL_Cert:
          Master_SSL_Cipher:
             Master_SSL_Key:
      Seconds_Behind_Master: NULL
1 row in set (0.00 sec)

Wichtig: Slave_IO_Running und Slave_SQL_Running müssen auf Yes stehen. Anderen Falles stimmen z.B. die Userberechtigungen des Replikationsusers nicht, das Passwort ist nicht oder nicht richtig eingetragen, oder  die MySQL Instanz kann sich nicht zum Master verbinden(Port, Ip usw.). Wie solche DInge repariert werden folgt an anderer Stelle.

Wenn der Master schon Daten enthält müssen wir anders vorgehen. Hierzu gibt es mehrere Varianten – die von mir vorgestellte benutze ich fast wöchentlich um Replikationen neu Aufzusetzen. Wenn wir den Master und den Slave vorbereitet haben, ziehen wir uns ein Backup mit mysqldump auf dem Masterserver.

Achtung je nachdem welche Engines ihr benutzt und wie diese verwendet werden, kann es zu Problemen führen. Die INNODB – Variante berücksichtigt, dass nur in Innodbtabellen geschrieben wird und somit können wir im Livebetrieb ein konsistentes Backup für eine Replikation ziehen. Wenn Ihr auch MyISAM Tabellen im Einsatz habt und in diese auch geschrieben wird, muss die Datenbank erst gelocked werden, siehe weiter unten.

INNODB

mysqldump -uroot -p --triggers --routines --verbose --master-data=2 --flush-logs --single-transaction --all-databases | gzip -1 -c > /pfad/dump.sql.gz

MyISAM

mysql -uroot -p

FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000999 |      112 |              |                  |
+------------------+----------+--------------+------------------+

Damit haben wir den Master gelocked, sprich es können keine Daten in die Datenbank geschrieben werden.

mysqldump -u root -p --triggers --routines --verbose --all-databases | gzip -1 -c > /pfad/dump.sql.gz

Nachdem wir nun den Dump auf den Slave kopiert haben spielen wir ihn in die Datenbank ein:

gunzip -c /pfad/dump.sql.gz | mysql -uroot -p

INNODB

gunzip -c /pfad/dump.sql.gz | head -n22 | tail -n1
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.122978', MASTER_LOG_POS=98;

mysql -uroot -p

CHANGE MASTER TO MASTER_HOST='IP_MASTER', MASTER_USER='replikation_user', MASTER_PASSWORD='replikation_password', MASTER_LOG_FILE='mysql-bin.122978', MASTER_LOG_POS=98;
START SLAVE;

MyISAM

Hier benutzen wir die Angaben aus dem SHOW MASTER Befehl des gelockten Masters.

mysql -uroot -p

CHANGE MASTER TO MASTER_HOST='IP_MASTER', MASTER_USER='replikation_user', MASTER_PASSWORD='replikation_password', MASTER_LOG_FILE='mysql-bin..000999', MASTER_LOG_POS=112;
START SLAVE;

Wenn wir überprüft haben, dass die Replikation läuft (SHOW SLAVE STATUS;) müssen wir in der MyISAM – Variante nur noch die Datenbanken auf dem Master wieder freigeben:

 UNLOCK TABLES;