How to SetUp MySQL Master-Master Replication on Ubuntu 22.04

To Set MySQL Master To Master Replication On Ubuntu 22.04

Introduction

MySQL replication is when a single data set, stored in a MySQL database, will be live-copied to a second server. This configuration, called “master-slave” replication, is a typical setup. Our setup will be better than that because master-master replication allows data to be copied from either server to the other. This subtle but important difference allows us to perform MySQL reads or writes from either server. This configuration adds redundancy and increases efficiency when dealing with accessing the data.

Procedure Steps

The examples in this article will be based on two server, named Master1 and Master2.
Master1 : 192.168.6.134
Master2 : 192.168.6.133

Install and Configure MySQL on Master1

Step 1: Check the OS Version by using the below command

root@Master1:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.3 LTS
Release:	22.04
Codename:	jammy

Step – 2 : Check the Server hostname by using the below command

root@Master1:~# hostname
Master1

Step – 3 : Then check the server IP Address by using the below command

root@Master1:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:51:d7:29 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.6.134/23 brd 192.168.7.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::ebbc:8197:c5a4:1c08/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Step – 4 : Now install mysql-server and mysql-client by using the below command

root@Master1:~# apt install mysql-server mysql-client -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2 libllvm13
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7 libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client-8.0
  mysql-client-core-8.0 mysql-common mysql-server-8.0 mysql-server-core-8.0
Suggested packages:
  libipc-sharedcache-perl mailx tinyca
The following NEW packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7 libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client mysql-client-8.0
  mysql-client-core-8.0 mysql-common mysql-server mysql-server-8.0 mysql-server-core-8.0
0 upgraded, 21 newly installed, 0 to remove and 241 not upgraded.
Need to get 29.2 MB of archives.
After this operation, 242 MB of additional disk space will be used.
Get:1 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 mysql-common all 5.8+1.0.8 [7,212 B]
Get:2 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-client-core-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [2,692 kB]
Get:3 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-client-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [22.7 kB]
Get:4 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libaio1 amd64 0.3.112-13build1 [7,176 B]
Get:5 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libevent-core-2.1-7 amd64 2.1.12-stable-1build3 [93.9 kB]
Get:6 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libevent-pthreads-2.1-7 amd64 2.1.12-stable-1build3 [7,642 B]
Get:7 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libmecab2 amd64 0.996-14build9 [199 kB]
Get:8 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 libprotobuf-lite23 amd64 3.12.4-1ubuntu7.22.04.1 [209 kB]
Get:9 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-server-core-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [17.5 MB]
Get:10 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-server-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [1,437 kB]
Get:11 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libcgi-pm-perl all 4.54-1 [188 kB]
Get:12 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libfcgi0ldbl amd64 2.4.2-2build2 [28.0 kB]
Get:13 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libfcgi-perl amd64 0.82+ds-1build1 [22.8 kB]
Get:14 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libcgi-fast-perl all 1:2.15-1 [10.5 kB]
Get:15 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libfcgi-bin amd64 2.4.2-2build2 [11.2 kB]
Get:16 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libhtml-template-perl all 2.97-1.1 [59.1 kB]
Get:17 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 mecab-utils amd64 0.996-14build9 [4,850 B]
Get:18 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 mecab-ipadic all 2.7.0-20070801+main-3 [6,718 kB]
Get:19 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 mecab-ipadic-utf8 all 2.7.0-20070801+main-3 [4,384 B]
Get:20 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-client all 8.0.36-0ubuntu0.22.04.1 [9,354 B]
done!
update-alternatives: using /var/lib/mecab/dic/ipadic to provide /var/lib/mecab/dic/debian (mecab-dictionary) in auto mode
Setting up libcgi-fast-perl (1:2.15-1) ...
Setting up mysql-server-core-8.0 (8.0.36-0ubuntu0.22.04.1) ...
emitting matrix      : 100% |###########################################| 
done!
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

Step – 5 : After installing the mysql, Need to configure for that change the mysqld.cnf file by using the below command

root@Master1:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf 
Change the following lines in the configuration file
bind-address        =  192.168.6.134
server-id               =  1
log_bin                 =   /var/log/mysql/mysql-bin.log
binlog_do_db      =  example

Step – 6 : Now restart the MySQL by using the below command

root@Master1:~# systemctl restart mysql

Step – 7 : Need to create a replicate user on MySQL for that login to the MySQL console

root@Master1:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.36-0ubuntu0.22.04.1 (Ubuntu)
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step – 8 : Now Create a user with password by using the below command

mysql> CREATE USER 'replicator'@'%' IDENTIFIED BY 'Linux@123';
Query OK, 0 rows affected (0.03 sec)

Step – 9 : Grant replication slave permission to the user for all databases.

mysql> GRANT REPLICATION SLAVE ON *.* to 'replicator'@'%';
Query OK, 0 rows affected (0.00 sec)

Step – 10 : By running the following command to apply the privileges by using the below command

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Step – 11 : Now show the master status by using the following command and remain the Position number

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

Install and Configure MySQL on Master2

Step – 12 : Now do the same for Master2 server. First check the server hostname

root@Master2:~# hostname
Master2

Step – 13 : Then check the server IP address.

root@Master2:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:22:b3:b8 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.6.133/23 brd 192.168.7.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::ed65:e6a5:ee5d:b483/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Step – 14 : Now install mysql-server and mysql-client by using following command

root@Master2:~# apt install mysql-server mysql-client -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2 libllvm13
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7 libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client-8.0
  mysql-client-core-8.0 mysql-common mysql-server-8.0 mysql-server-core-8.0
Suggested packages:
  libipc-sharedcache-perl mailx tinyca
The following NEW packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7 libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client
  mysql-client-8.0 mysql-client-core-8.0 mysql-common mysql-server mysql-server-8.0 mysql-server-core-8.0
0 upgraded, 21 newly installed, 0 to remove and 241 not upgraded.
Need to get 29.2 MB of archives.
After this operation, 242 MB of additional disk space will be used.
Get:1 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 mysql-common all 5.8+1.0.8 [7,212 B]
Get:2 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-client-core-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [2,692 kB]
Get:3 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-client-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [22.7 kB]
Get:4 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libaio1 amd64 0.3.112-13build1 [7,176 B]
Get:5 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libevent-core-2.1-7 amd64 2.1.12-stable-1build3 [93.9 kB]
Get:6 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libevent-pthreads-2.1-7 amd64 2.1.12-stable-1build3 [7,642 B]
Get:7 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libmecab2 amd64 0.996-14build9 [199 kB]
Get:8 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 libprotobuf-lite23 amd64 3.12.4-1ubuntu7.22.04.1 [209 kB]
Get:9 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-server-core-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [17.5 MB]
Get:10 http://in.archive.ubuntu.com/ubuntu jammy-updates/main amd64 mysql-server-8.0 amd64 8.0.36-0ubuntu0.22.04.1 [1,437 kB]
Get:11 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libcgi-pm-perl all 4.54-1 [188 kB]
Get:12 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libfcgi0ldbl amd64 2.4.2-2build2 [28.0 kB]
Get:13 http://in.archive.ubuntu.com/ubuntu jammy/main amd64 libfcgi-perl amd64 0.82+ds- 
done!
emitting matrix      : 100% |###########################################| 
done!
Setting up mysql-server (8.0.36-0ubuntu0.22.04.1) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

Step – 15 : After installing the mysql, Need to configure for that change the mysqld.cnf file

root@Master2:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf 

Step – 16 : Now restart the mysql by using the following command

root@Master2:~# systemctl restart mysql

Step – 17 : Need to create a replicate user on mysql for that login to the mysql console

root@Master2:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.36-0ubuntu0.22.04.1 (Ubuntu)
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step – 18 : Now Create a user with password by using the following command

mysql> CREATE USER 'replicator'@'%' IDENTIFIED BY 'Linux@123';
Query OK, 0 rows affected (0.04 sec)

Step – 19 : Grant replication slave permission to the user for all databases;

mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
Query OK, 0 rows affected (0.00 sec)

Step – 20 : By running the following command to apply the privileges.

mysql> flush privileges;

Step – 21 : Now show the master status by using the following command and remain the Position number.

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

Step - 22 : Now Stop the slave by using the following command

mysql> stop slave;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

Step – 23 : Then change the MASTER to MASTER_HOST for information that we took a note of earlier and applying it to our mysql instance

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.6.134', MASTER_USER = 'replicator', MASTER_PASSWORD = 'Linux@123', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 870; 
Query OK, 0 rows affected, 8 warnings (0.04 sec)

Step – 24 : Start the slave by using the following command

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.02 sec)

Step – 25 : Go to the Master 1 server and change the settings, first stop the slave.

mysql> stop slave;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

Step – 26 : Then change the MASTER to MASTER_HOST for information that we took a note of earlier and applying it to our mysql instance.

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.6.133', MASTER_USER = 'replicator', MASTER_PASSWORD = 'Linux@123', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 870; 
Query OK, 0 rows affected, 8 warnings (0.04 sec)

Step – 27 : Start the slave by using the following command

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)

Step – 28 : Now check the replication is working or not. If you have the database in the same name in the mysql configuration use that DB, Otherwise need to create a database in same name

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| example            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

Step – 29 : change the database by using the following command

mysql> use example;
Database changed

Step – 30 : Now check by creating the table in the example database

mysql> CREATE TABLE example.dummy (`id` varchar(1));
Query OK, 0 rows affected (0.03 sec)

Step – 31 : Verify that Table is created or not by using the following command

mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| dummy             |
+-------------------+
1 row in set (0.01 sec)

Step – 32 : Go to the Master2 Server and list the databases;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| example            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

Step – 33 : Change the database by using the following command

mysql> use example;
Database changed

Step – 34 : Verify that the table created in the Master1 server is replicated here or not

mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| dummy             |
+-------------------+
1 row in set (0.00 sec)

Step – 35 : Table created here also, now Drop the table.

mysql> DROP TABLE dummy;
Query OK, 0 rows affected (0.02 sec)

Step – 36 : Verify that table is deleted or not

mysql> show tables;
Empty set (0.00 sec)

Step – 37 : Also verify in Master1 server, for that go to the Master1 server and list the tables in the example database.

mysql> show tables;
Empty set (0.00 sec)

Conclusion :

We have reached the end of this article. In this guide, we have walked you through the steps required to setup MySQL Master to Master replication on Ubuntu 22.04. Your feedback is much welcome.

FAQ
Q
How to check the status of the slave server?
A
Use the below command on MySQL console to check the slave status
Q
How do I tell a replica to use row-based replication?
A
Replicas automatically know which format to use.
Q
How to Check the value of the binlog_format system variable?
A
Use the below command on MySQL console to get the value of the binlog_format
mysql> SHOW VARIABLES LIKE 'binlog_format';
Q
How do I prevent GRANT and REVOKE statements from replicating to replica machines?
A
Start the server with the --replicate-wild-ignore-table=mysql.% option to ignore replication for tables in the MySQL database
Q
How to install MySQL server on a Linux machine?
A
By using the following command you can install MySQL
#apt install mysql-server