Back to blog

// OSSeva Blog

Migration

MySQL 8.0 to 8.4 Upgrade Guide: Breaking Changes and How to Check for Each

Matt Reynolds10 min read

The short answer

MySQL supports upgrading from 8.0.37 or later directly to 8.4 LTS, in place, by dump and load, or through replication. Most upgrades stall on four things: accounts that still use mysql_native_password, which 8.4 no longer enables by default; replication scripts and tools that use the removed CHANGE MASTER TO, START SLAVE and SHOW SLAVE STATUS statements; server options that 8.4 removed and now refuses at startup; and InnoDB defaults that changed under you. Run MySQL Shell's upgrade checker first, fix what it finds, then upgrade a replica before the primary.

There is no in-place downgrade from 8.4 to 8.0. Rolling back means a logical dump or replication, and only if no 8.4-only functionality has touched the data, so plan the way back before you start.

Upgrade paths

FromToSupported?
8.0.37 or later8.4.xYes: in place, logical dump and load, or replication
Earlier 8.08.4.xMove to the latest 8.0 first, 8.0.46, then to 8.4
5.78.4.xNo. Upgrade to 8.0 first, then to 8.4
8.09.7 LTSNo. An LTS series cannot be skipped, so 8.4 comes first
8.4.x8.0Only by dump and load or replication, for rollback, and only if no new functionality has been used

MySQL Clone cannot be used to move between series. Within 8.4, clone now works between point releases, for example from 8.4.0 to a later 8.4 release.

Step 1: run the upgrade checker

MySQL Shell's upgrade checker connects to an 8.0 server, reads its configuration file and reports what will break. Use a MySQL Shell version at least as new as your target.

mysqlsh -- util checkForServerUpgrade root@db1:3306 \
  --target-version=8.4.12 \
  --config-path=/etc/mysql/my.cnf \
  --output-format=JSON > db1-upgrade-check.json

Its checks include reserved keywords used as identifiers, removed functions, system variables that were removed or changed default, the default authentication plugin, zero dates and utf8mb3 usage. It also lists manual checks it cannot automate, such as replication topology. Treat every error as a blocker and every warning as a ticket.

Breaking change 1: mysql_native_password is off by default

In 8.4 the mysql_native_password authentication plugin is no longer enabled by default. Accounts that use it cannot log in until you either move them to caching_sha2_password or turn the plugin back on. The default_authentication_plugin variable has been removed; authentication_policy replaces it, with changed syntax.

Find the affected accounts before the upgrade:

SELECT user, host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password';

The clean fix is to move each account, after checking that every client driver, connection pool and proxy in use supports caching_sha2_password:

ALTER USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY 'new-password';

As a bridge, start 8.4 with mysql_native_password=ON in the [mysqld] section and convert accounts afterwards. Remove any default_authentication_plugin line from the configuration file, or the server will not start.

Breaking change 2: replication statements and options were removed

The MASTER and SLAVE forms that 8.0 deprecated are gone, and using them in 8.4 is a syntax error:

Removed in 8.4Use instead
CHANGE MASTER TOCHANGE REPLICATION SOURCE TO
START SLAVE / STOP SLAVESTART REPLICA / STOP REPLICA
SHOW SLAVE STATUSSHOW REPLICA STATUS
SHOW SLAVE HOSTSSHOW REPLICAS
RESET SLAVERESET REPLICA
RESET MASTERRESET BINARY LOGS AND GTIDS
SHOW MASTER STATUSSHOW BINARY LOG STATUS
SHOW MASTER LOGS / PURGE MASTER LOGSSHOW BINARY LOGS / PURGE BINARY LOGS
MASTER_HOST, MASTER_PORT, MASTER_AUTO_POSITION and the other MASTER_ optionsSOURCE_HOST, SOURCE_PORT, SOURCE_AUTO_POSITION and so on

Also removed: the Com_slave_* status counters, file-based replication metadata options such as --master-info-repository and --relay-log-info-file, binlog_transaction_dependency_tracking (8.4 always uses writesets), and --slave-rows-search-algorithms. The default SOURCE_RETRY_COUNT is now 10.

The statements live outside the database: failover scripts, orchestration tools, backup scripts, monitoring checks that parse SHOW SLAVE STATUS, and Ansible or Puppet roles. Search for them before the upgrade:

grep -rniE "change master|start slave|stop slave|show slave status|reset master|show master status|com_slave_" \
  ./ops ./ansible ./monitoring

Check that the versions of your HA and monitoring tools support 8.4, since many issue these statements themselves.

Breaking change 3: server options that now stop startup

Setting a removed option in 8.4 raises an error, so a configuration file copied from 8.0 can keep the server from starting. The ones most often found in real configuration files:

  • expire_logs_days: use binlog_expire_logs_seconds.
  • default_authentication_plugin: use authentication_policy.
  • --skip-host-cache: use --host-cache-size=0.
  • --ssl, --admin-ssl, have_ssl, have_openssl: use --tls-version and --admin-tls-version.
  • --old, --new, --language, --character-set-client-handshake, --old-style-user-limits, --innodb and --skip-innodb.
  • avoid_temporal_upgrade and show_old_temporals.
  • keyring_file and keyring_encrypted_file plugins: use the component_keyring_file and component_keyring_encrypted_file components.

The FLUSH HOSTS statement is gone too; use TRUNCATE TABLE performance_schema.host_cache or mysqladmin flush-hosts. TLS settings that name weak ciphers are rejected, and 8.4 accepts only ciphers that meet its TLS 1.2 and 1.3 requirements. The authentication_fido plugin has been replaced by authentication_webauthn.

Breaking change 4: nonstandard foreign keys are rejected

Foreign keys that reference a non-unique or partial key are now refused by default, because restrict_fk_on_non_standard_key is ON. Existing tables with such keys still upgrade; the error appears when a migration or DDL script creates one. Find them in advance by checking each referenced column set against a unique index, and either add the unique index or set restrict_fk_on_non_standard_key to OFF as a temporary measure.

Changed InnoDB defaults

These do not break anything outright, but they change behaviour on servers that never set them explicitly:

Variable8.0 default8.4 default
innodb_io_capacity20010000
innodb_adaptive_hash_indexONOFF
innodb_change_bufferingallnone
innodb_log_buffer_size16 MiB64 MiB
innodb_flush_method (Linux)fsyncO_DIRECT if supported
innodb_numa_interleaveOFFON
innodb_buffer_pool_instances8 (1 below 1 GiB)Calculated from buffer pool size and CPUs
innodb_page_cleaners4Equal to innodb_buffer_pool_instances
temptable_max_ram1 GiB3% of memory, between 1 and 4 GiB

The adaptive hash index and I/O capacity changes are the ones most likely to show up in benchmarks. Record the effective values on 8.0 with SHOW GLOBAL VARIABLES, decide which to pin in the configuration file, and compare query latency on a test replica before the change reaches production.

An order of work that leaves a way back

  1. Move every 8.0 server to 8.0.46, the final 8.0 release.
  2. Run the upgrade checker against each server and its configuration file, and clear the errors.
  3. Convert mysql_native_password accounts, or plan to enable the plugin temporarily.
  4. Update replication, failover, backup and monitoring tooling to the REPLICA and SOURCE syntax.
  5. Clean removed options out of the configuration files.
  6. Upgrade one replica to 8.4, let it replicate from the 8.0 primary and run read traffic or a replayed workload against it.
  7. Upgrade the remaining replicas, then switch the primary role to an 8.4 replica.
  8. Keep an 8.0 replica of the new primary for a short period as the rollback route, since in-place downgrade is not supported.

On Amazon RDS the in-place 8.0 to 8.4 major version upgrade is supported, and AWS describes rehearsing it on an instance restored from a snapshot. On Azure, mysql_native_password stays enabled, which removes the first blocker but not the others.

Where OSSeva fits

If some servers cannot move before their window closes, OSSeva for MySQL keeps 8.0 patched with signed Community builds that install on the same data directory, so the upgrade can run at the pace your applications allow. OSSeva Assure builds the 8.0 to 8.4 and 8.4 to 9.7 upgrade plan from the upgrade checker output, including the authentication review for mysql_native_password accounts and a replication topology review. OSSeva Operate executes rolling upgrades replica by replica. Pricing is per cluster; book a discovery call for a quote. For the dates behind the deadline, see MySQL 8.0 end of life.

Frequently asked questions

Can I upgrade directly from MySQL 8.0 to 8.4?

Yes, from 8.0.37 or later, in place, by dump and load, or by replication. Earlier 8.0 releases should be updated to the latest 8.0 first.

Can I upgrade from MySQL 5.7 to 8.4 directly?

No. MySQL does not allow skipping an LTS or bugfix series, so 5.7 goes to 8.0 first and then to 8.4.

Why can't users log in after upgrading to MySQL 8.4?

Usually because their accounts use mysql_native_password, which 8.4 no longer enables by default. Move the accounts to caching_sha2_password, or start the server with mysql_native_password=ON while you convert them.

Can I downgrade from MySQL 8.4 to 8.0?

Not in place. A downgrade is possible by logical dump and load or replication, for rollback purposes, and only if no new 8.4 functionality has been applied to the data.

What happened to SHOW SLAVE STATUS in MySQL 8.4?

It was removed, along with the other SLAVE and MASTER statements. Use SHOW REPLICA STATUS, and update any monitoring check that parses the old output.

Should we go to 8.4 or wait for 9.7?

Go to 8.4. An LTS series cannot be skipped, so every 8.0 server passes through 8.4 on the way to 9.7 anyway, and 8.4 has Premier Support until April 2029.

Tags

MySQLMySQL 8.4UpgradeReplicationAuthentication

Ready to get your open source under control?

Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.