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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here