DBAtlas · Database operations atlas

MySQL InnoDB Cluster (Group Replication) setup

Symptom

Goal: set up high availability with automatic failover for MySQL using InnoDB Cluster (Group Replication + MySQL Shell + MySQL Router).

1. Meet the prerequisites

InnoDB Cluster requires MySQL 8.0+, a unique server_id, GTID mode, and the InnoDB storage engine on every node. All instances must be reachable from each other over the network, and tables must have primary keys. Prepare a clusterAdmin user for administration.

MySQL

-- my.cnf on each instance:
-- server_id unique, gtid_mode=ON, enforce_gtid_consistency=ON
CREATE USER 'icadmin'@'%' IDENTIFIED BY 'secret';
GRANT ALL PRIVILEGES ON *.* TO 'icadmin'@'%' WITH GRANT OPTION;

2. Configure each instance with MySQL Shell

In mysqlsh, dba.configureInstance() makes each node suitable for Group Replication; it fixes missing parameters and asks for a restart if needed. Repeat on all nodes.

MySQL

-- mysqlsh:
dba.configureInstance('icadmin@node1:3306')
dba.configureInstance('icadmin@node2:3306')
dba.configureInstance('icadmin@node3:3306')

3. Create the cluster (seed node)

Connect to one node and start the cluster with dba.createCluster(); this node becomes the first primary. A cluster object is returned and used for subsequent additions.

MySQL

-- mysqlsh, while connected to node1:
var cluster = dba.createCluster('appCluster')

4. Add the other instances to the cluster

Add the secondary nodes with cluster.addInstance(). Choose clone (physical clone, fast for a new node) or incremental (via GTID) as recoveryMethod. At least 3 nodes provide an odd majority and automatic failover.

MySQL

-- mysqlsh:
cluster.addInstance('icadmin@node2:3306', {recoveryMethod: 'clone'})
cluster.addInstance('icadmin@node3:3306', {recoveryMethod: 'clone'})

5. Bootstrap MySQL Router

MySQL Router routes between the application and the cluster; it exposes read/write (6446) and read-only (6447) ports and redirects traffic automatically when the primary changes. Bootstrap generates the configuration from the cluster metadata.

MySQL

mysqlrouter --bootstrap icadmin@node1:3306 --user=mysqlrouter --directory /etc/mysqlrouter
# Then: mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf &

6. Check cluster status and verify failover

cluster.status() shows each node's role (R/W primary, R/O secondary) and state (ONLINE). clusterName and topology should be healthy. Test failover by shutting down the primary and observing the automatic election of a new primary.

MySQL

-- mysqlsh:
var cluster = dba.getCluster('appCluster')
cluster.status()
-- Members via SQL:
SELECT member_host, member_role, member_state FROM performance_schema.replication_group_members;
Open in DBAtlas →