We are assuming these:
- Same version and same setup of MySQL is installed on SOURCE (Master) host and TARGET (AKA Replica or Slave) host.
- In our example our Source/Master is 192.168.100.1
- In our example our Target/Slave is 192.168.100.2
- For username for replication, we'll use 'replicator' as example.
1. Backup MySQL configcp /etc/mysql/my.cnf /etc/mysql/my.cnf.BACKUP_`date +%Y%m%s_%H%M%S`
2. Edit /etc/mysql/my.cnfAdd:[mysqld] server-id = 1 log_bin = mysql-bin binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON binlog_row_image = FULL log_slave_updates = ON binlog_expire_logs_seconds = 604800 # optional, keep binlogs 7 daysSave changes.
3. Restart MySQL on Source/Mastersudo systemctl restart mysql
1. Backup MySQL configcp /etc/mysql/my.cnf /etc/mysql/my.cnf.BACKUP_`date +%Y%m%s_%H%M%S`
2. Edit /etc/mysql/my.cnfAdd:[mysqld]
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_format = ROW
log_slave_updates = ON
relay_log = relay-bin
read_only = ON
super_read_only = ON
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 4
Save changes
3. Restart MySQL on Target/Slavesudo systemctl restart mysql
1. Login to MySQL:mysql -u root -p2. Create the replication user:mysql> CREATE USER 'replicator'@'<SLAVE_IP>' IDENTIFIED BY '<password>';
OR
mysql> CREATE USER 'replicator'@'<SLAVE_IP>' IDENTIFIED WITH mysql_native_password BY '<password>';
NOTE: Replace <SLAVE_IP> with the IP address of your slave host, and <password> with actual password.Example:
mysql> CREATE USER 'replicator'@'192.168.100.2' IDENTIFIED BY 'mySecretpw%489';ORmysql> CREATE USER 'replicator'@'%' IDENTIFIED BY '12345678';
3. Grant access:mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'<SLAVE_IP>';Example:mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'192.168.100.2';mysql> FLUSH PRIVILEGES;
4. Exit:mysql > exit;
1. Login to MySQL:mysql -u root -p
2. Flush:mysql> FLUSH TABLES WITH READ LOCK;NOTE, this lock prevent changes to be made to all tables. To unlock, use:mysql> UNLOCK TABLES;
3. Get master status:mysql> SHOW MASTER STATUS;+------------------+----------+--------------+------------------+------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+------------------------------------------+ | mysql-bin.000001 | 896 | | | c1a85a0a-4afc-11f0-b090-bc2411487311:1-3 | +------------------+----------+--------------+------------------+------------------------------------------+ 1 row in set (0.00 sec)4. List all GTIDs processedmysql> SELECT @@GLOBAL.GTID_EXECUTED;+------------------------------------------+ | @@GLOBAL.GTID_EXECUTED | +------------------------------------------+ | c1a85a0a-4afc-11f0-b090-bc2411487311:1-3 | +------------------------------------------+ 1 row in set (0.00 sec)Keep this terminal open so the lock stays in place
1. Login to MySQL:mysql -u root -p
2. SQL:mysql> SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';mysql> SET GLOBAL slave_parallel_workers = 4;
3. Configure replication (SQL):
mysql>STOP SLAVE;mysql> RESET SLAVE ALL;
NON-SSL:mysql> CHANGE MASTER TOMASTER_HOST='192.168.100.1',MASTER_USER='replicator',MASTER_PASSWORD='replicaPass@123',MASTER_AUTO_POSITION=1;
SSL-ENABLED:CHANGE MASTER TO
MASTER_HOST='192.168.100.1',
MASTER_USER='replicator',
MASTER_PASSWORD='replicaPass@123',
MASTER_AUTO_POSITION=1,
MASTER_SSL=1,
MASTER_SSL_CA='/etc/mysql/certs/self-ca.pem',
MASTER_SSL_CERT='/etc/mysql/certs/self-slave-cert.pem',
MASTER_SSL_KEY='/etc/mysql/certs/self-slave-key.pem';
mysql> START SLAVE;4. See status:mysql> SHOW SLAVE STATUS\G
On MASTERCreate a test database on On master (test_replica):mysql> CREATE DATABASE IF NOT EXISTS test_replica;mysql> use test_replica;mysql> CREATE TABLE IF NOT EXISTS replication_test (
id INT PRIMARY KEY AUTO_INCREMENT,
message VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);mysql> INSERT INTO replication_test (message) VALUES ('Hello from master!');
mysql> FLUSH TABLES WITH READ LOCK;
On SLAVECheck if the test datanase created on Master, is also on the Slave:
mysql> show databases;+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test_replica | | testdb | +--------------------+ 6 rows in set (0.00 sec)NOTE: 'test_replica' should replicate over to the slave as seen above.mysql> use test_replica;mysql> SELECT * FROM replication_test;+----+--------------------+---------------------+ | id | message | created_at | +----+--------------------+---------------------+ | 1 | Hello from master! | 2025-06-17 15:15:56 | +----+--------------------+---------------------+ 1 row in set (0.00 sec)