MySQL 8.0 to 8.4 LTS Upgrade Guide — 5-Part Series
- Part 1: Pre-Upgrade Preparation
- Part 2: Upgrade Testing
- Part 3: Upgrade Execution (You Are Here)
- Part 4: Rollback and Post-Upgrade Validation
- Part 5: Change Management, Troubleshooting, and Checklist
Three primary approaches exist for performing the MySQL 8.0 to 8.4 upgrade. Each has different trade-offs for downtime, rollback complexity, and hardware requirements. Use the decision flowchart below to choose the right one for your environment.
Choosing Your Upgrade Approach
| Approach | Downtime | Rollback | Hardware | Best For |
|---|---|---|---|---|
| Replication-Based | Minutes (cutover only) | Instant (redirect to 8.0) | Requires extra server | Production-critical, large datasets |
| Rolling Replica | Minutes per node | Un-upgraded source available | Uses existing replicas | Replicated topologies |
| In-Place | Hours (full duration) | Restore from backup (hours) | No extra hardware | Dev/QA, small datasets, budget-constrained |
Approach 1: Replication-Based Upgrade (Recommended)
The replication-based approach provides minimal downtime, a natural testing period, and a straightforward rollback path. It requires additional hardware.
Step-by-Step Procedure
Step 1: Install MySQL 8.4.8 on a new dedicated server.
Step 2: Configure the 8.4 server with cleaned-up my.cnf.
Step 3: Take a consistent backup from the MySQL 8.0 source:
# Using XtraBackup:
xtrabackup --backup --target-dir=/backup/for_84 --user=root --password=<pw>
# Or using mysqldump:
mysqldump --all-databases --single-transaction --routines --triggers \
--events --source-data=2 > backup_for_84.sql
Step 4: Restore the backup on the MySQL 8.4 server.
Step 5: Set up replication from 8.0 (source) to 8.4 (replica).
For GTID-based replication (recommended):
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '8.0_source_ip',
SOURCE_USER = 'repl_user',
SOURCE_PASSWORD = 'repl_password',
SOURCE_AUTO_POSITION = 1,
GET_SOURCE_PUBLIC_KEY = 1;
START REPLICA;
For binary log position-based replication:
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '8.0_source_ip',
SOURCE_USER = 'repl_user',
SOURCE_PASSWORD = 'repl_password',
SOURCE_LOG_FILE = 'binlog.000XXX',
SOURCE_LOG_POS = XXXXXXX,
GET_SOURCE_PUBLIC_KEY = 1;
START REPLICA;
Step 6: Monitor replication lag until Seconds_Behind_Source = 0.
Step 7: Run application validation tests against the 8.4 replica.
Step 8: Schedule maintenance window for cutover.
Step 9: During cutover:
- Set 8.0 source to read-only to drain writes gracefully:
SET GLOBAL read_only = 1;
SET GLOBAL super_read_only = 1;
- Verify 8.4 replica is fully caught up (
Seconds_Behind_Source = 0) - Stop replication on the 8.4 server:
STOP REPLICA; - Redirect application connections to the MySQL 8.4 server
- Verify application functionality with smoke tests
Estimated Time by Phase
| Phase | Estimated Hours |
|---|---|
| Install and configure MySQL 8.4 | 3-5 |
| Backup and restore from 8.0 to 8.4 | 5-15 (depends on data size) |
| Setup replication and sync | 2-4 |
| Monitoring and validation period | 8-24 |
| Cutover activity | 2-5 |
| Post-cutover monitoring | 4-8 |
Approach 2: In-Place Upgrade
The in-place upgrade replaces MySQL binaries on the same server. This requires less hardware but carries higher risk and longer downtime.
WARNING: In-place upgrades have NO easy rollback. If the upgrade fails, you must restore from backup, which for large datasets can take 10-20+ hours.
Step-by-Step Procedure
Step 1: Take full backup (both logical and physical) and verify restore works.
Step 2: Ensure binary log retention covers your rollback window:
SET GLOBAL binlog_expire_logs_seconds = 259200; -- 3 days
Step 3: Record the current binary log position and GTID state.
Step 4: Stop MySQL 8.0 cleanly:
SET GLOBAL innodb_fast_shutdown = 0; -- Clean shutdown (CRITICAL)
systemctl stop mysqld
Step 5: Back up the configuration file and data directory:
cp /etc/my.cnf /etc/my.cnf.bak_8037
# Option A: LVM snapshot (preferred for large datasets):
lvcreate --size 100G --snapshot --name mysql_snap /dev/vg0/mysql_data
# Option B: File copy (slower, requires disk space):
cp -a /var/lib/mysql /var/lib/mysql.bak_8037
Step 6: Remove MySQL 8.0 packages:
For Percona Server:
# RHEL/CentOS:
yum remove percona-server-server percona-server-client
# Debian/Ubuntu (use remove, NEVER purge):
apt-get remove percona-server-server percona-server-client
For Oracle MySQL:
# RHEL/CentOS:
yum remove mysql-community-server mysql-community-client
# Debian/Ubuntu (use remove, NEVER purge):
apt-get remove mysql-server mysql-client
CRITICAL: On Debian/Ubuntu, NEVER use apt-get purge instead of apt-get remove. Purge deletes configuration files AND can trigger data directory cleanup, destroying your data. Always use remove and verify /var/lib/mysql is intact before proceeding.
Step 7: Install MySQL 8.4 packages:
For Percona Server repo:
# RHEL/CentOS:
yum install percona-server-server percona-server-common percona-server-client
# Debian/Ubuntu:
apt install -y percona-server-server percona-server-common percona-server-client
dpkg -l |grep percona |grep '8.4'
For Oracle MySQL rpm:
# RHEL/CentOS:
sudo yum install mysql-community-{server,client,client-plugins,icu-data-files,common,libs}-*
rpm -qa | grep mysql
# Debian/Ubuntu:
sudo dpkg -i mysql-{common,community-client-plugins,community-client-core,community-client,client,community-server-core,community-server,server}_*.deb
Step 8: Update my.cnf: remove all deprecated parameters, set explicit defaults.
Step 9: Start MySQL 8.4 with the existing data directory:
systemctl start mysqld
Step 10: Review the error log for upgrade messages and any issues:
tail -500 /var/log/mysql/mysqld.log
The server automatically upgrades the data dictionary and system tables on first start.
CRITICAL: Always set innodb_fast_shutdown = 0 before stopping MySQL 8.0. Using innodb_fast_shutdown = 2 leaves redo logs in a crash-like state. MySQL 8.4 cannot safely process these logs and will refuse to start. Recovery requires a full restore from backup.
Want a DBA team to handle your upgrade?
A MySQL major version upgrade is high-stakes work. If you'd rather have experienced DBAs execute it while you focus on your applications, book a free assessment call.
Book Free Assessment →Approach 3: Rolling Replica Upgrade
For environments with an existing source-replica replication topology, upgrade replicas first, then failover. This combines the benefits of minimal downtime with no extra hardware requirement.
Procedure
- Upgrade Replica 1: Stop replication, perform in-place upgrade to 8.4 (per the In-Place procedure above), restart replication
- Monitor Replica 1 for stability, replication health, and query correctness (24-48 hours)
- Upgrade Replica 2 using the same procedure
- Once all replicas are on 8.4 and stable, perform a planned failover: promote an 8.4 replica as the new source
- Upgrade the old source (now demoted to replica) to 8.4
NOTE: During the rolling upgrade, the un-upgraded source remains your rollback point. If any upgraded replica shows issues, you can remove it from the pool and rebuild. Only after promoting an 8.4 replica to source is the rollback path more complex.
Configuration File Template for MySQL 8.4
Below is a recommended baseline my.cnf template, cleaned of all removed parameters and with explicit values for changed defaults. Adjust all values to match your hardware and workload.
[mysqld]
# ── Basic Settings ──
datadir = /var/lib/mysql
port = 3306
server-id = 1001
log-error = /var/log/mysql/mysqld.log
# ── InnoDB (set explicitly to avoid silent default changes) ──
innodb_adaptive_hash_index = OFF # 8.4 default; set ON only if benchmarks justify
innodb_flush_method = O_DIRECT # 8.4 default; use fsync for ZFS/NFS
innodb_io_capacity = 5000 # SSDs: 2000-5000, NVMe: 10000+, HDD: 200
innodb_log_buffer_size = 64M # 8.4 default; reduce if memory-constrained
innodb_page_cleaners = 4
# ── Binary Logging ──
binlog_expire_logs_seconds = 259200 # 3 days; set to cover rollback window
# ── Authentication ──
# Transitional: uncomment to temporarily allow legacy auth during migration
# mysql_native_password = ON
# ── REMOVED in 8.4 - DO NOT INCLUDE ──
# default_authentication_plugin (use authentication_policy)
# master_info_repository (always TABLE)
# relay_log_info_repository (always TABLE)
# binlog_transaction_dependency_tracking
# expire_logs_days (use binlog_expire_logs_seconds)
# avoid_temporal_upgrade
# show_old_temporals
Part 3 Quick Checklist
- Choose upgrade approach based on hardware and risk tolerance
- Take final pre-upgrade backup
- Execute upgrade using chosen approach
- Verify MySQL 8.4 starts and runs without errors
- Review error log for warnings
- Apply cleaned
my.cnfconfiguration template
Continue the Series
- ← Part 2: Upgrade Testing
- Part 3: Upgrade Execution (You Are Here)
- Part 4: Rollback and Post-Upgrade Validation →