Testing MySQL InnoDB Cluster in a controlled lab is essential before committing to it in production. This guide walks through a practical, repeatable setup on RHEL/Rocky Linux that you can run on VMs or cloud instances.
1. Lab goals and topology
Define what you want from the lab:
- Understand Group Replication behaviour (failover, conflicts, flow control).
- Test application connection patterns via MySQL Router.
- Practise planned and unplanned failover.
- Validate backup and recovery in a clustered context.
A simple but realistic topology is three data nodes plus one router node.
┌───────────────────────────────────────────────┐
│ InnoDB Cluster │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ node1 │ │ node2 │ │ node3 │ │
│ │ (RW) │ │ (RO/RW) │ │ (RO/RW) │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ ▲ ▲ ▲ │
│ │ Group Replication (GCS) │ │
└────────┴─────────────┴──────────────┴─────────┘
▲
│
┌──────────────┐
│ MySQL Router │
└──────────────┘
Host suggestions (can be VMs on a single laptop):
node1.lab.local– MySQL server (primary seed).node2.lab.local– MySQL server.node3.lab.local– MySQL server.router.lab.local– MySQL Router and test client tools.
2. Base OS preparation (RHEL / Rocky Linux)
On each node, perform basic OS setup.
2.1 System packages and networking
sudo dnf -y update
sudo dnf -y install wget curl vim net-tools firewalld
# Enable and start firewalld
sudo systemctl enable firewalld --now
Ensure hostnames resolve consistently. For a lab, you can use /etc/hosts on all nodes:
192.168.56.11 node1.lab.local node1
192.168.56.12 node2.lab.local node2
192.168.56.13 node3.lab.local node3
192.168.56.14 router.lab.local router
2.2 Time synchronisation
Group Replication is sensitive to clock drift. Enable NTP:
sudo dnf -y install chrony
sudo systemctl enable chronyd --now
3. Install MySQL server on the three data nodes
Install a standard MySQL Server package from a vendor repository that supports Group Replication and InnoDB Cluster. The exact repo commands vary by vendor, but on RHEL/Rocky you typically:
# Example: enable vendor repo (adjust for your chosen distribution)
# sudo dnf -y install https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
# sudo dnf config-manager --enable mysql80-community
sudo dnf -y install mysql-community-server
sudo systemctl enable mysqld --now
Retrieve the temporary root password (for the first login):
sudo grep 'temporary password' /var/log/mysqld.log
Log in and set a strong root password:
mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongRootPassw0rd!';
4. Configure MySQL for Group Replication
On each of the three data nodes, edit /etc/my.cnf (or a drop-in under /etc/my.cnf.d/). Adjust server IDs, hostnames and IPs appropriately.
4.1 Basic InnoDB and binary logging
[mysqld]
server_id=1 # 2 on node2, 3 on node3
log_bin=binlog
binlog_format=ROW
binlog_checksum=CRC32
transaction_write_set_extraction=XXHASH64
# InnoDB settings suitable for lab
innodb_flush_log_at_trx_commit=1
sync_binlog=1
# Required for Group Replication
plugin_load_add=group_replication.so
4.2 Group Replication configuration
Still in [mysqld] on each node:
group_replication_group_name="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# Local address for this node
# Example for node1; change port or IP per node if needed
group_replication_local_address="node1.lab.local:33061"
# List all members (same on all nodes)
group_replication_group_seeds=
"node1.lab.local:33061,node2.lab.local:33061,node3.lab.local:33061"
group_replication_start_on_boot=OFF
group_replication_bootstrap_group=OFF
group_replication_single_primary_mode=ON
group_replication_enforce_update_everywhere_checks=OFF
Restart MySQL on each node:
sudo systemctl restart mysqld
5. Create an InnoDB Cluster with MySQL Shell
Install MySQL Shell on one host (router node is a good place):
sudo dnf -y install mysql-shell
5.1 Create an admin user
On each data node, create a dedicated cluster admin user:
mysql -uroot -p
CREATE USER 'clusterAdmin'@'%' IDENTIFIED BY 'Str0ngClusterPass!';
GRANT ALL PRIVILEGES ON *.* TO 'clusterAdmin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
5.2 Configure instances for InnoDB Cluster
From the router node, use MySQL Shell in JavaScript or Python mode. This example uses JavaScript:
mysqlsh --js
// Connect to node1
shell.connect('[email protected]:3306');
// Configure instance for Group Replication
dba.configureInstance({
user: 'clusterAdmin',
host: 'node1.lab.local',
port: 3306
});
// Repeat for node2 and node3
shell.connect('[email protected]:3306');
dba.configureInstance({ user: 'clusterAdmin', host: 'node2.lab.local', port: 3306 });
shell.connect('[email protected]:3306');
dba.configureInstance({ user: 'clusterAdmin', host: 'node3.lab.local', port: 3306 });
5.3 Create and grow the cluster
// Back to node1 as seed
shell.connect('[email protected]:3306');
var cluster = dba.createCluster('labCluster');
// Add the other nodes
cluster.addInstance('[email protected]:3306');
cluster.addInstance('[email protected]:3306');
// Check status
cluster.status();
You should see all three instances ONLINE, with one PRIMARY and two SECONDARY members.
6. Add MySQL Router for application access
On router.lab.local, install MySQL Router:
sudo dnf -y install mysql-router
Bootstrap the router against the cluster (this creates configuration and systemd unit files):
mysqlrouter --bootstrap [email protected]:3306 \
--directory /etc/mysqlrouter \
--user mysqlrouter
Enable and start the router:
sudo systemctl enable mysqlrouter --now
Check which ports are in use (usually one for read-write and one for read-only):
grep "bind_port" /etc/mysqlrouter/mysqlrouter.conf
Test connectivity from the router node:
mysql -h 127.0.0.1 -P 6446 -u clusterAdmin -p # RW port example
mysql -h 127.0.0.1 -P 6447 -u clusterAdmin -p # RO port example
7. Firewall and SELinux considerations
Open MySQL and Group Replication ports on each data node:
sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --permanent --add-port=33061/tcp
sudo firewall-cmd --reload
On the router node, open router ports as needed (example 6446 and 6447):
sudo firewall-cmd --permanent --add-port=6446/tcp
sudo firewall-cmd --permanent --add-port=6447/tcp
sudo firewall-cmd --reload
If SELinux is enforcing, use semanage port to label additional ports for MySQL-related services instead of disabling SELinux.
8. Basic lab exercises
8.1 Write and read tests
From router.lab.local, connect via the RW port and create a test schema:
mysql -h 127.0.0.1 -P 6446 -u clusterAdmin -p
CREATE DATABASE labtest;
USE labtest;
CREATE TABLE t1 (
id INT PRIMARY KEY AUTO_INCREMENT,
payload VARCHAR(100)
) ENGINE=InnoDB;
INSERT INTO t1 (payload) VALUES ('row1'), ('row2');
On another terminal, connect to any node directly and verify data:
mysql -h node2.lab.local -u clusterAdmin -p -e "SELECT * FROM labtest.t1"
8.2 Failover simulation
Observe which node is PRIMARY:
mysqlsh --js
shell.connect('[email protected]');
var cluster = dba.getCluster('labCluster');
cluster.status();
Simulate a failure by stopping MySQL on the PRIMARY (lab only):
sudo systemctl stop mysqld # On the PRIMARY node only, in the lab
Watch the cluster re-elect a PRIMARY and confirm that RW connections via MySQL Router continue to work. Then restart the stopped node and verify it rejoins:
sudo systemctl start mysqld
cluster.status();
9. Best practices for a useful lab
- Automate builds: Use scripts or Ansible to recreate the lab quickly. This makes it easy to test new versions or topology changes.
- Use realistic schemas: Load anonymised production-like data to exercise replication, indexes and query plans.
- Test backups: Combine physical (e.g. file-level or snapshot) and logical (e.g.
mysqldump) backups and practise restoring a node into the cluster. - Exercise maintenance tasks: Rolling restarts, configuration changes, and version upgrades are all safer when rehearsed in the lab.
- Observe metrics: Enable the Performance Schema and sys schema; monitor replication lag, flow control and transaction conflicts.
- Document scenarios: Keep a runbook of commands and outcomes for failure tests, so you can compare future behaviour after upgrades.
10. Conclusion
A small InnoDB Cluster lab built on three MySQL nodes and one router node is enough to understand how Group Replication behaves, how applications should connect, and how operational tasks work in practice. By automating the build, using realistic data, and repeatedly testing failure and recovery scenarios, you gain confidence and clear procedures before deploying InnoDB Cluster into any production environment.
This article offers general technical guidance. Validate all configurations in a safe environment before applying them to production.


Leave a Reply