MySQL 8.0 to 8.4 LTS Upgrade Guide — 5-Part Series
- Part 1: Pre-Upgrade Preparation (You Are Here)
- Part 2: Upgrade Testing
- Part 3: Upgrade Execution
- Part 4: Rollback and Post-Upgrade Validation
- Part 5: Change Management, Troubleshooting, and Checklist
MySQL 8.0 reached End of Life (EOL) on April 6, 2026. After that date, Oracle no longer provides standard support, security updates, or bug fixes. Upgrading to MySQL 8.4 LTS ensures continued long-term support, security patches, and access to performance improvements.
CRITICAL: This is a MAJOR version upgrade, not a minor patch. MySQL 8.0 to 8.4 introduces breaking changes in authentication, SQL syntax, configuration parameters, and data type handling. Thorough testing is mandatory.
This guide is intended for Database Administrators (DBAs) performing the upgrade on self-managed MySQL or Percona Server installations. It covers both Oracle MySQL Community/Enterprise and Percona Server for MySQL. Where package commands differ between the two, both variants are shown explicitly.
Key Differences: MySQL 8.0 vs 8.4 LTS
Before starting any upgrade work, understand the scope of what's changing. The following table summarizes the most impactful differences between MySQL 8.0 and 8.4 LTS.
| Area | Change in MySQL 8.4 | Impact |
|---|---|---|
| Authentication | mysql_native_password plugin removed | All users must use caching_sha2_password or other supported plugins |
| AUTO_INCREMENT | No longer supported on FLOAT/DOUBLE columns | Tables using float/double AUTO_INCREMENT must be altered |
| Foreign Keys | Stricter foreign key validation | Existing FK definitions may fail validation checks |
| Reserved Keywords | New reserved keywords (e.g., MANUAL, QUALIFY, INTERSECT) | Tables/columns using new keywords need backtick quoting |
| SQL Terminology | MASTER/SLAVE commands fully removed | Must use SOURCE/REPLICA; old syntax will ERROR, not just warn |
| Removed Parameters | default_authentication_plugin, master_info_repository, relay_log_info_repository, binlog_transaction_dependency_tracking, plus others | Must remove from my.cnf or server will refuse to start |
| Default Values | innodb_adaptive_hash_index, innodb_flush_method, innodb_io_capacity, innodb_log_buffer_size | Behavior changes silently if not explicitly set |
| sql_mode | Stricter defaults for SQL mode enforcement | Queries valid in 8.0 may fail or return different results in 8.4 |
| GROUP BY | Implicit sorting by GROUP BY fully removed | Queries relying on GROUP BY sort order must add explicit ORDER BY |
Backup Strategy
Pre-upgrade preparation is the most critical phase. A well-prepared upgrade dramatically reduces risk and downtime. It all starts with backups.
BEST PRACTICE: Always take BOTH a logical backup AND a physical backup before any upgrade activity. Test your restore procedure on a separate server before proceeding.
A reliable, tested backup is your only safety net. Without it, a failed upgrade could result in catastrophic, unrecoverable data loss.
Logical Backup Options
- mysqldump: Full logical dump including routines, triggers, and events
- mydumper / myloader: Multi-threaded logical backup and restore for large datasets
- MySQL Shell Dump Utility (
util.dumpInstance): Modern parallel dump with compression
Physical Backup Options
- Percona XtraBackup: Hot, non-blocking backup for InnoDB (use version matching your MySQL)
- LVM Snapshots: Instant filesystem-level snapshot (requires clean InnoDB shutdown or flush with lock)
- File system copy (tar/gzip): Cold backup after clean shutdown with
innodb_fast_shutdown=0
Sample mysqldump Command
mysqldump -u root -p --all-databases --single-transaction --routines \
--triggers --events --set-gtid-purged=OFF > full_backup_pre_upgrade.sql
Sample XtraBackup Commands
xtrabackup --backup --target-dir=/backup/full_pre_upgrade \
--user=root --password=<password>
xtrabackup --prepare --target-dir=/backup/full_pre_upgrade
WARNING: Always verify your backup by performing a test restore on a separate server BEFORE beginning the upgrade. An untested backup is not a backup.
Disk Space Planning
A major version upgrade requires significant free disk space. Plan for the following:
| Item | Space Required | Notes |
|---|---|---|
| Logical backup (mysqldump) | 1x database size (uncompressed) | Compressed: ~30-50% of raw size |
| Physical backup (XtraBackup) | 1x database size + redo logs | Stores raw InnoDB data files |
| Data directory copy (in-place upgrade) | 1x datadir size | cp -a /var/lib/mysql for safety copy |
| Temporary upgrade space | 10-20% of datadir | InnoDB DD upgrade, redo log rebuild |
| Binary log retention | Varies | Ensure binlog_expire_logs_seconds covers rollback window |
BEST PRACTICE: As a rule of thumb, ensure at least 2.5x your current datadir size is available as free disk space before starting the upgrade. For a 1TB database, plan for at least 2.5TB free.
Table Integrity Check
Identify and repair any corrupted tables before upgrading. Upgrading with corrupted data can cause the new version to fail to start or cause silent data corruption.
Run Table Checks
mysqlcheck -u root -p --all-databases --check
Auto-Repair Corrupted Tables (only after confirming backup)
mysqlcheck -u root -p --all-databases --auto-repair
Check for Orphaned Tablespace Files
-- Check for orphaned tablespace files:
SELECT * FROM information_schema.INNODB_TABLESPACES
WHERE NAME NOT IN (SELECT CONCAT(TABLE_SCHEMA,'/',TABLE_NAME)
FROM information_schema.TABLES WHERE ENGINE='InnoDB');
WARNING: Large table repairs can be extremely time-consuming and lock the table. Schedule repairs during a maintenance window.
MySQL Shell Upgrade Checker Utility
The MySQL Shell Upgrade Checker is the single most important pre-upgrade tool. It analyzes your current instance against 24+ compatibility metrics and reports errors, warnings, and notices.
Run the Upgrade Checker (targeting 8.4.8)
mysqlsh -- util checkForServerUpgrade root@localhost:3306 \
--target-version=8.4.8 \
--config-path=/etc/mysql/mysql.conf.d/mysqld.cnf
Alternative JavaScript Syntax within MySQL Shell
util.checkForServerUpgrade("root@localhost:3306",
{targetVersion: "8.4.8",
configPath: "/etc/mysql/mysql.conf.d/mysqld.cnf"})
The Upgrade Checker examines:
- Usage of removed or deprecated system variables
- Usage of new reserved keywords as identifiers (table/column names)
- Deprecated
utf8(utf8mb3) character set usage - Tables with temporal columns in pre-5.6.4 format
- Partitioned tables with unsupported engines
- Foreign key constraint naming conflicts
- Column definitions exceeding maximum lengths
- Zero date/datetime values (
0000-00-00) violating strict mode - Authentication plugin compatibility
- Orphan data dictionary entries and inconsistencies
CRITICAL: All ERRORS reported by the Upgrade Checker MUST be resolved before proceeding. Warnings should also be addressed. Ignoring these will lead to failed upgrades or production outages.
NOTE: If you encounter a "No database selected" error, include the database in the connection string: mysqlsh user@localhost:3306/mysql -- util check-for-server-upgrade
Removed and Changed Configuration Parameters
MySQL 8.4 removes several parameters that were deprecated in 8.0. If any of these remain in your my.cnf, the server will refuse to start.
Parameters Removed in MySQL 8.4 (must remove from my.cnf)
| Parameter | Action Required |
|---|---|
default_authentication_plugin | Remove. Use authentication_policy system variable instead. |
master_info_repository | Remove. Always uses TABLE in 8.4. |
relay_log_info_repository | Remove. Always uses TABLE in 8.4. |
binlog_transaction_dependency_tracking | Remove. No longer available. |
avoid_temporal_upgrade | Remove. Temporal columns always use new format. |
show_old_temporals | Remove. No longer available. |
log_bin_use_v1_row_events | Remove. v2 row events are always used. |
expire_logs_days | Remove. Use binlog_expire_logs_seconds instead. |
old_alter_table | Remove. No longer available. |
group_replication_recovery_complete_at | Remove if using Group Replication. |
NOTE: This is not exhaustive. Run the Upgrade Checker (Section above) against your specific my.cnf to get the complete list of incompatible parameters for your configuration.
Parameters with Changed Default Values in 8.4
| Parameter | 8.0 Default | 8.4 Default | Recommendation |
|---|---|---|---|
innodb_adaptive_hash_index | ON | OFF | Explicitly set based on your workload benchmarks |
innodb_flush_method | fsync | O_DIRECT | O_DIRECT is better for most Linux + SSD/NVMe setups; use fsync for ZFS or NFS |
innodb_io_capacity | 200 | 10000 | 200 for spinning disks, 2000-5000 for SSD, 10000+ for NVMe |
innodb_log_buffer_size | 16M | 64M | 64M is fine for most workloads; reduce only if memory-constrained |
BEST PRACTICE: Before upgrading, explicitly set any parameters whose defaults change if you rely on the 8.0 behavior. Silent default changes are one of the biggest sources of unexpected post-upgrade performance shifts.
sql_mode Changes
MySQL 8.4 enforces stricter sql_mode defaults. This is one of the most common sources of silent breakage where queries that worked in 8.0 fail or return different results in 8.4.
Key sql_mode Changes
- ONLY_FULL_GROUP_BY is enforced by default: SELECT columns not in GROUP BY or aggregate functions will error
- NO_ZERO_IN_DATE and NO_ZERO_DATE: Dates like
'0000-00-00'or'2024-00-15'are rejected - Implicit GROUP BY sorting removed: Queries relying on GROUP BY producing sorted output must add explicit ORDER BY clauses
Check Your Current sql_mode
SELECT @@GLOBAL.sql_mode;
Find Tables with Zero-Date Values
-- Example for a specific table:
SELECT COUNT(*) FROM your_table
WHERE date_column = '0000-00-00' OR date_column = '0000-00-00 00:00:00';
WARNING: If your application relies on zero-date values or implicit GROUP BY sorting, these must be fixed before upgrading, or you must explicitly set sql_mode in my.cnf to match your 8.0 behavior. However, carrying forward legacy modes is technical debt that should be addressed.
Authentication Plugin Migration
CRITICAL: The mysql_native_password plugin is REMOVED in MySQL 8.4. Any user account still using this plugin will be unable to authenticate after upgrade unless the transitional option is used.
Identify Affected Users
SELECT user, host, plugin, password_expired
FROM mysql.user WHERE plugin = 'mysql_native_password';
Migrate Users to caching_sha2_password
ALTER USER 'username'@'host' IDENTIFIED WITH caching_sha2_password BY 'new_password';
Verify that all application connection libraries and drivers support caching_sha2_password. Older MySQL connectors (pre-8.0) may not support the new authentication plugin. Common connectors that need updating:
| Connector | Minimum Version Required |
|---|---|
| MySQL Connector/J | 8.0.12+ |
| MySQL Connector/Python | 8.0.11+ |
| PHP mysqlnd | PHP 7.4+ with mysqlnd (native support) |
| Go sql driver (go-sql-driver/mysql) | 1.4+ |
| Node.js mysql2 | 1.6+ (note: mysql package does NOT support it) |
Transitional Option: Temporarily Re-enabling mysql_native_password
If an immediate migration of all users and applications to caching_sha2_password isn't feasible, MySQL 8.4 provides a transitional option. Add the following to your my.cnf:
[mysqld]
mysql_native_password = ON
This loads the plugin at startup so existing accounts using mysql_native_password can still authenticate. It does not make it the default for new accounts. This is strictly a temporary measure to allow a phased migration.
WARNING: The mysql_native_password plugin is deprecated and will be permanently removed in a future MySQL release. Using the transitional option only buys time. Plan to complete migration to caching_sha2_password within 30 days of upgrade.
Recommended Migration Sequence
- Add
mysql_native_password = ONtomy.cnffor the 8.4 upgrade - Upgrade MySQL from 8.0.37 to 8.4
- Verify all applications and users can connect successfully
- Migrate user accounts to
caching_sha2_passwordin batches:
ALTER USER 'app_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'password';
- After all accounts are migrated, remove
mysql_native_password = ONfrommy.cnf - Restart MySQL and verify all connections still work
ProxySQL Considerations
If your environment uses ProxySQL for connection pooling, load balancing, or query routing, the authentication plugin change requires special attention.
CRITICAL: ProxySQL version 2.5.4 or later is required for caching_sha2_password support on the backend side. Upgrade ProxySQL BEFORE upgrading MySQL.
Key Considerations
- ProxySQL handles frontend (app-to-ProxySQL) and backend (ProxySQL-to-MySQL) authentication separately. Both paths must support
caching_sha2_password. caching_sha2_passwordrequires either TLS or RSA public key exchange for the initial handshake. Without TLS between ProxySQL and MySQL, the first authentication will fail.- Configure
GET_SOURCE_PUBLIC_KEY=1in ProxySQLmysql_servers, or enable TLS between ProxySQL and MySQL backends.
Recommended Upgrade Order for ProxySQL Environments
- Upgrade ProxySQL to version 2.5.4+ (no disruption to existing 8.0 traffic)
- Configure TLS or RSA key exchange between ProxySQL and MySQL backends
- Test
caching_sha2_passwordconnectivity through ProxySQL in staging - Proceed with MySQL 8.0.37 to 8.4 upgrade (with
mysql_native_password=ONas transitional) - Migrate user accounts to
caching_sha2_passwordin batches, validating through ProxySQL - Remove
mysql_native_password = ONfrommy.cnfonce fully migrated
BEST PRACTICE: Always test the full authentication chain (Application → ProxySQL → MySQL 8.4) in staging before production cutover. Authentication failures through ProxySQL are one of the most common post-upgrade issues.
Planning a MySQL 8.4 upgrade?
Pre-upgrade preparation is where most teams underestimate the work. If you'd like expert guidance through the compatibility checks, authentication migration, and configuration changes, book a free assessment call.
Book Free Assessment →Schema Compatibility Checks
AUTO_INCREMENT on FLOAT/DOUBLE Columns
MySQL 8.4 removes AUTO_INCREMENT support on FLOAT or DOUBLE columns. Identify and alter affected tables:
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM information_schema.COLUMNS
WHERE EXTRA LIKE '%auto_increment%'
AND DATA_TYPE IN ('float', 'double');
Fix by altering the column to INT or BIGINT:
ALTER TABLE table_name MODIFY COLUMN id BIGINT AUTO_INCREMENT;
New Reserved Keywords
MySQL 8.4 adds reserved keywords including MANUAL, QUALIFY, INTERSECT, and others. If any identifiers use these keywords, they must be backtick-quoted:
-- This will FAIL in 8.4:
CREATE TABLE manual (id INT);
-- Fix:
CREATE TABLE `manual` (id INT);
Foreign Key Validation
MySQL 8.4 enforces stricter foreign key validation. The Upgrade Checker identifies problematic FK constraints. Common issues include mismatched column types between parent and child tables, and FK names that conflict with reserved identifiers.
Character Set Considerations (utf8mb3 to utf8mb4)
While not a hard blocker, utf8 (utf8mb3) is deprecated. Converting to utf8mb4 changes byte widths from 3 to 4 bytes per character, which may violate index length limits (767 bytes for compact/redundant, 3072 for dynamic/compressed). Always check index sizes before converting:
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME
FROM information_schema.COLUMNS
WHERE CHARACTER_SET_NAME IN ('utf8', 'utf8mb3');
SQL Syntax and Terminology Changes
MySQL 8.4 fully removes deprecated replication-related SQL syntax. In 8.0, these produced warnings. In 8.4, they produce ERRORS. All scripts, monitoring tools, and automation must be updated.
| Removed Syntax (8.0) | Required Replacement (8.4) |
|---|---|
SHOW SLAVE STATUS | SHOW REPLICA STATUS |
SHOW MASTER STATUS | SHOW BINARY LOG STATUS |
CHANGE MASTER TO ... | CHANGE REPLICATION SOURCE TO ... |
RESET MASTER | RESET BINARY LOGS AND GTIDS |
STOP SLAVE / START SLAVE | STOP REPLICA / START REPLICA |
RESET SLAVE / RESET SLAVE ALL | RESET REPLICA / RESET REPLICA ALL |
WARNING: Audit ALL application code, stored procedures, monitoring scripts (PMM custom queries, Nagios/Zabbix checks, cron jobs), ProxySQL query rules, and automation tools for deprecated syntax. These commands will produce hard errors in MySQL 8.4.
Part 1 Quick Checklist
Use this checklist to verify you've completed all pre-upgrade preparation steps before moving on to testing.
- Take full logical backup (mysqldump/mydumper) and verify restore
- Take full physical backup (XtraBackup/LVM snapshot) and verify restore
- Verify sufficient disk space (2.5x datadir free)
- Run
mysqlcheck --all-databases --checkfor corruption - Run MySQL Shell Upgrade Checker targeting 8.4.8
- Resolve all Upgrade Checker ERRORS
- Address all Upgrade Checker WARNINGS
- Identify and migrate
mysql_native_passwordusers (or plan transitional) - Identify and fix AUTO_INCREMENT on FLOAT/DOUBLE columns
- Audit
my.cnf: remove all deprecated/removed parameters - Set explicit values for parameters with changed defaults
- Review and fix
sql_mode-dependent queries (GROUP BY, zero dates) - Audit all scripts/code for MASTER/SLAVE syntax
- Upgrade ProxySQL to 2.5.4+ (if applicable)
- Test auth chain through ProxySQL in staging (if applicable)
- Verify all tool versions are 8.4-compatible (PMM, XtraBackup, etc.)
Continue the Series
- Part 1: Pre-Upgrade Preparation (You Are Here)
- Part 2: Upgrade Testing →