This guide walks through setting up a MySQL InnoDB Cluster from scratch, focusing on practical steps and safe defaults suitable for general engineers.
What Is a MySQL InnoDB Cluster?
A MySQL InnoDB Cluster is a high-availability setup built on Group Replication, MySQL Shell, and MySQL Router. It provides:
- Multiple MySQL instances (InnoDB only) replicating using Group Replication
- Automatic failover via an integrated cluster metadata store
- Application connectivity through MySQL Router
Conceptually, you have three main layers:
+---------------------+
| Applications |
+----------+----------+
|
v
+-------------+
| MySQL Router|
+------+------+
|
+--------+--------+--------+
v v v
+-----+ +-----+ +-----+
| M1 | <------> | M2 | | M3 |
+-----+ (Group +-----+ +-----+
Replication)
Prerequisites and Assumptions
This article assumes:
- Three Linux hosts (or VMs) with network connectivity: db1, db2, db3
- One optional host for MySQL Router (can be one of the DB nodes in labs)
- Same MySQL Server major version on all nodes
- InnoDB as the default storage engine
- Root or sudo access on all machines
Throughout, replace hostnames, passwords, and IPs with values appropriate for your environment.
Step 1: Install MySQL Server and MySQL Shell
Install MySQL Server and MySQL Shell on all three database nodes. Use your distribution packages or official MySQL repositories.
Example (Debian/Ubuntu-like, adjust as needed):
sudo apt-get update
sudo apt-get install mysql-server mysql-shell
Ensure the MySQL service is enabled and running:
sudo systemctl enable mysql
sudo systemctl start mysql
Step 2: Basic MySQL Configuration for InnoDB Cluster
On each node, configure MySQL with settings compatible with Group Replication and InnoDB Cluster. Edit my.cnf (location varies by distribution) on each node.
Warning: Changing these settings on an existing production server can be disruptive. Validate in a test environment first.
Essential InnoDB and Binary Log Settings
Apply on all nodes, adjusting server IDs and hostnames:
[mysqld]
# Unique per server
server_id = 1 # db1: 1, db2: 2, db3: 3
# Required for Group Replication
binlog_format = ROW
log_bin = mysql-bin
binlog_checksum = NONE
transaction_write_set_extraction = XXHASH64
# InnoDB durability (recommended for HA)
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
# Networking and replication
gtid_mode = ON
enforce_gtid_consistency = ON
# Group Replication plugin
plugin_load_add = group_replication.so
Set server_id uniquely on each node. After editing, restart MySQL:
sudo systemctl restart mysql
Create a Cluster Admin User
On the first node (db1), connect as root and create a user for cluster management and replication:
mysql -u root -p
CREATE USER 'cluster_admin'@'%' IDENTIFIED BY 'StrongPass!123';
GRANT ALL PRIVILEGES ON *.* TO 'cluster_admin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
For stricter security, limit the host (e.g. 'cluster_admin'@'10.%') and refine privileges to what InnoDB Cluster requires, but for a lab environment the above is acceptable.
Step 3: Prepare Instances with MySQL Shell
MySQL Shell (mysqlsh) provides AdminAPI commands to configure and manage InnoDB Cluster.
On db1, start MySQL Shell and connect using the admin user:
mysqlsh cluster_admin@db1:3306
Switch to JavaScript mode (AdminAPI examples often use JS):
\js
Instance Configuration
Use AdminAPI to configure each instance for InnoDB Cluster. From db1:
var dba = require('dba');
// Configure db1
dba.configureInstance('cluster_admin@db1:3306', {
interactive: false
});
// Configure db2
dba.configureInstance('cluster_admin@db2:3306', {
interactive: false
});
// Configure db3
dba.configureInstance('cluster_admin@db3:3306', {
interactive: false
});
These commands adjust instance settings (for example, group replication options) and may prompt you to restart MySQL. If you used interactive: false, review the output carefully and perform any required restarts.
Step 4: Create and Bootstrap the InnoDB Cluster
Initial Cluster Creation
On db1 in MySQL Shell (JS mode), create the cluster and bootstrap Group Replication:
var cluster = dba.createCluster('prodCluster');
Then add the first instance (db1 itself) as the seed member:
cluster.addInstance('cluster_admin@db1:3306', {
recoveryMethod: 'clone'
});
If the data directory is not empty, recoveryMethod: 'clone' may overwrite data. Use this only on fresh instances or where data loss is acceptable.
Add the Remaining Instances
Still in MySQL Shell on db1:
cluster.addInstance('cluster_admin@db2:3306', {
recoveryMethod: 'clone'
});
cluster.addInstance('cluster_admin@db3:3306', {
recoveryMethod: 'clone'
});
AdminAPI will clone data from an existing member and configure Group Replication automatically.
Verify Cluster Status
Check the cluster status:
cluster.status();
You should see all three instances listed as ONLINE and the cluster mode as Single-Primary by default (one writable primary, others read-only).
Always verify cluster status after any topology change; do not assume Group Replication has converged until the AdminAPI reports all members as ONLINE.
Operational best practice
Step 5: Configure MySQL Router
MySQL Router provides a stable endpoint for applications, routing writes to the primary and reads to replicas (if configured).
Install MySQL Router on an application host or one of the DB nodes (for labs):
sudo apt-get install mysql-router
Bootstrap Router from the Cluster Metadata
On the Router host, run:
mysqlrouter --bootstrap cluster_admin@db1:3306 \
--directory /var/lib/mysqlrouter \
--user mysqlrouter
This connects to the InnoDB Cluster, reads its metadata, and creates a router configuration with separate endpoints for read-write and read-only traffic.
Start and enable the Router service (command names may vary by packaging):
sudo systemctl enable mysqlrouter
sudo systemctl start mysqlrouter
Connect Applications via Router
Typically, Router exposes ports like:
- Read-write: 6446
- Read-only: 6447
Applications can then connect using:
mysql -u app_user -p -h router_host -P 6446
This keeps application configuration stable across failovers.
Step 6: Testing Failover
Once the cluster is up and Router is configured, test failover behaviour in a non-production environment.
- Identify the primary:
cluster.status();
- Connect an application or MySQL client through Router to the read-write port and perform some writes.
- Simulate a primary failure by stopping MySQL on the primary node:
sudo systemctl stop mysql
- Observe cluster status again and confirm a new primary is elected.
- Verify that writes through Router still succeed.
Warning: Do not perform failover tests on a production cluster during business hours. Always coordinate and test on staging first.
Best Practices and Operational Tips
Instance Sizing and Layout
- Use identical hardware and MySQL versions across nodes.
- Keep latency between nodes as low as possible; Group Replication is sensitive to network delays.
- Use three or more members for production; avoid even numbers when possible to simplify quorum behaviour.
Backups
- Take logical or physical backups from a non-primary node to reduce impact on the primary.
- Ensure GTID-consistent backups so they can be used to seed new members if needed.
- Regularly test backup restore procedures independently of the cluster.
Monitoring
- Monitor
cluster.status()output regularly via automation. - Track replication lag, network latency, and InnoDB metrics (buffer pool hit rate, log waits).
- Alert on member state changes (ONLINE, UNREACHABLE, OFFLINE).
Common Pitfalls
- Mixed storage engines: InnoDB Cluster relies on InnoDB; avoid MyISAM or other non-transactional engines for replicated data.
- Non-deterministic SQL: Statements must be deterministic with row-based replication; avoid relying on non-deterministic functions without care.
- Split-brain risk: Ensure proper network design and avoid manual interventions that could create multiple primaries.
- Ignoring error logs: Group Replication issues often surface in the MySQL error log; integrate them into your logging stack.
This article offers general technical guidance. Validate all configurations in a safe environment before applying them to production.
With these steps and practices, you can build a reliable MySQL InnoDB Cluster from scratch, then iterate on monitoring, backups, and automation to reach production-grade high availability.


Leave a Reply