MySQL Master Master Replication

Do you like HowtoForge? Please consider supporting us by becoming a subscriber.
Submitted by sheikhsa (Contact Author) (Forums) on Sun, 2006-09-10 08:31. :: MySQL

MySQL Master Master Repliction Tutorial

This tutorial describes how 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.

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.

Step 1:

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

Master 1/Slave 2 ip: 192.168.16.4

Master 2/Slave 1 ip : 192.168.16.5 

 

Step 2:

On Master 1, make changes in my.cnf:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
old_passwords=1

log-bin
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

server-id=1

[mysql.server]
user=mysql
basedir=/var/lib


[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


Step 3:

On master 1, create a replication slave account in mysql.

mysql> grant replication slave on *.* to 'replication'@192.168.16.5 \
identified by 'slave';

and restart the mysql master1. 

 

Step 4:

Now edit my.cnf on Slave1 or Master2 :

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
old_passwords=1

server-id=2

master-host = 192.168.16.4
master-user = replication
master-password = slave
master-port = 3306

[mysql.server]
user=mysql
basedir=/var/lib

[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


 Step 5:

Restart mysql slave 1 and at

mysql> start slave;
mysql> 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.

 

Step 6:

On master 1:

mysql> show master status;
+------------------------+----------+--------------+------------------+
| File                   | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------------+----------+--------------+------------------+
|MysqlMYSQL01-bin.000008 |      410 | adam         |                  |
+------------------------+----------+--------------+------------------+
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.

 

Step 7:

On Master2/Slave 1, edit my.cnf and master entries into it:

 [mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
server-id=2

master-host = 192.168.16.4
master-user = replication
master-password = slave
master-port = 3306

log-bin                     #information for becoming master added
binlog-do-db=adam

[mysql.server]
user=mysql
basedir=/var/lib

[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

 

Step 8:

Create a replication slave account on master2 for master1:

mysql> grant replication slave on *.* to 'replication'@192.168.16.4 identified by 'slave2';

 

Step 9:

Edit my.cnf on master1 for information of its master.

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1


log-bin
binlog-do-db=adam
binlog-ignore-db=mysql
binlog-ignore-db=test

server-id=1
#information for becoming slave.
master-host = 192.168.16.5
master-user = replication
master-password = slave2
master-port = 3306

[mysql.server]user=mysqlbasedir=/var/lib 

 

Step 10:

Restart both mysql master1 and master2.

On mysql master1:

mysql> start slave;

On mysql master2: 

mysql > show master status;

On mysql master 1:

mysql> show slave status\G;


*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 192.168.16.5
                Master_User: replica
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: Mysql1MYSQL02-bin.000008
        Read_Master_Log_Pos: 410
             Relay_Log_File: Mysql1MYSQL01-relay-bin.000008
              Relay_Log_Pos: 445
      Relay_Master_Log_File: Mysql1MYSQL02-bin.000008
           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: 410
            Relay_Log_Space: 445
            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: 103799
1 row in set (0.00 sec)

ERROR:
No query specified

Check for the hightlighted rows, make sure its running. Now you can create tables in the database and you will see changes in slave. Enjoy!! 


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by fosiul (registered user) on Mon, 2009-11-23 18:27.

Today , While trying this article, I was keep getting this error for Step 9( Changing Master1 as Slaves for Master2)

---------------------------

091123 18:59:13 [ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id

option must be used on slave but this does not always make sense; please check the manual before using it). Error_code: 1593
 --------------------------------
I don't know if I was doing anything wrong or not.
but by adding  "log-slave-updates" solved my issue.
so it was like this :
server-id=1
#information for becoming slave.
master-host = 192.168.16.5
master-user = replication
master-password = slave2
master-port = 3306
log-slave-updates
 
Ref :
(a) http://dev.mysql.com/doc/refman/5.0/en/replication-options-slave.html#option_mysqld_replicate-same-server-id
 
(b) http://dev.mysql.com/doc/refman/5.0/en/replication-options-slave.html#option_mysqld_log-slave-updates

 Thanks

Submitted by Hassan (not registered) on Wed, 2009-11-11 09:39.

do you have any steps for us to setup load balancer with master-master replication what you described above?

 if we are using PHP5, where does the connection point to in the master-master replication?

 I'm looking for failover in this setup, how does it work?

regards

Submitted by Glen Bremner-Stokes (not registered) on Thu, 2009-07-16 21:12.

Thank you for a great post and for taking the time to put it out there.

I now have my sugarcrm system on the web and a local sugarcrm on my laptop working bi-directionally. So I can update a record in either system and the other is instantly updated.

Very very cool and really easy following your instructions. Well done. 

 

Submitted by Chris Dean (not registered) on Wed, 2009-05-06 12:41.

Here are some additional notes on issues you might encounter during this process:

  1. If your first Master DB (Master 1) contains views (at the time of writing) you'll not be able to use the command "load data from master" to clone Master 1 to Master 2 due to this bug: and you'll have to replicate the existing system some other way e.g. copy and paste data files or stream data via mysqldump

  2. If you use auto incremeneting id's and you're using Master Master with both masters active you might want to consider setting the following options on Master 1 and Master 2 so that the auto increment values don't end up clashing in the case where an insert happens to occur at exactly the same time on both servers:

    Make Master 1 only auto-increment odd numbers by adding this to my.cnf under [mysqld]:
    auto_increment_increment= 2
    auto_increment_offset   = 1


    Make Master 2 only auto-increment even numbers by adding this to my.cnf under [mysqld]:
    auto_increment_increment= 2
    auto_increment_offset   = 2

    This is particularly important if you're using auto increment id columns as primary keys

Submitted by Anonymous (not registered) on Mon, 2009-01-26 09:06.
Dear, I have done the Multi master Replication with the proceedure described above. No records are being replicated on both servers. and the status of the Slave shows: Slave_IO_Running: NO Slave_SQL_Running: Yes And same thing are shown on both Servers when looking at the 'show slave status\G;' Please help me out how i can rectify this problem. Regards, Majid
Submitted by tom (not registered) on Wed, 2008-12-03 01:55.

hi adam,

thanks for putting this up. just one possible typo:

in step 2 you have

....
 old_passwords=1

log-bin
binlog-do-db=<database name>  # input the database which should be replicated
....

shouldn't log-bin be followed with a filename like ?

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

cheers,
tom

 

 

Submitted by Fabio Cecaro (not registered) on Thu, 2008-11-27 10:53.

Hi sheikhsa,

In a Master-Master replication there are many problems with the autonumber field tables.

Because when a client insert a value in a table in a master on the other master we can have another client with another insert in the same table. So we have a possible conflict when the replication mechanism replies these two records, because if this ID is relationate with another table I think we corrupting the relational logical.

We must fix addend two lines in the my.cnf of two masters

auto_increment_increment

auto_increment_offset

Example in this case we can set to the first Master the values:

auto_increment_increment = 2

auto_increment_offset = 1

 and in the other:

auto_increment_increment = 2

auto_increment_offset = 2.

So in one master we generate only the pairs number and  dispair in the other, when the replication come we haven't conflicts.

Submitted by Marco Fretz (not registered) on Tue, 2008-10-21 14:38.

thank you for this great how-to. works pretty well for me.

 

 

Submitted by da644 (registered user) on Thu, 2007-06-14 15:39.

One thing that is missing from the above, is how to deal with auto-increments so that you do not get collisions if you add data to both masters at the same time. There is an easy way to deal with this if you are using MySQL 5.0.2 or above.

In the my.cnf file on server1 add:

auto_increment_increment=2
auto_increment_offset=1

In the my.cnf file on server2 add:

 auto_increment_increment=2
auto_increment_offset=2

This will make the auto-increment on server1 go, 1,3,5,7,9,etc... and on server2 go, 2,4,6,8,etc... thereby preventing collisions.

Andrew
www.andrewdixon.co.uk

Submitted by krex (not registered) on Fri, 2009-08-14 07:19.

 Try setting on both servers my.cnf:

auto_increment_increment=1

auto_increment_offset=2

Submitted by Andreas (not registered) on Sun, 2008-10-05 15:44.

How will this setup solve collisions in data changes?

"First wins?"

"Don't care?"

Submitted by Anonymous (not registered) on Fri, 2009-04-17 17:49.

for the autoincrement field if you run it buck wild on both u get data for a single field from both servers.

this breaks replication. error duplicate yadda yadda yadda

serverID 1

auto_increment_increment        2                               
auto_increment_offset            1   

------------------------------------------------                             

serverID 2

auto_increment_increment        2                               
auto_increment_offset            2

serverID 1 will start at 1 and increment 2 always giving odd numbers

serverID2 will start at 2 and increment by 2 always giving even numbers.

this will prevent the autoincrement field having duplicates when cross replicating. 

Submitted by Fred59 (not registered) on Wed, 2010-03-17 16:38.

Thanks for this good howto.

Despite writing different auto_increment_offset in master 1 and master2, all my records are always with even number. How is it possible ?

Submitted by Anonymous (not registered) on Thu, 2009-09-17 06:44.

Do you think this setting is required for active-passive  master-master replication?

I don't think as there will be no simulteneous writes that may require alternating auto increment requied!
Submitted by Will Fitch (not registered) on Thu, 2009-03-05 03:50.
Agreed. InnoDB's row-level locking (or any locking for that matter) doesn't propagate via the replication protocol.  This is a big disadvantage and the only solution is to implement a solution on the client code.
Submitted by Matt (not registered) on Thu, 2008-10-16 08:18.

It doesn't.  If both nodes attempt to edit the same record at the same time, you could have problems.  Not sure on the behavior, but most likely the last one to update would win.

 The post described a way to deal with auto-increment data type, which is often use to uniquely index new records.  The clear use of increment interval and offset allows new records to be created without collision.

Sponsored Links: Turn your desk phone and mobile phone into one with Sprint Mobile Integration.
www.seamlessenterprise.com

One number. One voicemail. Seize the lead. Sprint Mobile Integration.
www.seamlessenterprise.com

One Number. One Voicemail.
Make it easier for clients to reach you. Turn your desk phone and mobile phone into one with Sprint Mobile Integration.
www.seamlessenterprise.com

One number. One voicemail. Sprint Mobile Integration.
www.seamlessenterprise.com

AT&T Synaptic Compute as a Service. Boost your power on demand.

Trial: IBM Cognos Express Reporting, Analysis & Planning

Learn benefits of Simpana software.
View the Gartner Video