()

How to Setup MySQL Master-Master Replication (Circular Replication)


Master-Master Replication
(Circular Replication) also known as ring topology in MySQL, this setup requires two or more MySQL servers which act as a master. All masters receive writes and generate binlogs.

Below points should be considered while doing the master-master setup.

  • You need to set an auto-increment offset on each server to avoid primary key collisions.
  • There is no conflict resolution.
  • MySQL Replication currently does not support the atomicity of updates across two different servers.


We have already set up 2 mysql instances in test-machine01 server running on port 3306 (Server_ID : 1) & 3307 (Server_ID : 3), We have also changed the mysql prompt to Master-1Master-2, and Replica for easy understanding.

HostnameIPRole
Server_ID
Port
Installation Link
test-machine01192.168.114.177Master-113306Click Here
test-machine01192.168.114.177Master-233307Click Here

Master-1: Below are the Master-1 configuration parameters

mysql> prompt mysql Master-1>
PROMPT set to 'mysql Master-1>'
mysql Master-1>

mysql Master-1>select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 13ecba9c-444a-11eb-a397-000c29f9d9e6 |
+--------------------------------------+
1 row in set (0.00 sec)

mysql Master-1>
mysql Master-1>
mysql Master-1>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

mysql Master-1>select @@port;
+--------+
| @@port |
+--------+
|   3306 |
+--------+
1 row in set (0.00 sec)

mysql Master-1>


[mysqld@inst1]
#General
user = mysql
port = 3306
server_id = 1
socket=/var/lib/mysql/mysql.sock
pid_file=/var/run/mysqld/mysqld.pid

# Data Storage
datadir=/var/lib/mysql
innodb_directories="/u01/mysql/"

#Logging
log_bin = /var/lib/mysql/binlog
log_error = /var/lib/mysql/mysqld.log
expire_logs_days = 7
relay_log = /var/lib/mysql/relay_bin01
relay_log_index = /var/lib/mysql/relay_bin.index
relay_log_recovery = on
master_info_repository = TABLE
relay_log_info_repository = TABLE

# GTID Based Replication Parameter
gtid-mode=on
enforce-gtid-consistency=1
log_slave_updates= 1
auto_increment_increment=2
auto_increment_offset=1


Master-1: Below are the Master-2 configuration parameters

mysql> prompt mysql Master-2>
PROMPT set to 'mysql Master-2>'
mysql Master-2>

mysql Master-2>select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 98411332-6aad-11eb-809a-000c29f9d9e6 |
+--------------------------------------+
1 row in set (0.00 sec)

mysql Master-2>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

mysql Master-2>select @@port;
+--------+
| @@port |
+--------+
|   3307 |
+--------+
1 row in set (0.00 sec)

mysql Master-2>


[mysqld@inst2]
#General
user = mysql
port=3307
server_id = 3
socket=/u01/mysql-2/mysql.sock
pid_file=/u01/mysql-2/mysqld.pid

# Data Storage
basedir=/u01/mysql-2
datadir=/u01/mysql-2/data
innodb_directories="/u01/mysql/"
plugin_dir=/usr/lib64/mysql/plugin

#Logging
log_bin = /u01/mysql-2/data/binlog
log_error = /u01/mysql-2/data/mysqld.log
expire_logs_days = 7
relay_log = /u01/mysql-2/data/relay_bin01
relay_log_index = /u01/mysql-2/data/relay_bin.index
relay_log_recovery = on
master_info_repository = TABLE
relay_log_info_repository = TABLE

# GTID Based Replication Parameter
gtid-mode=on
enforce-gtid-consistency=1
log_slave_updates= 1
auto_increment_increment=2
auto_increment_offset=2


Step 1. Configuration Setup: Setup above parameters in masters configuration file (my.cnf) and restart both mysql instance.

[root@test-machine01 ~]# systemctl restart mysqld@inst1
[root@test-machine01 ~]#
[root@test-machine01 ~]# systemctl restart mysqld@inst2
[root@test-machine01 ~]#


Step 2.: Create Replication User: Create replication user in both master mysql instances. This user will be used by replica to connect to the master instance.

mysql Master-1>CREATE USER IF NOT EXISTS 'repluser'@'%' IDENTIFIED BY 'Password123#@!';
Query OK, 0 rows affected (0.06 sec)
 
mysql Master-1>GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repluser'@'%';
Query OK, 0 rows affected (0.00 sec)
 
mysql Master-1>ALTER USER 'repluser'@'%' IDENTIFIED WITH mysql_native_password BY 'Password123#@!';
Query OK, 0 rows affected (0.00 sec)
 
mysql Master-1>flush privileges;
Query OK, 0 rows affected (0.00 sec)
 
mysql Master-1>
 
mysql Master-2>CREATE USER IF NOT EXISTS 'repluser'@'%' IDENTIFIED BY 'Password123#@!';
Query OK, 0 rows affected (0.06 sec)
 
mysql Master-2>GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repluser'@'%';
Query OK, 0 rows affected (0.00 sec)
 
mysql Master-2>ALTER USER 'repluser'@'%' IDENTIFIED WITH mysql_native_password BY 'Password123#@!';
Query OK, 0 rows affected (0.00 sec)
 
mysql Master-2>flush privileges;
Query OK, 0 rows affected (0.00 sec)
 
mysql master2 >


Step 3. Reset Master: Execute reset master command to reset Executed_Gtid_Set variable in both masters mysql instances.


Master-1

mysql Master-1>show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000004 |      196 |              |                  | 13ecba9c-444a-11eb-a397-000c29f9d9e6:1-7 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql Master-1>
mysql Master-1>reset master;
Query OK, 0 rows affected (0.07 sec)

mysql Master-1>show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql Master-1>


Master-2

mysql Master-2>show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000002 |      196 |              |                  | 98411332-6aad-11eb-809a-000c29f9d9e6:1-9 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql Master-2>
mysql Master-2>
mysql Master-2>reset master;
Query OK, 0 rows affected (0.07 sec)

mysql Master-2>show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql Master-2>
mysql Master-2>


Step 4. Dummy Transaction: Execute dummy transaction in both masters mysql instances to increment Executed_Gtid_Set variable to 1 and note down Executed_Gtid_Set value.


Master-1

mysql Master-1>use repl_test;
Database changed
mysql Master-1>create table dummy ( id int);
Query OK, 0 rows affected (0.06 sec)

mysql Master-1>show master status;
+---------------+----------+--------------+------------------+----------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+---------------+----------+--------------+------------------+----------------------------------------+
| binlog.000001 |      363 |              |                  | 13ecba9c-444a-11eb-a397-000c29f9d9e6:1 |
+---------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

mysql Master-1>


Master-2

mysql Master-2>use repl_test;
Database changed

mysql Master-2>create dummy test ( id int);
Query OK, 0 rows affected (0.07 sec)

mysql Master-2>show master status;
+---------------+----------+--------------+------------------+----------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+---------------+----------+--------------+------------------+----------------------------------------+
| binlog.000001 |      363 |              |                  | 98411332-6aad-11eb-809a-000c29f9d9e6:1 |
+---------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

mysql Master-


Step 5: Update Executed_Gtid_Set: Update variable gtid_purged with Executed_Gtid_Set value from the above output and update master information and then start replica.


Master-1

mysql Master-1>
mysql Master-1>SET @@GLOBAL.gtid_purged = "98411332-6aad-11eb-809a-000c29f9d9e6:1";
Query OK, 0 rows affected (0.00 sec)

mysql Master-1>

mysql Master-1>CHANGE MASTER TO MASTER_HOST='192.168.114.177',MASTER_USER='repluser',MASTER_PASSWORD='Password123#@!',MASTER_PORT=3307,MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql Master-1>start replica ;
Query OK, 0 rows affected (0.00 sec)

mysql Master-1>


Master-2

mysql Master-2>SET @@GLOBAL.gtid_purged = "13ecba9c-444a-11eb-a397-000c29f9d9e6:1";
Query OK, 0 rows affected (0.07 sec)

mysql Master-2>
mysql Master-2>CHANGE MASTER TO MASTER_HOST='192.168.114.177',MASTER_USER='repluser',MASTER_PASSWORD='Password123#@!',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.08 sec)

mysql Master-2>start replica ;
Query OK, 0 rows affected (0.01 sec)

mysql Master-2>


Step 6: Check Status: Execute command show replica status to validate the status.

Master-1

mysql Master-1>show replica status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.114.177
                  Master_User: repluser
                  Master_Port: 3307
                Connect_Retry: 60
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 363
               Relay_Log_File: relay_bin01.000002
                Relay_Log_Pos: 409
        Relay_Master_Log_File: binlog.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: 363
              Relay_Log_Space: 614
              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:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 3
                  Master_UUID: 98411332-6aad-11eb-809a-000c29f9d9e6
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 13ecba9c-444a-11eb-a397-000c29f9d9e6:1,
98411332-6aad-11eb-809a-000c29f9d9e6:1
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
       Master_public_key_path:
        Get_master_public_key: 0
            Network_Namespace:
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

mysql Master-1>


Master-2

mysql Master-2>show replica status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.114.177
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 363
               Relay_Log_File: relay_bin01.000002
                Relay_Log_Pos: 409
        Relay_Master_Log_File: binlog.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: 363
              Relay_Log_Space: 614
              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:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 13ecba9c-444a-11eb-a397-000c29f9d9e6
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 13ecba9c-444a-11eb-a397-000c29f9d9e6:1,
98411332-6aad-11eb-809a-000c29f9d9e6:1
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
       Master_public_key_path:
        Get_master_public_key: 0
            Network_Namespace:
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

mysql Master-2>


Step 7: Test replication configuration: Execute transaction in both master mysql instances and validate if the same transaction replicated in other master instances.


Master-1

mysql Master-1>use repl_test;
Database changed

mysql Master-1>create table repl_test8 as select *from repl_test7;
Query OK, 28 rows affected (0.07 sec)
Records: 28  Duplicates: 0  Warnings: 0


Master-2

mysql Master-2>show tables ;
+---------------------+
| Tables_in_repl_test |
+---------------------+
| repl_test           |
| repl_test1          |
| repl_test2          |
| repl_test3          |
| repl_test4          |
| repl_test5          |
| repl_test6          |
| repl_test8          |
| test                |
+---------------------+
9 rows in set (0.00 sec)


Master-2

mysql Master-2>create table repl_test9 as select *from repl_test8;
Query OK, 28 rows affected (0.01 sec)
Records: 28  Duplicates: 0  Warnings: 0

mysql Master-2>


Master-1

mysql Master-1>show tables ;
+---------------------+
| Tables_in_repl_test |
+---------------------+
| repl_test1          |
| repl_test2          |
| repl_test3          |
| repl_test4          |
| repl_test5          |
| repl_test6          |
| repl_test7          |
| repl_test8          |
| repl_test9          |
| test                |
+---------------------+
10 rows in set (0.01 sec)

mysql Master-1>

This document is only for learning purpose and always validate in the LAB environment first before applying in the LIVE environment.


Hope so you like this article
!
Please share your valuable feedback/comments/subscribe and follow us below and don’t forget to click on the bell icon to get the latest update. Click here to know more about our pursuit.

Loading

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Jamsher Khan

Hello and welcome to DBsGuru,I’m Jamsher Khan working as Senior Oracle DBA based in KSA-Jeddah, I have working experience in Oracle DBA, SQL Server, MySql, PostgreSQL, Linux, Golden Gate, ODA.Thanks for the visits!Share Learn Grow!