How to Set Up MariaDB Master-Slave Replication

A MariaDB master-slave replication enables you to create a copy of a database (slave) that tracks and copies changes from master database in real-time. It is useful setup in backup strategies, data recovery, and load balancing by distributing database reads to reduce load on the primary server . In this tutorial, we will walk you through the complete steps of configuring MariaDB master-slave replication on Linux servers.

Setup Requirements

Before we get started, make sure you meet the following requirements:

  • Two Linux servers that has MariaDB installed – One will be Master, and the other Slave.
  • SSH access to the servers with root privileges.
  • Both servers should have static IPs configured – Don’t use DHCP.
  • Configured Firewall to allow MySQL service port – 3306

In our example, there will be two servers with the following IP addresses, and hostnames:

Server IPServer HostnameServer Role
192.168.1.50dbmaster.cloudspinx.comMaster DB Server
192.168.1.51dbslave.cloudspinx.comSlave DB Server

Install Master DB Server

If DB server doesn’t exist already, install MariaDB database server:

  • Debian / Ubuntu:
sudo apt update
sudo apt -y install mariadb-server
  • Rocky / AlmaLinux:
sudo dnf install @mariadb
sudo systemctl enable --now mariadb

Secure database server installation:

  • Newer MariaDB releases:
sudo mariadb-secure-installation
  • Older MariaDB releases:
sudo mysql_secure_installation

Choose your preferred hardening configurations.

Switch to unix_socket authentication [Y/n] n
Change the root password? [Y/n] y
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Configure MariaDB master server

A replication user is needed, which is responsible for syncing data from the primary(master) database to the replica(slave). Login to MySQL shell:

sudo mysql -u root -p

We are going to create replication user with the following details:

  • User: replicausr
  • Password: Str0ngPassw0rD
  • Connection from address: % or IP
CREATE USER 'replicausr'@'%' IDENTIFIED BY 'Str0ngPassw0rD';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;
EXIT;

Edit database server configuration and set:

[mysqld]
server-id = 1
log_bin = mariadb-bin

Restart mariadb service after the changes:

sudo systemctl restart mariadb

Run the following commands in MariaDB shell and ensure that File and Position values are shown.

MariaDB [(none)]> show master status\G
*************************** 1. row ***************************
            File: mariadb-bin.000001
        Position: 245
    Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

Allow remote connections on master server

On the primary database server, set listed address to the actual server IP address. Check listening address:

sudo ss -tunelp | grep 3306

If you see *:3306, there’s no need to change it – this means it’s listening on all interfaces.

tcp    LISTEN     0      50        *:3306                  *:*                   users:(("mysqld",pid=18511,fd=15)) uid:27 ino:59667213 sk:ffff8f9df0b33e00 <->

Depending on your distro, locate MariaDB server configuration file and set bind-address inside [mysqld] block.

[mysqld]
#bind-address = 192.168.1.50

If you have Firewalld or UFW, and would like to only allow database remote connections from Slave IP configured as below.

  • Firewalld rich-rules:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.51/32" service name="mysql" accept'
sudo firewall-cmd --reload
  • UFW:
sudo ufw allow from 192.168.1.51 to any port 3306 proto tcp
sudo ufw reload

Dump and Copy databases from master to slave

Dump all databases from the Master DB:

mysqldump -u root -p --all-databases --single-transaction --master-data=2 --events > dbs_dump.sql

Enter the database root user’s password to perform the dump. Once done, validate the size:

$ du -sh dbs_dump.sql
29G	dbs_dump.sql

Transfer the dump to the slave server:

scp dbs_dump.sql [email protected]:
scp dbs_dump.sql [email protected]:

Configure MariaDB Slave

Confirm the version of MariaDB installed on the primary database server:

$ mariadb -V
mariadb  Ver 15.1 Distrib 10.5.28-MariaDB, for Linux (x86_64) using readline 5.1

Try as much as possible to install the same version on the replica. After package installation, you need to configure Slave server.

Common database server configuration paths:

  • /etc/mysql/mariadb.conf.d/50-server.cnf
  • /etc/my.cnf.d/server.cnf

Edit the MariaDB configuration file to configure as slave server.

[mysqld]
read_only=1
server-id = 2
report-host=dbslave
log-bin=mariadb-bin
relay-log=mariadb-relay-bin
slow_query_log_file=/var/log/mysql/mariadb-slow.log
expire_logs_days = 3

Create log directory if doesn’t exist, and set correct permissions.

sudo mkdir /var/log/mysql
sudo chown -R mysql:mysql /var/log/mysql

Stop and start the database service after making the changes:

sudo systemctl stop mariadb
sudo systemctl start mariadb

If you have Firewalld or UFW, you can permit connections from Master DB IP:

  • Firewalld rich-rules:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50/32" service name="mysql" accept'
sudo firewall-cmd --reload
  • UFW:
sudo ufw allow from 192.168.1.50 to any port 3306 proto tcp
sudo ufw reload

Import the database file exported from the master.

mysql -u root -p < dbs_dump.sql

Start Replication service on the Slave

Test connection to Master DB from Slave:

mysql -h 192.168.1.51 -u replicausr -p
Str0ngPassw0rD

Login to the MariaDB shell:

sudo mysql -u root -p

Retrieve the master binary log file and position:

$ head -n 50  dbs_dump.sql|egrep "CHANGE MASTER TO"
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=105;

Then set up the replication:

CHANGE MASTER TO
  MASTER_HOST='192.168.1.50',
  MASTER_USER='replicausr',
  MASTER_PASSWORD='Str0ngPassw0rD',
  MASTER_LOG_FILE='mariadb-bin.000001',
  MASTER_LOG_POS=105;

Replace MASTER_LOG_FILE and MASTER_LOG_POS with the values retrieved earlier from the master server.

Once done, start slave:

START SLAVE;

Verify the Replication Status

Check the replication status:

SHOW SLAVE STATUS\G

Check for:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes

Sample output:

MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 192.168.1.50
                   Master_User: replica_user
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mariadb-bin.000002
           Read_Master_Log_Pos: 110574028
                Relay_Log_File: mariadb-relay-bin.000002
                 Relay_Log_Pos: 90380422
         Relay_Master_Log_File: mariadb-bin.000002
              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: 245
               Relay_Log_Space: 857
               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_SSL_Crl:
            Master_SSL_Crlpath:
                    Using_Gtid: No
                   Gtid_IO_Pos:
       Replicate_Do_Domain_Ids:
   Replicate_Ignore_Domain_Ids:
                 Parallel_Mode: optimistic
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: closing tables
              Slave_DDL_Groups: 15
Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 71914680
1 row in set (0.000 sec)

The Seconds_Behind_Master: 0 is a key indicator in MySQL or MariaDB replication. It may take a while for it to turn 0.

Use STOP SLAVE; and RESET SLAVE; if you need to reconfigure.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Unlock the Right Solutions with Confidence

At CloudSpinx, we don’t just offer services - we deliver clarity, direction, and results. Whether you're navigating cloud adoption, scaling infrastructure, or solving DevOps challenges, our seasoned experts help you make smart, strategic decisions with total confidence. Let us turn complexity into opportunity and bring your vision to life.

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

In this tutorial we will cover step-by-step procedure of compiling Open vSwitch (OVS) from source code on Rocky Linux, AlmaLinux, […]

Open vSwitch (OVS) is an open source virtual switch widely adopted in network virtualization. OVS is popular in platforms like […]

Photoshop can be such a headache for both experts and beginners alike. Every time you open photoshop there’s always a […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.