NEWS Earn Money with Onidel Cloud! Affiliate Program Details - Check it out

How to Perform a Zero‑Downtime MySQL 8.0→8.4 LTS Upgrade on an Ubuntu 24.04 VPS with InnoDB Cluster (Group Replication), MySQL Router, Rolling Cutover/Failback, and TLS (2025 Tutorial)

Introduction

Upgrading MySQL from 8.0 to 8.4 LTS in production environments requires careful planning to maintain high availability and prevent data loss. With MySQL 8.4 LTS offering enhanced performance, security improvements, and long-term support, the upgrade provides significant benefits for production workloads.

This comprehensive tutorial demonstrates how to perform a zero-downtime MySQL upgrade using InnoDB Cluster’s Group Replication technology. We’ll implement a rolling upgrade strategy that maintains service availability throughout the entire process, complete with TLS encryption and proper failback procedures.

By the end of this guide, you’ll have successfully upgraded your MySQL cluster while maintaining continuous service availability and understanding the complete rollback process if needed.

Prerequisites

Before beginning this upgrade process, ensure you have the following requirements in place:

  • System Requirements: 3 Ubuntu 24.04 LTS VPS instances with minimum 4GB RAM and 2 vCPUs each
  • Existing Setup: Functional MySQL 8.0 InnoDB Cluster with Group Replication and MySQL Router
  • Storage Space: At least 50% free disk space for upgrade operations and backups
  • Network Access: SSH access to all cluster nodes and proper firewall configuration
  • Backup Strategy: Recent full backup using point-in-time recovery setup
  • Maintenance Window: While targeting zero-downtime, plan for a maintenance window as contingency

Important: Test this entire procedure in a staging environment that mirrors your production setup before executing on live systems.

Step 1: Pre-Upgrade Preparations and Health Checks

Begin by verifying your current cluster health and creating comprehensive backups:

# Check cluster status on primary node
mysql -u root -p
SELECT * FROM performance_schema.replication_group_members;

# Verify MySQL Router status
mysqlrouter --bootstrap mysqlx://clusteradmin@mysql1:3306 --dry-run

# Create full backup before upgrade
mysqlsh --uri clusteradmin@mysql1:3306
dba.createCluster('prodCluster')
util.dumpInstance('/backup/pre-upgrade-dump', {threads: 4})

Document current configuration settings and verify TLS certificates:

# Export current configuration
mysqld --print-defaults > /backup/mysql-config-pre-upgrade.txt

# Verify TLS status
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl_cipher';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'require_secure_transport';"

# Check binary log status
mysql -u root -p -e "SHOW BINARY LOGS;"
mysql -u root -p -e "SHOW VARIABLES LIKE 'gtid_mode';"

Step 2: MySQL 8.4 Package Preparation

Download and prepare MySQL 8.4 LTS packages on all nodes without installing them yet:

# Add MySQL 8.4 repository on all nodes
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb

# Update package cache
sudo apt update

# Download packages without installing
sudo apt download mysql-server mysql-client mysql-shell mysql-router

# Verify package versions
dpkg -I mysql-server*.deb | grep Version

Validate package integrity and prepare upgrade scripts:

# Create upgrade script
cat > /tmp/upgrade-node.sh << 'EOF'
#!/bin/bash
set -e

NODE_ID=$1
echo "Starting upgrade for node $NODE_ID"

# Stop MySQL Router first
sudo systemctl stop mysqlrouter

# Stop MySQL server
sudo systemctl stop mysql

# Upgrade packages
sudo apt install -y ./mysql-*.deb

# Start MySQL with upgrade mode
sudo systemctl start mysql

# Run mysql_upgrade
mysql_upgrade -u root -p

echo "Node $NODE_ID upgrade completed"
EOF

chmod +x /tmp/upgrade-node.sh

Step 3: Rolling Upgrade Execution

Execute the rolling upgrade starting with secondary nodes to maintain primary availability:

# Step 3a: Identify primary node
mysql -u root -p -e "SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;"

# Step 3b: Start with first secondary node (mysql2)
ssh mysql2

# Remove node from cluster temporarily
mysql -u root -p
mysqlsh --uri clusteradmin@localhost:3306
var cluster = dba.getCluster('prodCluster')
cluster.removeInstance('clusteradmin@mysql2:3306')

# Execute upgrade
/tmp/upgrade-node.sh mysql2

# Verify upgrade successful
mysql -u root -p -e "SELECT VERSION();"

# Rejoin cluster
mysqlsh --uri clusteradmin@mysql1:3306
var cluster = dba.getCluster('prodCluster')
cluster.addInstance('clusteradmin@mysql2:3306')

# Wait for sync
cluster.status()

Repeat the process for the second secondary node:

# Step 3c: Upgrade second secondary (mysql3)
ssh mysql3

# Same process as mysql2
mysqlsh --uri clusteradmin@mysql1:3306
var cluster = dba.getCluster('prodCluster')
cluster.removeInstance('clusteradmin@mysql3:3306')

/tmp/upgrade-node.sh mysql3

# Rejoin and verify
cluster.addInstance('clusteradmin@mysql3:3306')
cluster.status()

Step 4: Primary Node Upgrade with Failover

Perform controlled failover to upgrade the original primary:

# Step 4a: Perform controlled switchover
mysqlsh --uri clusteradmin@mysql1:3306
var cluster = dba.getCluster('prodCluster')

# Switch primary to upgraded node
cluster.setPrimaryInstance('clusteradmin@mysql2:3306')

# Wait for switchover completion
cluster.status()

# Step 4b: Upgrade original primary (mysql1)
ssh mysql1
cluster.removeInstance('clusteradmin@mysql1:3306')

/tmp/upgrade-node.sh mysql1

# Rejoin as secondary
cluster.addInstance('clusteradmin@mysql1:3306')

Update MySQL Router configuration to handle the topology changes:

# Update router bootstrap
mysqlrouter --bootstrap clusteradmin@mysql2:3306 --force

# Restart router with new config
sudo systemctl restart mysqlrouter

# Verify router status
mysqlrouter --help | grep version
curl http://localhost:8080/api/20190715/routes

Step 5: Post-Upgrade Validation

Thoroughly validate the upgraded cluster functionality:

# Verify all nodes are MySQL 8.4
for node in mysql1 mysql2 mysql3; do
  echo "Checking $node:"
  ssh $node "mysql -u root -p -e 'SELECT VERSION();'"
done

# Test cluster operations
mysql -u root -p
CREATE DATABASE upgrade_test;
USE upgrade_test;
CREATE TABLE test_table (id INT PRIMARY KEY, data VARCHAR(100));
INSERT INTO test_table VALUES (1, 'upgrade successful');

# Verify replication
SELECT * FROM test_table;

# Check from secondary nodes
ssh mysql2 "mysql -u root -p -e 'SELECT * FROM upgrade_test.test_table;'"
ssh mysql3 "mysql -u root -p -e 'SELECT * FROM upgrade_test.test_table;'"

Performance and configuration validation:

# Verify TLS still functional
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl_%';"

# Check Group Replication status
mysql -u root -p -e "SELECT * FROM performance_schema.replication_group_members;"

# Run performance baseline
mysqlslap --create-schema=test --query="SELECT * FROM upgrade_test.test_table" --concurrency=10 --iterations=100

Rollback Procedure (Emergency Only)

Warning: Only use this rollback procedure if critical issues are discovered immediately after upgrade and no new data has been written.

# Emergency rollback steps
# 1. Stop all applications
# 2. Restore from pre-upgrade backup
mysqlsh --uri clusteradmin@mysql1:3306
util.loadDump('/backup/pre-upgrade-dump')

# 3. Downgrade packages on each node
sudo apt install mysql-server=8.0.* mysql-client=8.0.*

# 4. Reconfigure cluster
dba.createCluster('prodCluster')
cluster.addInstance('mysql2:3306')
cluster.addInstance('mysql3:3306')

Best Practices

Follow these essential practices for production MySQL upgrades:

  • Testing Environment: Always test the complete procedure in a staging environment that mirrors production
  • Backup Strategy: Maintain multiple backup types including binary logs for point-in-time recovery
  • Monitoring: Implement comprehensive monitoring during the upgrade process to catch issues early
  • Documentation: Document all configuration changes and maintain an upgrade log
  • Rollback Planning: Prepare and test rollback procedures before starting the upgrade

For enhanced observability during upgrades, consider implementing a comprehensive monitoring stack that can track cluster health, replication lag, and application performance throughout the upgrade process.

Security Considerations:

  • Verify TLS certificates remain valid after upgrade
  • Review user privileges and authentication methods
  • Update firewall rules if MySQL 8.4 introduces new network requirements
  • Rotate passwords and certificates if required by security policies

Conclusion

You’ve successfully completed a zero-downtime MySQL upgrade from 8.0 to 8.4 LTS using InnoDB Cluster’s Group Replication technology. This rolling upgrade approach ensures continuous service availability while providing the enhanced performance and security features of MySQL 8.4 LTS.

The upgrade process covered critical aspects including proper backup procedures, controlled failover execution, comprehensive validation, and emergency rollback planning. Your MySQL cluster now benefits from improved performance, enhanced security features, and long-term support.

For organizations requiring high-performance database infrastructure with advanced features like automatic backups and TLS encryption, explore Onidel’s managed VPS solutions that provide the reliability and performance needed for demanding database workloads.

Share your love