MySQL InnoDB Cluster: High Availability Setup Guide
Learn to set up MySQL InnoDB Cluster for high availability.
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
- ✓Basic knowledge of MySQL administration (starting/stopping, configuration files).
- ✓Familiarity with SQL and database concepts.
- ✓Three or more MySQL 8.0+ instances (physical or virtual).
- ✓MySQL Shell installed on an admin machine.
- ✓Network connectivity between nodes on ports 3306 and 33061.
- InnoDB Cluster provides automatic failover and high availability for MySQL.
- It uses Group Replication for data consistency across nodes.
- Setup involves configuring instances, creating a cluster, and adding nodes.
- MySQL Router provides transparent client routing.
- Monitor with performance_schema and cluster status commands.
Think of InnoDB Cluster as a team of synchronized dancers. Each dancer (MySQL instance) knows the exact same moves (data). If one dancer stumbles (node fails), the others seamlessly continue the performance without missing a beat. The audience (your application) doesn't even notice the change because the show goes on.
Imagine your e-commerce platform is experiencing a surge in traffic during a flash sale. Suddenly, your primary database server crashes. Without high availability, your site goes down, orders are lost, and customers are furious. This is where MySQL InnoDB Cluster comes to the rescue. It's a built-in solution that provides automatic failover, ensuring your database remains accessible even when individual nodes fail. InnoDB Cluster combines Group Replication for data consistency, MySQL Shell for management, and MySQL Router for client routing. In this tutorial, you'll learn how to set up a three-node InnoDB Cluster from scratch, configure MySQL Router, and handle real-world scenarios like node failures and recovery. By the end, you'll have a production-ready high-availability setup that keeps your applications running smoothly.
Prerequisites and Environment Setup
Before setting up InnoDB Cluster, ensure you have three MySQL 8.0+ instances (physical or virtual machines) with clean installations. Each instance should have a unique server_id and be able to communicate over ports 3306 (MySQL) and 33061 (Group Replication). Install MySQL Shell on your admin machine. For this tutorial, we'll use three nodes: node1 (192.168.1.10), node2 (192.168.1.11), node3 (192.168.1.12). Configure each MySQL instance with the following minimal settings in my.cnf:
[mysqld] server_id=1 # unique per node gtid_mode=ON enforce_gtid_consistency=ON binlog_format=ROW log_bin=mysql-bin log_slave_updates=ON relay_log=relay-log
Also ensure that group_replication is enabled:
group_replication=ON group_replication_start_on_boot=OFF group_replication_group_name='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' group_replication_local_address='192.168.1.10:33061' group_replication_group_seeds='192.168.1.10:33061,192.168.1.11:33061,192.168.1.12:33061'
Restart MySQL after changes.
Creating the InnoDB Cluster
Once the instances are configured, use MySQL Shell to create the cluster. Connect to the first node (node1) using MySQL Shell:
mysqlsh --uri root@192.168.1.10:3306
Then, create the cluster:
var cluster = dba.createCluster('myCluster');
This command configures Group Replication on node1 and bootstraps the cluster. After creation, check the status:
cluster.status();
You should see node1 as the PRIMARY (read-write) and the cluster is ONLINE. Now add the other nodes:
cluster.addInstance('root@192.168.1.11:3306'); cluster.addInstance('root@192.168.1.12:3306');
Each addition will prompt for the root password and then synchronize the data from the primary. After adding all nodes, the cluster.status() should show all three nodes as ONLINE with one PRIMARY and two SECONDARIES.
cluster.status().Configuring MySQL Router
MySQL Router provides transparent client-side routing. Install MySQL Router on a separate machine (or on the application server). Configure it to connect to the cluster:
mysqlrouter --bootstrap root@192.168.1.10:3306 --user=mysqlrouter
This command discovers the cluster and creates configuration files. The default configuration creates two ports: 6446 (read-write, routed to primary) and 6447 (read-only, load-balanced across secondaries). Start the router:
systemctl start mysqlrouter
Now applications can connect to port 6446 for writes and 6447 for reads. If the primary fails, Router automatically routes to the new primary. Test the connection:
mysql -h 127.0.0.1 -P 6446 -u appuser -p
You can also verify routing with:
mysqlrouter --list-routes
Testing Failover and Recovery
Simulate a primary failure to verify automatic failover. First, identify the primary:
mysqlsh -- cluster.status()
Then, stop MySQL on the primary (node1):
sudo systemctl stop mysql
After a few seconds, check cluster status again. You should see that one of the secondaries (e.g., node2) has become the new primary. The cluster status will show 'OK' with a new primary. Applications connected via Router will experience a brief interruption (usually a few seconds) but will automatically reconnect. To recover the failed node, start MySQL on node1 and rejoin it to the cluster:
sudo systemctl start mysql mysqlsh -- cluster.rejoinInstance('root@192.168.1.10:3306')
After rejoining, node1 will become a secondary. Verify with cluster.status().
Monitoring and Maintenance
Monitor cluster health using MySQL Shell and performance_schema. Key commands:
- cluster.status(): Overall cluster health.
- cluster.describe(): Configuration details.
- SELECT * FROM performance_schema.replication_group_members: Member states.
- SELECT * FROM performance_schema.replication_group_member_stats: Transaction stats.
Set up alerts for member state changes and replication lag. Use MySQL Enterprise Monitor or open-source tools like Prometheus with mysqld_exporter. Regular maintenance includes: - Upgrading MySQL versions: Use cluster rolling upgrade procedure. - Adding/removing nodes: Use cluster.addInstance() and cluster.removeInstance(). - Backup: Use mysqldump or MySQL Enterprise Backup. Remember that backups should be taken from a secondary to avoid load on primary.
Scaling and Advanced Configuration
InnoDB Cluster supports scaling out by adding more secondary nodes for read scalability. However, adding too many nodes can increase replication lag. For write scaling, consider sharding with MySQL Cluster (NDB). Advanced configuration options include: - group_replication_flow_control_mode: Controls how aggressively to throttle writes to prevent lag. Set to 'QUOTA' for strict control. - group_replication_member_expel_timeout: Timeout for expelling unresponsive members. Increase to 30-60 seconds in production. - group_replication_autorejoin_tries: Number of automatic rejoin attempts.
You can also configure multi-primary mode (all nodes writable) but it requires conflict detection and is not recommended for most applications. To enable multi-primary:
var cluster = dba.createCluster('myCluster', {multiPrimary: true});
But be aware of potential conflicts and performance overhead.
The Black Friday Outage: A Replication Nightmare
- Always set group_replication_member_expel_timeout high enough to handle transient network issues.
- Use an odd number of nodes (at least 3) to avoid split-brain.
- Monitor cluster status with performance_schema and alerts.
- Test failover scenarios regularly in a staging environment.
- Document recovery procedures and train the team.
cluster.status(). Verify all nodes are ONLINE. Check MySQL Router logs for routing failures.mysqlsh -- cluster.checkInstanceState()SELECT * FROM performance_schema.replication_group_members;| File | Command / Code | Purpose |
|---|---|---|
| my.cnf | server_id=1 | Prerequisites and Environment Setup |
| create_cluster.js | mysqlsh --uri root@192.168.1.10:3306 | Creating the InnoDB Cluster |
| router_setup.sh | sudo apt-get install mysql-router | Configuring MySQL Router |
| failover_test.sh | sudo systemctl stop mysql | Testing Failover and Recovery |
| monitoring.sql | SELECT * FROM performance_schema.replication_group_members; | Monitoring and Maintenance |
| advanced_config.sql | SET GLOBAL group_replication_flow_control_mode = 'QUOTA'; | Scaling and Advanced Configuration |
Key takeaways
Common mistakes to avoid
4 patternsUsing an even number of nodes (e.g., 2).
Setting group_replication_member_expel_timeout too low (e.g., 5 seconds).
Not enabling GTID mode.
Using the same server_id on multiple nodes.
Interview Questions on This Topic
Explain how InnoDB Cluster handles automatic failover.
Frequently Asked Questions
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
That's MySQL & PostgreSQL. Mark it forged?
3 min read · try the examples if you haven't