Beschreibung

MySQL soll als Master-Master Replikation unter Ubuntu 10.04 LTS (x86_64) betrieben werden. Es kommt die MySQL Version 5.1.67 aus der Paketverwaltung zum Einsatz.

Die Master-Master Replikation kann mit einer Failover IP über Corosync und Pacemaker hochverfügbar gemacht werden.

Folgende IP's werden verwendet:

10.4.12.111 node1
10.4.12.112 node2

Installation

node[1|2] # aptitude install mysql-server-5.1

Konfiguration

MySQL muss auf dem gewünschten Interface lauschen. Wenn man eine Failover IP verwendet, sollte man sicherheitshalber einfach bind-address auskommentieren:

node[1|2] # vi /etc/mysql/my.cnf
- bind-address           = 127.0.0.1
+ #bind-address           = 127.0.0.1

Danach startet man MySQL neu und kontrolliert die Einstellungen:

node[1|2] # /etc/init.d/mysql restart
node[1|2] # netstat -tulpen|grep mysql
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      103        6416        1735/mysqld

Im nächsten Schritt richtet man einen Benutzer für die Replikation ein:

node[1|2] # mysql -u root -p
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%' IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;
mysql> QUIT;

Jetzt kann man auf beiden Nodes eine Datenbank anlegen, die repliziert werden soll:

node[1|2] # mysql -u root -p
mysql> CREATE DATABASE test;
mysql> QUIT;

Danach muss die Konfiguration angepasst werden. Zuerst Node 1:

node1 # vi /etc/mysql/my.cnf
[mysqld]
server-id = 1
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 1
master-host = 10.4.12.112
master-user = replication
master-password = password
master-connect-retry = 60
replicate-do-db = test
log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db = test
relay-log = /var/lib/mysql/slave-relay.log
relay-log-index = /var/lib/mysql/slave-relay-log.index

node1 # /etc/init.d/mysql restart

Danach Node 2:

node2 # vi /etc/mysql/my.cnf
[mysqld]
server-id = 2
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 2
master-host = 10.4.12.111
master-user = replication
master-password = password
master-connect-retry = 60
replicate-do-db = test
log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db = test
relay-log = /var/lib/mysql/slave-relay.log
relay-log-index = /var/lib/mysql/slave-relay-log.index

node2 # /etc/init.d/mysql restart

Im nächsten Schritt muss man den Schreibzugriff unterbinden und die aktuelle Log Position ermitteln:

node1 # mysql -u root -p
mysql> USE test;
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      194 | test         |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Jetzt erstellt man ein Backups auf Node 1, welches auf Node 2 wiederhergestellt werden muss. Dazu eine neue SSH Sessions öffnen und die aktuelle MySQL Cli nicht schließen!

node1 # mysqldump -u root -p test > test.sql
node1 # scp test.sql root@node2:

Jetzt kann man die Datenbank auf Node 1 wieder freigeben:

mysql> UNLOCK TABLES;
mysql> QUIT;

Das Backup muss jetzt auf Node 2 wiederhergestellt werden:

node2 # mysqladmin -u root -p stop-slave
node2 # mysql -u root -p test < test.sql

Danach ermittelt man die Log Position von Node 2:

node2 # mysql -u root -p
mysql> USE test;
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      106 | test         |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

mysql> UNLOCK TABLES;

Jetzt macht man aus Node 2 einen Slave von Node 1 (Werte mit Log Position auf Node 2 füllen):

node2 # mysql -u root -p
mysql> CHANGE MASTER TO MASTER_HOST='10.4.12.111', MASTER_USER='replication',
       MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=194;
mysql> START SLAVE;

Der Status von Node 2 sollte noch kontrolliert werden:

node2 # mysql -u root -p
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.4.12.111
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 194
               Relay_Log_File: slave-relay.000002
                Relay_Log_Pos: 251
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: test
          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: 194
              Relay_Log_Space: 402
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
1 row in set (0.00 sec)

Zum Schluss macht man Node 1 zum Slave von Node 2 (Werte mit Log Position aus Node 2 füllen):

node1 # mysql -u root -p
mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_HOST='10.4.12.112', MASTER_USER='replication',
       MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=106;
mysql> START SLAVE;

Auch hier kontrolliert man nochmal die Einstellungen:

node1 # mysql -u root -p
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.4.12.112
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 106
               Relay_Log_File: slave-relay.000002
                Relay_Log_Pos: 251
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: test
          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: 106
              Relay_Log_Space: 402
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
1 row in set (0.00 sec)

Damit ist die Master-Master Replikation aktiv und die Datenbank test kann verwendet werden.

Links