Skip to main content
CloudSeptember 28, 20268 min read

Upgrade RDS MySQL 8.0 to 8.4 With a Blue/Green Switch

Get technical support

AWS run day to day, not when it breaks

RDS for MySQL 8.0 left standard support on July 31, 2026, and instances still on it are now billed for Extended Support. This shows how to reach 8.4 with a blue/green switch: what rules the method out, what 8.4 refuses that 8.0 accepted, the CLI steps, and why there is no switch-back unless you build one first.

Amazon RDS for MySQL 8.0 left standard support on July 31, 2026. Since August 1, every instance still on 8.0 that was not opted out has been enrolled in RDS Extended Support, which AWS bills on top of the normal instance charge, and for Multi-AZ on the standby as well. Extended Support for 8.0 ends on July 31, 2029, and after that AWS upgrades the major version itself, on its schedule rather than yours. When we covered the deadline in June, the advice was to upgrade before it. For the instances that did not make it, this is how to do the upgrade now with as little downtime as RDS allows.

The only upgrade target from 8.0 is 8.4. A blue/green deployment builds an 8.4 copy of production beside it, keeps the copy in sync, and then swaps the two. The RDS user guide says the swap usually costs under a minute of downtime, and a January 2026 update puts it at typically five seconds or less for applications that connect straight to the database endpoint.

How the Swap Works

Production is the blue environment. RDS creates the green environment by restoring a snapshot of blue, including its read replicas, and keeps green in step through binary log replication. Green may run a newer engine version than blue but never an older one, which is what makes it usable for a major upgrade. Until the switch, green is read-only.

When you switch over, RDS checks that both sides are ready, stops writes on both, drops connections, waits for green to catch up, and then renames everything. Green takes over blue's instance names and endpoints, and blue is renamed with a suffix such as -old1. The application keeps its connection string. If the switch takes longer than the timeout, 300 seconds by default, RDS rolls it back and changes nothing.

Clients must not cache DNS for longer than five seconds, the TTL of the RDS DNS zones. A client that holds on to the old address keeps writing to the old primary after the switch.

What Rules a Blue/Green Deployment Out

Check these before creating anything. From the RDS documentation:

  • Automated backups have to be enabled.
  • Master user passwords managed in AWS Secrets Manager are not supported.
  • Cascading read replicas, cross-Region read replicas, CloudFormation and Multi-AZ DB clusters are not supported. Multi-AZ DB instances are.
  • The blue instance cannot be an external binlog replica.
  • If you use RDS Proxy, the blue database has to be registered with the proxy before the deployment is created.
  • Zero-ETL integrations with Amazon Redshift have to be deleted before the switch and recreated after it.
  • If the database uses a custom option group, the major upgrade cannot be requested when the deployment is created. Create it on the same version and upgrade green afterwards.
  • The event scheduler, event_scheduler, must be off on green when the deployment is created.
  • Point-in-time recovery history does not carry over. After the switch, the new production instance can be restored only back to the moment green was created.

Find What 8.4 Will Refuse

RDS checks for incompatibilities before every major version upgrade, cancels the upgrade if it finds any, and records each one in PrePatchCompatibility.log. For 8.0 to 8.4 the documented checks cover tables that use obsolete data types or functions, triggers with a missing or empty definer or an invalid creation context, keywords that 8.4 reserves, tables in the mysql schema whose names collide with the 8.4 data dictionary, obsolete sql_mode values, ENUM or SET elements longer than 255 characters or 1,020 bytes, features removed in 8.4, and foreign key constraint names longer than 64 characters.

If the upgrade of green is refused, read the log from the green instance:

aws rds download-db-log-file-portion \
  --db-instance-identifier app-prod-green-abc123 \
  --log-file-name PrePatchCompatibility.log \
  --output text

The prechecks look at the schema. They cannot see the SQL that applications, scripts and monitoring send, and that is where the next four changes land.

Authentication

On RDS for MySQL 8.4, new users get caching_sha2_password. Users that existed before the upgrade, the master user included, keep mysql_native_password, which RDS says still works on 8.4 but whose support ends with 8.4. Community MySQL 8.4 goes further and ships the old plugin disabled.

Find the accounts still on the old plugin, and move each one once its clients are ready:

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

-- keep the same password string so the application does not need a new one
ALTER USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY 'the-current-password';

RDS requires accounts on caching_sha2_password to connect over SSL. In PHP, the mysqlnd driver behind PDO and mysqli fully supports the plugin from PHP 7.4.4, so an application on an older PHP has to keep the old plugin until the application itself is upgraded.

Foreign keys

MySQL 8.4 turns restrict_fk_on_non_standard_key on by default, so a foreign key that references a non-unique key, or only part of one, is rejected where 8.0 accepted it. A migration that relied on that behavior fails on 8.4 unless the variable is set to OFF.

Replication statements, procedures and variables

Statements with MASTER and SLAVE in them are gone. SHOW SLAVE STATUS is now SHOW REPLICA STATUS, SHOW MASTER STATUS is SHOW BINARY LOG STATUS, CHANGE MASTER TO is CHANGE REPLICATION SOURCE TO, and RESET MASTER is RESET BINARY LOGS AND GTIDS. Monitoring checks written for 8.0 often still use the old forms. The expire_logs_days and binlog_transaction_dependency_tracking variables are removed as well, and setting either raises an error. On RDS the replication procedures were renamed in the same way, for example mysql.rds_set_external_source in place of mysql.rds_set_external_master.

Parameters and performance

An 8.4 instance needs a parameter group from the mysql8.4 family, so custom settings have to be carried across by hand, leaving out the variables 8.4 removed. RDS also enables innodb_dedicated_server on 8.4, which means the engine now sizes the buffer pool and redo log capacity itself. MySQL 8.4 changed several InnoDB defaults too, among them innodb_adaptive_hash_index (now OFF), innodb_change_buffering (now none) and innodb_io_capacity (now 10000, up from 200). Check what the RDS default group sets for your instance class, and compare query timings on green instead of assuming 8.4 behaves like 8.0.

Build Green

# a parameter group for 8.4: copy your custom settings into it,
# leave out variables 8.4 removed, and keep the event scheduler off for now
aws rds create-db-parameter-group \
  --db-parameter-group-name app-mysql84 \
  --db-parameter-group-family mysql8.4 \
  --description "App on MySQL 8.4"

aws rds modify-db-parameter-group \
  --db-parameter-group-name app-mysql84 \
  --parameters "ParameterName=event_scheduler,ParameterValue=OFF,ApplyMethod=immediate"

# on blue, before the deployment exists, keep binary logs for a day:
#   CALL mysql.rds_set_configuration('binlog retention hours', 24);

# use the newest 8.4 minor version offered in your Region
aws rds create-blue-green-deployment \
  --blue-green-deployment-name app-mysql84 \
  --source arn:aws:rds:eu-central-1:111122223333:db:app-prod \
  --target-engine-version 8.4.11 \
  --target-db-parameter-group-name app-mysql84

# wait until this prints AVAILABLE
aws rds describe-blue-green-deployments \
  --filters Name=blue-green-deployment-name,Values=app-mysql84 \
  --query 'BlueGreenDeployments[0].Status'

The binlog retention step comes from AWS's own guide to this upgrade, which lists it as a check before the deployment is created so that enough binary log remains after the switch to replicate back. The RDS maximum is 168 hours.

If the source uses a custom option group, leave out the two --target options, let the deployment build on 8.0, and upgrade the green instance afterwards with aws rds modify-db-instance, passing --engine-version, --allow-major-version-upgrade and the new parameter group.

Warm Green Up and Test It

Green was restored from a snapshot and loads its data blocks lazily, fetching each one from Amazon S3 the first time it is read. AWS asks for that loading to be complete before the switch. Run the heaviest read queries against green, or read through the largest tables, so that the first production requests after the switch are not the ones waiting on cold blocks.

Then test green as the 8.4 server it now is. Watch replication lag with SHOW REPLICA STATUS, since SHOW SLAVE STATUS no longer exists there. Point a staging copy of the application at green's endpoint for reads, confirm that every application user can still log in from the application servers, and run EXPLAIN on the queries that matter most.

Switch

aws rds switchover-blue-green-deployment \
  --blue-green-deployment-identifier bgd-1234567890abcdef \
  --switchover-timeout 300

RDS will not start the switch while green is not replicating cleanly or is too far behind, or while blue has long-running writes or DDL in progress. Once it completes:

  • turn the event scheduler back on in app-mysql84 if the application uses events,
  • repoint any external replica or binlog consumer that read from blue, using the binary log coordinates that RDS records in an event on the old green instance,
  • remove the deployment object with aws rds delete-blue-green-deployment --blue-green-deployment-identifier bgd-1234567890abcdef --no-delete-target, which leaves every instance in place.

If You Need a Way Back

There is no switch-back. Replication between the environments stops at the switch, and the old 8.0 instance stays read-only under its -old1 name until you set read_only to 0 and reboot it. MySQL supports going from 8.4 back to 8.0 only by dump and load or by replication, and only as a rollback, before anything new in 8.4 has touched the data.

A realistic way back is therefore replication from the new 8.4 primary into the old 8.0 instance, starting from those binary log coordinates, and it has to be prepared and rehearsed before the switch rather than improvised after it. AWS's database blog has a full walkthrough of that reverse replication.

Keep the old instance, or at least a final snapshot of it, for as long as your recovery window. The new instance's point-in-time history only starts when green was created, and the old instance is billed like any other until you delete it.

If a Magento store runs on this database, the 2.4.9 upgrade guide covers the application side. Running RDS day to day, upgrades like this one included, is part of AWS Cloud Management.

Or read how we handle it in AWS Cloud Management.