MySQL primary-replica replication (formerly called master-slave) copies data changes from a primary (write) server to one or more replica (read) servers in near-real-time. Replication solves multiple operational problems: distributing read traffic across replicas reduces load on the primary, a replica provides a hot standby for failover if the primary fails, replicas can be used for backups without impacting the primary, and point-in-time recovery is possible from the binary log. MySQL replication uses binary logs — the primary records every data-changing query in the binary log (binlog), and each replica connects, reads new binlog events, and replays them. This guide covers setting up asynchronous row-based replication between a primary and a replica MySQL server on RHEL 9.
Prerequisites
- Two RHEL 9 servers with MySQL 8 installed on each
- Primary IP:
10.0.1.10| Replica IP:10.0.1.11 - MySQL running and accessible on both servers
Step 1 — Configure the Primary Server
# /etc/my.cnf.d/primary.cnf on the PRIMARY server (10.0.1.10)
[mysqld]
server-id = 1 # Must be unique across all servers
log_bin = /var/lib/mysql/mysql-bin
binlog_format = ROW # Row-based replication (recommended)
binlog_row_image = FULL
expire_logs_days = 7
gtid_mode = ON # GTID-based replication (simpler failover)
enforce_gtid_consistency = ON
systemctl restart mysqld
# Create a dedicated replication user on the PRIMARY
mysql -u root -p <<'SQL'
CREATE USER 'replicator'@'10.0.1.11' IDENTIFIED WITH caching_sha2_password BY 'ReplPassword123!';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'10.0.1.11';
FLUSH PRIVILEGES;
SHOW MASTER STATUSG
SQL
Step 2 — Configure the Replica Server
# /etc/my.cnf.d/replica.cnf on the REPLICA server (10.0.1.11)
[mysqld]
server-id = 2 # Must differ from primary
log_bin = /var/lib/mysql/mysql-bin
relay_log = /var/lib/mysql/relay-bin
read_only = ON # Prevent accidental writes to replica
gtid_mode = ON
enforce_gtid_consistency = ON
log_replica_updates = ON
systemctl restart mysqld
Step 3 — Take a Snapshot of the Primary and Copy to Replica
# On the PRIMARY: dump all databases with GTID position
mysqldump -u root -p --all-databases --single-transaction --master-data=2 --triggers --routines --events > /tmp/primary-snapshot.sql
# Copy to the replica
scp /tmp/primary-snapshot.sql [email protected]:/tmp/
# On the REPLICA: restore the snapshot
mysql -u root -p < /tmp/primary-snapshot.sql
Step 4 — Start Replication on the Replica
# On the REPLICA
mysql -u root -p <<'SQL'
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='10.0.1.10',
SOURCE_USER='replicator',
SOURCE_PASSWORD='ReplPassword123!',
SOURCE_AUTO_POSITION=1; -- Uses GTID (no need to specify binlog file/pos)
START REPLICA;
SHOW REPLICA STATUSG
SQL
In the output, verify: Replica_IO_Running: Yes and Replica_SQL_Running: Yes
Step 5 — Test Replication
# On PRIMARY: create a test table
mysql -u root -p -e "CREATE DATABASE reptest; USE reptest; CREATE TABLE t1 (id INT PRIMARY KEY, val VARCHAR(50)); INSERT INTO t1 VALUES (1,'hello');"
# On REPLICA: verify it appeared
mysql -u root -p -e "USE reptest; SELECT * FROM t1;"
Conclusion
MySQL GTID-based primary-replica replication on RHEL 9 provides automatic failover capabilities, read scaling, and a real-time hot standby. GTID replication eliminates the need to track binary log file names and positions manually, simplifying failover and the process of adding new replicas. Monitor replication lag with Seconds_Behind_Source from SHOW REPLICA STATUS to ensure the replica stays current with the primary.
Next steps: How to Configure MySQL Group Replication on RHEL 9, How to Secure MySQL on RHEL 9, and How to Back Up MySQL with mysqldump on RHEL 9.