Replication Master to Master

From Deimos.fr / Bloc Notes Informatique
Jump to: navigation, search

Contents


MySQL Logo

1 Introduction

After done the installation (Look here : Installation et configuration), we are going to set up MySQL master-master replication. We need to replicate MySQL servers to achieve high-availability (HA). In my case I need two masters that are synchronized with each other so that if one of them drops down, other could take over and no data is lost. Similarly when the first one goes up again, it will still be used as slave for the live one.

Mysql replication.png

Here is a basic step by step tutorial, that will cover the mysql master and slave replication and also will describe the mysql master and master replication.

Notions: we will call system 1 as master1 and slave2 and system2 as master2 and slave 1.


Install mysql on master 1 and slave 1. configure network services on both system, like :

  • Master 1/Slave 2 ip: 10.8.0.1
  • Master 2/Slave 1 ip : 10.8.0.6

2 Master 1 configuration

2.1 Step 1

On Master 1, make changes in my.cnf :

Configuration File my.cnf
...
[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
binlog-do-db=<database name>  # input the database which should be replicated
binlog-ignore-db=mysql        # input the database that should be ignored for replication
binlog-ignore-db=test
expire_logs_days=14
# binlog_cache_size = 64K # Enable this if binlog_cache_disk_use increase in 'show global status'
sync_binlog = 1 # Reduce performances but essential for data integrity between slave <- master
slave_compressed_protocol = 1 # Good for wan replication to reduce network I/O at low cost of extra CPU

server-id=1
bind-address = 0.0.0.0
...

Notes : Italic lines are nearly optional and bold lines need to be set

If you want to sync all databases without setting exclusions, you could without adding '*ignore-db' values :

Configuration File my.cnf
...
[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
expire_logs_days=14
# binlog_cache_size = 64K # Enable this if binlog_cache_disk_use increase in 'show global status'
sync_binlog = 1 # Reduce performances but essential for data integrity between slave <- master
slave_compressed_protocol = 1 # Good for wan replication to reduce network I/O at low cost of extra CPU

server-id=1
bind-address = 0.0.0.0
...

Restart MySQL :

Command restart
/etc/init.d/mysql restart

2.2 Step 2

On master 1, connect on it and create a replication slave account in mysql.

Command
mysql> create user 'replication'@'10.8.0.1' identified by 'password';

  • replication : username for replication
  • password : password for replication user
Command
mysql> grant replication slave on <database name>.* to 'replication'@'10.8.0.1';

or

mysql> grant replication slave on *.* to 'replication'@'10.8.0.1';

Flush the privileges and database tables with read lock :

Command
  1.  flush privileges;
  2.  flush tables with read lock;
  3.  show master status;
  4.  +------------------+----------+--------------+------------------+
  5.  | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  6.  +------------------+----------+--------------+------------------+
  7.  | mysql-bin.000173 |    50937 | wikidb       |                  | 
  8.  +------------------+----------+--------------+------------------+
  9.  1 row in set (0.00 sec)

Note, if you have full InnoDB databases, you needn't to flush tables with read locks.

2.3 Step 3

Backup the desired database and upload them to the slave. If you're on InnoDB :

Command mysqldump
mysqldump -uroot -p --opt --add-drop-table --routines --triggers --events --single-transaction --master-data=2 -B wikidb > wikidb.sql

Note: If there is InnoDB/MyISAM, add --lock-all-tables !

Command scp
scp wikidb.sql 10.8.0.6:~/

Then we will unlock tables :

Command
mysql -uroot -p
unlock tables;
quit;

3 Slave 1 configuration

3.1 Step 1

Let's create the database :

Command
mysql -uroot -p
create database wikidb;
quit;

Then we import the database :

Command
mysql -uroot -p  wikidb < wikidb.sql

3.2 Step 2

Now edit my.cnf on Slave1 or Master2 :

Configuration File my.cnf
[mysqld]
...
server-id=2
bind-address = 0.0.0.0
# sync_binlog = 1
expire_log_days = 14
...

Then restart MySQL :

Command restart
/etc/init.d/mysql restart

3.3 Step 3

Grab informations from the Master :

Command head
head -n100 database.sql 

Now we're going to inform the slave database :

Command
mysql -uroot -p
stop slave;
reset slave;
change master to master_host='10.8.0.1', master_user='replication', master_password='password', master_log_file='mysql-bin.000173', master_log_pos=50937;

Let's starting the slave 1 :

Command
start slave;
show slave status\G;

 ************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 192.168.16.4
                Master_User: replica
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: MASTERMYSQL01-bin.000009
        Read_Master_Log_Pos: 4
             Relay_Log_File: MASTERMYSQL02-relay-bin.000015
              Relay_Log_Pos: 3630
      Relay_Master_Log_File: MASTERMYSQL01-bin.000009
           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: 4
            Relay_Log_Space: 3630
            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: 1519187

1 row in set (0.00 sec)

Above highlighted rows must be indicate related log files and Slave_IO_Running and Slave_SQL_Running: must be to YES.

  • Seconds_Behind_Master : is the difference time between master and slave data sync (in progress...).
  • Master_Host : This is the address of the master server. The slave will connect on it to get the logs that have to be replayed
  • Master_User : The user that we will use for the replication
  • Master_Port : The port where the slave will connect to on the master
  • Master_Log_File: This file is the binary log that the slave will have to replay. the binary log is located on the master server. This file contains every statement that makes a change to the database in a binary format.
  • Read_Master_Log_Pos : This is the position number on the binary log file that is being read by the "Slave_I/O Process" (the process that established the connexion to the master and ensure the sync)
  • Relay_Log_File: Same as the binary log but this file is located on the slave. This is a relay file of the master binary log
  • Relay_Log_Pos: This is the position number on the relay log file that is being read by the "Slave_SQL Process" (the process that replays the changes to the slave database)
  • Relay_Master_Log_File : It contains all the statements that have been processed by the slave.
  • Slave_IO_Running : The status of the Slave_I/O process. when it's on "Yes" that means that the slave is properly connected to the master. if it's on "No" that means that something goes wrong with the connectivity between the 2 nodes
  • Slave_SQL_Running : The status of the Slave_SQL process. when it's on "Yes" that means that the slave is able to process statements and that all is working correctly. if it's on "No" that means that something goes wrong while reading the relay logs

4 Master 1 verification

Command
  1. mysql> show master status;
  2. +------------------------+----------+--------------+------------------+
  3. | File                   | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  4. +------------------------+----------+--------------+------------------+
  5. |MysqlMYSQL01-bin.000008 |      410 | adam         |                  |
  6. +------------------------+----------+--------------+------------------+
  7. 1 row in set (0.00 sec)

The above scenario is for master-slave, now we will create a slave master scenario for the same systems and it will work as master master.

5 Master 2 configuration

5.1 Step 1

On Master 2, make changes in my.cnf :

Configuration File my.cnf
...
[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
binlog-do-db=<database name>  # input the database which should be replicated
binlog-ignore-db=mysql        # input the database that should be ignored for replication
binlog-ignore-db=test
expire_logs_days=14
# binlog_cache_size = 64K # Enable this if binlog_cache_disk_use increase in 'show global status'
sync_binlog = 1 # Reduce performances but essential for data integrity between slave <- master
slave_compressed_protocol = 1 # Good for wan replication to reduce network I/O at low cost of extra CPU

server-id=2
bind-address = 0.0.0.0
# sync_binlog = 1
expire_log_days = 14
...

Restart MySQL :

Command
/etc/init.d/mysql restart

5.2 Step 2

On master 1, connect on it and create a replication slave account in mysql.

Command
mysql> create user 'replication'@'10.8.0.6' identified by 'password';

  • replication : username for replication
  • password : password for replication user
Command
mysql> grant replication slave on <database name>.* to 'replication'@'10.8.0.6';

or

mysql> grant replication slave on *.* to 'replication'@'10.8.0.6';

Flush the provileges :

Command
  1.  flush privileges;
  2.  show master status;
  3.  +------------------+----------+--------------+------------------+
  4.  | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  5.  +------------------+----------+--------------+------------------+
  6.  | mysql-bin.000173 |    50937 | wikidb       |                  | 
  7.  +------------------+----------+--------------+------------------+
  8.  1 row in set (0.00 sec)

6 Slave 1 configuration

Now we're going to inform the slave database :

Command
mysql -uroot -p
slave stop;
reset slave;
change master to master_host='10.8.0.6', master_user='replication', master_password='password', master_log_file='mysql-bin.000173', master_log_pos=50937;

Let's starting the slave 2 :

Command
start slave;
show slave status\G;

 ************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 10.8.0.6
                Master_User: replica
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: MASTERMYSQL01-bin.000009
        Read_Master_Log_Pos: 4
             Relay_Log_File: MASTERMYSQL02-relay-bin.000015
              Relay_Log_Pos: 3630
      Relay_Master_Log_File: MASTERMYSQL01-bin.000009
           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: 4
            Relay_Log_Space: 3630
            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: 1519187

1 row in set (0.00 sec)

Above highlighted rows must be indicate related log files and Slave_IO_Running and Slave_SQL_Running: must be to YES.

7 Master 2 verification

Command
  1. mysql> show master status;
  2. +------------------------+----------+--------------+------------------+
  3. | File                   | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  4. +------------------------+----------+--------------+------------------+
  5. |MysqlMYSQL01-bin.000008 |      410 | adam         |                  |
  6. +------------------------+----------+--------------+------------------+
  7. 1 row in set (0.00 sec)

The above scenario is for master-slave, now we will create a slave master scenario for the same systems and it will work as master master.

8 Monitoring

Now you need to monitor your replication, you need to look at this when doing 'show slave status\G' :

Command show slave status
  1.              ...
  2.              Slave_IO_Running: Yes
  3.              Slave_SQL_Running: Yes
  4.              Seconds_Behind_Master: 0
  5.              ...

What is interesting to investigate are those lines :

Command show slave status
  1.              ...
  2.              Last_IO_Error: error connecting to master 'replication@192.168.25.9:3306' - retry-time: 60  retries: 86400
  3.              Last_SQL_Error:
  4.              ...

You also need to look at binlog size :

Command show global status
  1. mysql> show global status like '%binlog%';
  2. +------------------------+---------+
  3. | Variable_name          | Value   |
  4. +------------------------+---------+
  5. | Binlog_cache_disk_use  | 2       |
  6. | Binlog_cache_use       | 4333061 | 
  7. | Com_binlog             | 0       | 
  8. | Com_show_binlog_events | 0       | 
  9. | Com_show_binlogs       | 14      | 
  10. +------------------------+---------+
  11. 5 rows in set (0.00 sec)

Ugrade Binlog_cache_size from 32 to 128k if Binlog_cache_disk_use is not equal to 0.

9 FAQ

9.1 After a reboot the slave is not synchronized

On the master get informations :

Command
mysql -uroot -p
show master status;

Try to do this on the slave (adapt to your configuration) :

Command
  1. mysql -uroot -p
  2. slave stop;
  3. reset slave;
  4. change master to master_host='10.8.0.6', master_user='replication', master_password='password', master_log_file='mysql-bin.000173', master_log_pos=50937;
  5. start slave;
  6. show slave status\G;

The slave syncronization should be repared :-)

9.2 Watch current process to determine syncro problem

With this command, we can see if there is a mysql replication problem :

Command mysqladmin
  1.  $ mysqladmin -uroot -p processlist
  2.  
  3.  +------+-------------+------------------------+----+-------------+--------+-----------------------------------------------------------------------+------------------+
  4.  | Id   | User        | Host                   | db | Command     | Time   | State                                                                 | Info             |
  5.  +------+-------------+------------------------+----+-------------+--------+-----------------------------------------------------------------------+------------------+
  6.  | 1    | system user |                        |    | Connect     | 264546 | Waiting for master to send event                                      |                  |
  7.  | 2    | system user |                        |    | Connect     | 1798   | Has read all relay log; waiting for the slave I/O thread to update it |                  |
  8.  | 4796 | replication | 10.8.0.6:60523         |    | Binlog Dump | 4733   | Has sent all binlog to slave; waiting for binlog to be updated        |                  |
  9.  | 5020 | root        | localhost              |    | Query       | 0      |                                                                       | show processlist |
  10.  +------+-------------+------------------------+----+-------------+--------+-----------------------------------------------------------------------+------------------+

9.3 What if I have binlogs corrupted ?

If you've got this kind of problem, a tool called mk-table-checksum available here permit to check consitency between 2 servers. It also can help to recreate a consistancy database from the master.

10 Ressources

Here is another documentation if you encounter problem :
MySQL Database Scale-out and Replication for High Growth Businesses (Très bonne documentation)
Other MySQL masters replication documentation
Master to Master replication MySQL 5 on Debian Etch
Master to Master replication MySQL 5 on Fedora
How To Repair MySQL Replication
Setting Up Master-Master Replication On Four Nodes

Personal tools
Namespaces

Variants
Actions
navigation et RSS
Menu
Liens
Projets/Contribs
Google Search
Translate
Toolbox