MySQL 8.0 reaches end-of-life in April 2026. After that date, Oracle stops issuing security patches, bug fixes, and updates. If you're still running 8.0 after that point, you're running an unpatched database in production.
This guide gives you the actual technical information you need to plan and execute the upgrade to MySQL 8.4 LTS — what breaks, what's better, and how to do it safely in a maintenance window.
- MySQL 8.0.x → EOL April 2026. No more security patches after this date.
- MySQL 8.4 → LTS (Long-Term Support) with patches through 2032.
- MySQL 9.x → Innovation releases (not LTS; changes frequently, not for most production use).
- For most teams: upgrade path is 8.0 → 8.4 directly. In-place upgrade is supported.
What Actually Breaks in the 8.0 → 8.4 Upgrade
The MySQL team has kept 8.4 largely compatible with 8.0, but there are real breaking changes that will catch you off guard if you don't check for them.
1. mysql_native_password is disabled by default
This is the #1 cause of connection failures post-upgrade. MySQL 8.4 disables mysql_native_password by default. Any user account using it will fail to authenticate.
-- Before upgrading: check which accounts use mysql_native_password SELECT user, host, plugin FROM mysql.user WHERE plugin = 'mysql_native_password'; -- For each affected account, upgrade the authentication: ALTER USER 'appuser'@'%' IDENTIFIED WITH caching_sha2_password BY 'your_password'; ALTER USER 'readonly'@'10.0.1.%' IDENTIFIED WITH caching_sha2_password BY 'readonly_password'; FLUSH PRIVILEGES;
If your application client doesn't support caching_sha2_password, update it first. All modern drivers support it: MySQL Connector/Python 8.0+, mysql2 gem 0.5+, mysql2 Node.js 2.18+, JDBC Connector/J 8.0+.
If you absolutely cannot migrate a specific account, you can temporarily re-enable mysql_native_password in 8.4 (it'll be fully removed in MySQL 9.0):
# my.cnf — temporary workaround (plan to migrate off this) [mysqld] mysql_native_password=ON
2. Removed deprecated variables
Several variables that were deprecated in 8.0 are removed in 8.4. Running MySQL 8.4 with these in your config file will prevent startup:
-- Variables removed in MySQL 8.4: -- innodb_log_file_size (replaced by innodb_redo_log_capacity) -- innodb_log_files_in_group (folded into innodb_redo_log_capacity) -- slave_* variables (replaced by replica_* equivalents) -- query_cache_* variables (query cache removed in 8.0, now fully gone) -- Check your current config for these: SHOW VARIABLES LIKE 'innodb_log_file_size'; SHOW VARIABLES LIKE 'slave_parallel_workers'; -- Migration: -- OLD: innodb_log_file_size=1G + innodb_log_files_in_group=2 = 2GB total -- NEW: innodb_redo_log_capacity=2147483648 (same 2GB, one variable)
3. Replication: slave_ → replica_ variable rename
All slave_* replication variables have been renamed to replica_*. The old names still work in 8.0 but generate deprecation warnings. In 8.4, the old names are removed.
-- 8.0 syntax (deprecated): SET GLOBAL slave_parallel_workers = 4; SHOW SLAVE STATUS\G -- 8.4 syntax (required): SET GLOBAL replica_parallel_workers = 4; SHOW REPLICA STATUS\G -- Update your monitoring scripts, runbooks, and application code that -- reads SHOW SLAVE STATUS output before upgrading.
4. GTID behavior changes
MySQL 8.4 introduces Tagged GTIDs — a new GTID format that allows tagging transactions for multi-source replication. Existing GTID configurations work as-is, but if your monitoring or tooling parses GTID strings, check for the new format:
-- Traditional GTID format (still works): 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 -- New Tagged GTID format (8.4+): 3E11FA47-71CA-11E1-9E33-C80AA9429562:tag:1-5
5. Deprecation warnings to resolve before upgrading
-- Run the upgrade checker before you upgrade
-- This is the most important pre-upgrade step
mysqlsh --host=localhost --user=root \
--execute="util.checkForServerUpgrade('root@localhost', {targetVersion: '8.4.0'})"
-- Or from within mysqlsh:
JS> util.checkForServerUpgrade()
The upgrade checker scans your current configuration and schema for everything that will break. Run it on a copy of production first — fix every WARNING before you touch production.
What's Actually Better in MySQL 8.4
InnoDB parallel DDL — significantly faster index creation
-- MySQL 8.4 default: parallel DDL threads match CPU core count -- You can tune it: SET innodb_ddl_threads = 8; -- threads for DDL operations SET innodb_parallel_read_threads = 8; -- threads for parallel index reads SET innodb_ddl_buffer_size = 1073741824; -- 1GB DDL buffer -- On a large table (500M rows), adding an index: -- MySQL 8.0: ~45 minutes -- MySQL 8.4 with 8 DDL threads: ~12 minutes ALTER TABLE events ADD INDEX idx_user_date (user_id, created_at);
Automatic histogram statistics
In 8.0, histograms required manual ANALYZE TABLE ... UPDATE HISTOGRAM ON column calls. In 8.4, histograms update automatically when InnoDB detects significant data changes, reducing optimizer estimation errors without manual DBA intervention.
-- Configure auto-histogram memory budget
SET GLOBAL histogram_generation_max_mem_size = 20971520; -- 20MB
-- Check histogram state on a column
SELECT schema_name, table_name, column_name, last_updated, histogram
FROM information_schema.column_statistics
WHERE schema_name = 'myapp'
ORDER BY last_updated DESC;Redo log capacity — single variable replaces two
-- MySQL 8.0 (two variables):
innodb_log_file_size=1073741824 -- 1GB per file
innodb_log_files_in_group=2 -- 2 files = 2GB total
-- MySQL 8.4 (one variable):
innodb_redo_log_capacity=2147483648 -- 2GB total, dynamically adjustable
-- You can now resize the redo log without a restart:
SET PERSIST innodb_redo_log_capacity = 4294967296; -- resize to 4GB liveInnoDB Cluster improvements
- Rolling upgrades: You can upgrade cluster members one at a time without taking the whole cluster offline — the cluster stays available throughout the upgrade
- Group Replication improvements: Better handling of network partitions and split-brain scenarios
- MySQL Router 8.4: Improved connection routing with better failover detection times
The Upgrade Process: Step by Step
For standalone MySQL instances
# Step 1: Full backup before anything else
mysqldump --all-databases --single-transaction --master-data=2 \
--routines --events --triggers > full_backup_$(date +%Y%m%d).sql
# Or with MySQL Shell (much faster for large databases):
mysqlsh
JS> util.dumpInstance("/backup/pre-upgrade/", {threads: 8})
# Step 2: Run the upgrade checker
mysqlsh
JS> util.checkForServerUpgrade()
# Step 3: Fix every issue reported by the checker
# Step 4: On RHEL/CentOS — upgrade the package
sudo yum install mysql-community-server-8.4.x
# On Ubuntu/Debian:
sudo apt-get install mysql-server=8.4.x
# Step 5: Start MySQL 8.4 — it runs mysql_upgrade automatically
sudo systemctl start mysqld
# Step 6: Verify upgrade succeeded
mysql -u root -p -e "SELECT VERSION();"
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_redo_log_capacity';"
# Step 7: Validate your application connections work
mysql -u appuser -p myapp -e "SELECT 1;"For RDS MySQL 8.0 → 8.4
AWS supports in-place major version upgrades for RDS MySQL. The process is significantly simpler than self-managed upgrades but has the same breaking change risks:
# Using AWS CLI:
aws rds modify-db-instance \
--db-instance-identifier your-db-identifier \
--engine-version 8.4.3 \
--allow-major-version-upgrade \
--apply-immediately # or omit for next maintenance window
# Or via Terraform:
resource "aws_db_instance" "mysql" {
engine_version = "8.4.3"
allow_major_version_upgrade = true
# ...
}Before running this on production, test on a snapshot:
# Restore prod snapshot → test instance, then upgrade the test instance
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier mysql-upgrade-test \
--db-snapshot-identifier your-latest-snapshot
# Upgrade the test instance
aws rds modify-db-instance \
--db-instance-identifier mysql-upgrade-test \
--engine-version 8.4.3 \
--allow-major-version-upgrade \
--apply-immediately
# Run your application test suite against mysql-upgrade-test
# Fix any issues, then repeat on productionFor MySQL InnoDB Cluster (rolling upgrade)
# Connect to MySQL Shell with cluster admin
mysqlsh clusteradmin@primary-host:3306
# Get cluster status
JS> var cluster = dba.getCluster()
JS> cluster.status()
# Upgrade secondary members first (one at a time)
# MySQL 8.4 members can coexist with 8.0 members during rolling upgrade
# On each secondary (in order):
# 1. Remove from cluster temporarily
JS> cluster.removeInstance('secondary-host:3306')
# 2. Upgrade the instance
# [upgrade the MySQL binary on that host]
# 3. Re-add to cluster
JS> cluster.addInstance('clusteradmin@secondary-host:3306')
# 4. Wait for sync to catch up before moving to next member
JS> cluster.status() -- check "Transactions Set" lag
# 5. Finally, do a planned failover to upgrade the primary
JS> cluster.setPrimaryInstance('upgraded-secondary-host:3306')
# Then upgrade the old primary using the same processPost-Upgrade Validation Checklist
-- 1. Confirm version
SELECT VERSION();
-- 2. Check all user accounts are working
SELECT user, host, plugin, account_locked FROM mysql.user ORDER BY user;
-- 3. Verify replication is healthy (if applicable)
SHOW REPLICA STATUS\G -- check Seconds_Behind_Source = 0, no errors
-- 4. Check InnoDB engine status for any errors
SHOW ENGINE INNODB STATUS\G
-- 5. Validate the buffer pool is warming up
SELECT
FORMAT_BYTES(@@innodb_buffer_pool_size) AS configured,
FORMAT(variable_value * 100.0 /
(SELECT variable_value FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_total'), 2) AS pct_used
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_data';
-- 6. Check slow query log is still enabled and pointing to right file
SHOW VARIABLES LIKE 'slow_query_log%';
-- 7. Run your application smoke tests
-- 8. Monitor error log for 24 hours: /var/log/mysql/error.logRollback Plan
MySQL does not support downgrade (8.4 data files cannot be read by 8.0). Your rollback option is a restore from pre-upgrade backup. This means:
- Your backup must be taken immediately before the upgrade, not days before
- You need to measure how much data change occurs during the upgrade window to understand RPO
- For zero-data-loss rollback on RDS: use a blue-green deployment (AWS RDS Blue/Green Deployments feature) — keep the 8.0 instance running until you're confident in 8.4
# RDS Blue/Green Deployment (zero data loss rollback option)
aws rds create-blue-green-deployment \
--blue-green-deployment-name mysql-84-upgrade \
--source your-prod-db-arn \
--target-engine-version 8.4.3
# Test against the green (8.4) instance
# When confident: switchover (30-60 second cutover, data replicated)
aws rds switchover-blue-green-deployment \
--blue-green-deployment-identifier bgd-xxxxx
# If issues arise after switchover, the old blue (8.0) instance is retained
# for a configurable period — you can switch backPlanning Your Upgrade Timeline
With MySQL 8.0 EOL in April 2026, here's a realistic timeline for most organizations:
| Phase | Activity | Suggested Timing |
|---|---|---|
| Assessment | Run upgrade checker, identify breaking changes, inventory all MySQL instances | Now (if not done) |
| Dev/Test upgrade | Upgrade non-production environments, run full test suite, fix breaking changes | Q1 2025 or earlier |
| Staging upgrade | Load test staging on 8.4, validate performance matches or exceeds 8.0 | Q2 2025 |
| Production upgrade | Upgrade production with rollback plan, monitor 2 weeks post-upgrade | Q3 2025 (before any year-end freeze) |
| Buffer | Time for remediation if issues arise | Q4 2025 – Q1 2026 |
The organizations that get into trouble are the ones that schedule the upgrade for March 2026 and discover a breaking change with their ORM or driver compatibility in February.
Working with JusDB on Your 8.0 → 8.4 Upgrade
We've run MySQL major version upgrades across hundreds of production instances — from single RDS databases to multi-region InnoDB Clusters. The process is repeatable and low-risk when you follow the right sequence. The risk comes from skipping the pre-upgrade assessment or underestimating application-level breaking changes.
Our database upgrade service includes:
- Automated upgrade checker run against your current instances
- Application driver and ORM compatibility audit
- Upgrade execution with rollback procedures defined before we start
- Post-upgrade performance validation and monitoring for 2 weeks
If you have multiple MySQL instances to upgrade, or your upgrade involves InnoDB Cluster, or you can't afford more than 5 minutes of downtime, talk to us about planning it together.
Related reading: MySQL Performance Tuning Guide | MySQL 8.4 LTS New Features | MySQL InnoDB Cluster Guide