High Availability

MySQL InnoDB Cluster Explained: Complete Guide to High Availability

Deploy and operate MySQL InnoDB Cluster 8.4 safely with AdminAPI, Group Replication, Router, tested failover, and recoverable outage procedures.

JusDB Team
Published March 22, 2022
Updated August 1, 2026
6 min read

MySQL InnoDB Cluster combines MySQL Group Replication, MySQL Shell AdminAPI, and MySQL Router. Group Replication maintains a replicated group; AdminAPI creates and operates it; Router discovers the topology and directs new application connections to an appropriate member. This guide targets MySQL 8.4 LTS and deliberately avoids commands removed from that release.

In short
  • Use AdminAPI to validate and configure instances instead of hand-assembling Group Replication settings.
  • Deploy an odd-sized group across independent failure domains. A three-member group can tolerate one member becoming unavailable while retaining a majority.
  • Bootstrap Router against the cluster metadata and make applications retry connections and complete transactions after a failover.
  • Test planned switchovers, member rejoin, backup restore, and complete-outage recovery before relying on the design.

What the cluster does—and does not do

In the usual single-primary mode, one member accepts writes and the other online members apply the replicated transaction stream. Group Replication certifies transactions and requires a majority of members for progress. MySQL supports at most nine members in one replication group; that is a hard limit, not a recommendation that every deployment needs nine servers.

Router uses InnoDB Cluster metadata to find the current primary and eligible read-only members. Existing client sessions are not transparently moved when a server fails. A broken TCP session fails, Router selects a destination for a new connection, and the application must reconnect and retry the whole transaction when it is safe to do so. Do not publish a fixed failover SLA from a laboratory test: detection, election, transaction recovery, Router refresh, DNS and client retry behavior all contribute.

Preflight checks

  • Use supported, mutually compatible MySQL Server, Shell, and Router versions.
  • Place members on separate hosts or failure domains with stable hostnames, reliable time synchronization, and low-latency private networking.
  • Restrict the MySQL, Group Replication, and Router ports to the systems that need them.
  • Keep credentials out of shell history and source control. Let MySQL Shell prompt, or use an approved secret mechanism.
  • Confirm that every member has a unique server identity and enough disk capacity for data, binary logs, relay work, and recovery.

Configure instances with AdminAPI

Run the check on every prospective member. The output identifies settings AdminAPI can change and settings that require a restart.

javascript
// MySQL Shell JavaScript mode; the connection prompts for credentials.
shell.connect('root@db1.example.internal:3306')
dba.checkInstanceConfiguration()

// Create a narrowly scoped cluster administrator account.
dba.configureInstance('root@db1.example.internal:3306', {
  clusterAdmin: 'icadmin@10.0.1.%',
  restart: true
})

Repeat the operation for each server and review the report rather than assuming every change needs a restart. Use a host pattern no broader than the management network. The cluster administrator needs the privileges AdminAPI documents; it should not be a general application account.

Create the cluster and add members

javascript
shell.connect('icadmin@db1.example.internal:3306')

const cluster = dba.createCluster('production', {
  exitStateAction: 'READ_ONLY',
  ipAllowlist: '10.0.1.0/24'
})

cluster.addInstance('icadmin@db2.example.internal:3306', {
  recoveryMethod: 'auto'
})
cluster.addInstance('icadmin@db3.example.internal:3306', {
  recoveryMethod: 'auto'
})

cluster.status({extended: 1})

recoveryMethod: 'auto' lets AdminAPI decide whether incremental state recovery is possible or provisioning is required. If you explicitly choose clone recovery, remember that it replaces the recipient instance's data. Only clone a server whose existing contents may be discarded, and verify the selected donor and network capacity first.

Do not advertise a member as ready merely because the command returned. Confirm that its status is online, its role is expected, and its replication queues are converging under normal write traffic.

Bootstrap MySQL Router

bash
sudo mysqlrouter --bootstrap icadmin@db1.example.internal:3306 --user=mysqlrouter --conf-use-gr-notifications

The bootstrap command prompts for a credential and writes metadata-backed routes. With the default bootstrap base port, classic-protocol read/write and read-only routes use ports 6446 and 6447; X Protocol routes use 6448 and 6449. A customized base port changes those values, so read the generated configuration instead of hard-coding assumptions.

Group Replication notifications can reduce dependence on metadata polling, but they require a working X Plugin connection. If notifications are unavailable, Router uses its configured metadata refresh behavior. Run at least two Router instances if Router availability matters, and place them behind a client-visible endpoint appropriate to your environment.

Planned primary changes

A planned switchover is the safest way to prove routing and client behavior. Choose a healthy, caught-up member, drain or pause risky work, then use AdminAPI:

javascript
const cluster = dba.getCluster('production')
cluster.setPrimaryInstance('icadmin@db2.example.internal:3306')
cluster.status({extended: 1})

Validate both a new read/write connection and the application's transaction retry path. A successful server election is not the same as a successful application recovery.

Rejoin and outage recovery

Automatic rejoin behavior is configurable. When a member remains outside the group, inspect its error log and cluster status before forcing anything. If its GTID history is compatible, AdminAPI can rejoin it:

javascript
cluster.rejoinInstance('icadmin@db3.example.internal:3306')
cluster.status({extended: 1})

For a complete cluster outage, start all recoverable members and connect MySQL Shell to the member that contains the GTID superset. Run a dry run first:

javascript
dba.rebootClusterFromCompleteOutage('production', {dryRun: true})
dba.rebootClusterFromCompleteOutage('production')
Protect committed history

Do not force a member with less-complete GTID history to become the recovery seed unless you have explicitly accepted the resulting transaction loss. Do not run RESET BINARY LOGS AND GTIDS on a live cluster to solve a join problem. In MySQL 8.4, the older RESET MASTER statement is removed; the replacement is destructive, deletes binary logs and GTID history, and is not supported while replicas are running.

Monitoring and operational tests

  • Track member state, role, view changes, replication queue growth, transaction conflicts, and member error logs.
  • Monitor Router process health, metadata connectivity, route connection errors, and application reconnect failures.
  • Alert on deviations from a measured workload baseline and user-facing latency SLOs rather than copying universal queue or timing thresholds.
  • Exercise one-member loss, planned switchover, Router loss, network isolation, member clone/rejoin, and full-outage recovery in a non-production environment.
  • Record recovery time and recovery point results from those tests; do not infer them from component defaults.

Backups remain mandatory

Replication copies logical mistakes and destructive writes. An InnoDB Cluster is not a backup. Use a supported consistent backup method, retain binary logs according to the recovery objective, verify encryption and access controls, and restore into an isolated environment regularly. A backup taken from a secondary can still consume I/O and increase apply lag, so schedule and observe it like any other production workload.

Official primary sources

Working with JusDB on MySQL high availability

JusDB helps teams review InnoDB Cluster topology, Router behavior, failure testing, backup recovery, and application reconnect paths without relying on untested failover promises.

Explore JusDB MySQL services →  |  Talk to a DBA

Share this article

JusDB Team

Official JusDB content team

Deeper Reading

Curated companion guides for readers who want to go deeper on this topic.