How to Set up MySQL Database Cluster

How to Set up MySQL Database Cluster

The first time I had to explain to a client why their single MySQL server going down took their entire application offline, I didn’t have a good answer. That conversation is what pushed me to actually learn clustering properly instead of treating it as a “nice to have.” A cluster isn’t just about handling more traffic — it’s about making sure one server dying at 3 AM doesn’t become a business emergency.

This article walks through the real options for MySQL clustering, how they work internally, and how to actually set one up.

What “Cluster” Means in MySQL

People use “cluster” loosely, so let’s be precise. In the MySQL world there are a few distinct approaches:

ApproachDescriptionConsistency Model
MySQL Replication (async/semi-sync)One primary, one or more replicas copying data via binlogEventual (async) or near-real-time (semi-sync)
Group ReplicationMultiple nodes agree on transactions via a consensus protocolVirtually synchronous
InnoDB ClusterGroup Replication + MySQL Router + MySQL Shell, packaged togetherVirtually synchronous, managed
NDB Cluster (MySQL Cluster)Separate storage engine (NDB) built for distributed, in-memory, synchronous clusteringSynchronous, shared-nothing

For most teams building a highly available web application, InnoDB Cluster is the modern, officially recommended path, so I’ll focus there, with replication as the foundational concept underneath it.

Architecture Overview

graph TD
    A[Application] --> B[MySQL Router]
    B --> C[Primary Node - Read/Write]
    B --> D[Secondary Node 1 - Read Only]
    B --> E[Secondary Node 2 - Read Only]
    C <--> D
    C <--> E
    D <--> E
    F[Group Replication Consensus Layer] --- C
    F --- D
    F --- E

MySQL Router sits between your application and the cluster, automatically directing writes to the current primary and optionally distributing reads across secondaries. Under the hood, Group Replication uses a Paxos-based protocol to make sure a transaction is only committed once a majority of nodes agree — this is what gives InnoDB Cluster automatic failover with data consistency guarantees, unlike plain async replication.

Prerequisites

Step 1: Configure Each Node

On every server (node1, node2, node3), set these in my.cnf:

[mysqld]
server_id = 1                 # unique per node: 1, 2, 3
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_checksum = NONE
log_bin = binlog
log_slave_updates = ON
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "node1:33061"
loose-group_replication_group_seeds = "node1:33061,node2:33061,node3:33061"
loose-group_replication_bootstrap_group = OFF

Restart MySQL after applying this configuration.

Step 2: Create a Replication User

On each node:

SET SQL_LOG_BIN=0;
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'StrongPassword123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
GRANT BACKUP_ADMIN ON *.* TO 'repl_user'@'%';
SET SQL_LOG_BIN=1;

Step 3: Bootstrap the Cluster Using MySQL Shell

From your admin machine:

mysqlsh
\connect root@node1:3306
dba.configureInstance('root@node1:3306')
dba.configureInstance('root@node2:3306')
dba.configureInstance('root@node3:3306')

var cluster = dba.createCluster('productionCluster')
cluster.addInstance('root@node2:3306')
cluster.addInstance('root@node3:3306')

dba.configureInstance automatically validates and fixes configuration issues per node — it’s one of the most useful parts of the tooling because manual Group Replication setup used to be extremely error-prone.

Step 4: Verify Cluster Status

cluster.status()

Sample output:

{
    "clusterName": "productionCluster",
    "defaultReplicaSet": {
        "status": "OK",
        "topology": {
            "node1:3306": { "status": "ONLINE", "role": "PRIMARY" },
            "node2:3306": { "status": "ONLINE", "role": "SECONDARY" },
            "node3:3306": { "status": "ONLINE", "role": "SECONDARY" }
        }
    }
}

"status": "OK" means the cluster has quorum and is healthy.

Step 5: Deploy MySQL Router

MySQL Router is what your application actually connects to — it hides the cluster topology entirely.

mysqlrouter --bootstrap root@node1:3306 --user=mysqlrouter
mysqlrouter &

By default, Router exposes:

Your application’s connection string simply points at the Router host and port instead of a specific database server.

Failover Behavior

If the primary node fails, Group Replication’s consensus protocol detects the loss of quorum communication and automatically elects a new primary from the healthy secondaries — typically within a few seconds. MySQL Router detects the new primary and reroutes write traffic without application changes. This is the core value proposition over manual replication, where failover historically required a script or human intervention.

Transactions and Consistency

By default, Group Replication runs in single-primary mode, where all writes go to one node and secondaries stay read-only, which avoids conflict resolution complexity. It can also run in multi-primary mode, allowing writes to any node, but this requires careful application design to avoid write conflicts, since conflicting transactions are detected and one is rolled back.

-- Check current mode
SELECT * FROM performance_schema.global_variables 
WHERE variable_name = 'group_replication_single_primary_mode';

Monitoring the Cluster

SELECT MEMBER_HOST, MEMBER_STATE, MEMBER_ROLE 
FROM performance_schema.replication_group_members;
+-----------+--------------+-------------+
| MEMBER_HOST | MEMBER_STATE | MEMBER_ROLE |
+-----------+--------------+-------------+
| node1     | ONLINE       | PRIMARY     |
| node2     | ONLINE       | SECONDARY   |
| node3     | ONLINE       | SECONDARY   |
+-----------+--------------+-------------+

Also worth tracking: replication lag, applier queue length, and conflict/rollback counts, all exposed through performance_schema tables.

Real-World Scenario: Rolling Maintenance

One workflow I rely on constantly: patching OS-level packages on cluster nodes without downtime. I take one secondary out, patch it, bring it back and let it catch up via Group Replication, then repeat for the next node, and finally do a planned switchover of the primary role before patching the original primary. Applications never notice, because Router keeps routing to whichever node is currently primary.

cluster.setPrimaryInstance('root@node2:3306')  // planned switchover

Backup Strategy for a Cluster

Backups should generally run against a secondary to avoid load on the primary:

mysqldump --single-transaction --routines --triggers -h node2 -u backup_user -p mydb > backup.sql

For larger datasets, mysqlbackup or Percona XtraBackup with --galera-info-style consistency options are more appropriate than logical dumps.

Security Considerations

Troubleshooting Common Issues

Cluster shows “status”: “OK_NO_TOLERANCE”. This means the cluster is healthy but can’t tolerate another node failure without losing quorum — usually seen right after a node drops out. Get the missing node back online quickly.

A node stuck in “RECOVERING”. Usually a binlog or GTID mismatch. Check SHOW REPLICA STATUS equivalents in performance_schema.replication_applier_status_by_worker for the specific error.

Split-brain concerns. Group Replication’s consensus protocol is specifically designed to prevent split-brain by requiring majority agreement — this is why an odd number of nodes (3, 5, 7) is required; a tie can’t happen.

Frequently Asked Questions

How many nodes do I need minimum? Three, to tolerate a single node failure while maintaining quorum.

Does clustering replace backups? No. Clustering protects against node failure, not against accidental deletion, corruption, or application-level bugs that get replicated everywhere. You still need point-in-time backups.

Can I mix InnoDB Cluster with read replicas outside the cluster? Yes — you can attach additional asynchronous replicas to a cluster’s primary for extra read scaling or disaster recovery in another region.

Is NDB Cluster better than InnoDB Cluster? NDB Cluster offers synchronous, in-memory, shared-nothing architecture suited for telecom-grade workloads with extreme availability needs, but it has different SQL feature support and operational complexity. Most standard web applications are better served by InnoDB Cluster.

Interview Questions

  1. What’s the difference between asynchronous replication, semi-synchronous replication, and Group Replication?
  2. How does Group Replication achieve consensus, and why does it require an odd number of nodes?
  3. What role does MySQL Router play in a clustered deployment?
  4. Explain the difference between single-primary and multi-primary Group Replication modes.
  5. How does automatic failover work in an InnoDB Cluster, and what happens to in-flight transactions on the failed primary?
  6. Why should backups typically run against a secondary node rather than the primary?

Summary and Key Takeaways

Setting up a cluster the first time takes patience, but once it’s running, the peace of mind is worth every hour spent configuring it correctly.

References

Exit mobile version