Blue-green deployment upgrades the major engine version of ApsaraDB RDS for PostgreSQL by restoring the source instance to a new instance, then running pg_upgrade to bring the new instance to the target version. If you perform a cutover, the source instance endpoint automatically switches to the new instance — no connection string changes required in your application.
For a comparison of all available upgrade modes, see Introduction to major version upgrade solutions.
Prerequisites
Before you begin, make sure that:
-
The instance runs ApsaraDB RDS for PostgreSQL 16 or an earlier version
-
The instance is not a read-only instance or a dedicated cluster instance
-
Babelfish is not enabled on the instance (the minor engine version number does not end with
babelfish)
Billing
When you start a blue-green deployment upgrade, the system creates a new instance based on the source instance. Both instances are billed separately until you release the source instance.
| Source instance billing method | New instance billing method |
|---|---|
| Subscription or pay-as-you-go | Pay-as-you-go |
| Serverless | Serverless |
After confirming that your services run stably on the new instance, convert the new instance to subscription and release or unsubscribe from the source instance.
Note the following before releasing the source instance:
-
If your source instance is a subscription instance that has not expired, the new instance cannot inherit the remaining subscription duration. Releasing the source instance early may result in a financial loss. For more information about refund rules, see Refund policy.
-
The new instance does not inherit any discounts applied to the source instance. Check the specific refund amount on the instance unsubscription page before you decide to proceed.
-
Refunds for subscription instances are not processed in real time. The refund amount and timing are subject to the actual unsubscription bill.
Potential impacts
Review the following before starting the upgrade.
Service interruption
When you perform a blue-green deployment with a cutover, the source instance becomes read-only during the cutover, causing a transient connection interruption. Perform the upgrade during off-peak hours. If you do not perform a cutover, your services are not affected.
-
Read-only duration: Depends on the number of database objects. Run
SELECT count(1) FROM pg_class;to check the count. With millions of objects, the read-only period can last tens of minutes or longer. -
Connection interruption duration: Determined by the DNS cache refresh time on the client side. Use vSwitch switching to estimate this value in advance.
-
Total upgrade duration: Depends on the number of database objects. Monitor progress in Task Hub.
After the cutover, the source instance remains read-only by default. To allow writes on the source instance again, set the rds_force_trans_ro_non_sup parameter to off. See Set instance parameters.
Cross-version upgrade path
PostgreSQL 9.4 and 10 instances using high-performance local disks can only upgrade to cloud disks, with PostgreSQL 14 as the maximum direct target. To reach PostgreSQL 15 or later, first upgrade to an intermediate version:
-
PostgreSQL 9.4: can upgrade to 10, 11, 12, 13, or 14 as an intermediate step
-
PostgreSQL 10: can upgrade to 11, 12, 13, or 14 as an intermediate step
Replication slots
-
If the source instance is a publisher with replication slots, those replication slots are lost after the upgrade.
-
If the source instance is a replication slot subscriber, the upgrade may cause data synchronization issues due to replication slot preemption. See the FAQ for how to prevent this.
Virtual IP changes
After a cutover, the virtual IP address of the new instance changes. Check firewall configurations and any application configurations that reference the virtual IP directly. To avoid this complexity, configure your application using the instance connection address instead of the virtual IP.
Parameter changes
-
Parameters unsupported in the target version are automatically deleted.
-
Parameters with values outside the valid range for the target version are reset to the target version's default template values.
-
During the upgrade,
statement_timeoutis temporarily set to0and restored to its original value after the upgrade completes.
DTS tasks
If the instance is a source or destination for Data Transmission Service (DTS), recreate the DTS task after the upgrade.
Plugin compatibility
The upgrade automatically updates the instance to the latest minor engine version. Verify plugin compatibility before and after the upgrade.
Settings not inherited by the new instance
The new instance does not inherit the source instance's name, tags, CloudMonitor alert rules, or backup data.
Step 1: Run the pre-upgrade check
-
Log on to the ApsaraDB RDS console. In the top navigation bar, select the region where the instance resides. Find the instance and click its ID.
-
(Optional) If read-only instances exist for the source instance, change the read-only instance endpoint in your application to the primary instance endpoint during off-peak hours, then delete the read-only instance.
Deleting read-only instances before the upgrade is necessary because read-only nodes and replication slots are not automatically transferred to the new instance. After the upgrade, create new read-only instances on the new instance.
-
In the left navigation pane, click Major Version Upgrade.
If Major Version Upgrade is not visible, verify that your instance meets the prerequisites listed above.
-
On the Upgrade Check tab, click Create upgrade check report.
-
Select the target version, set Upgrade Mode to Blue-green Deployment, and click OK. The instance status changes to Maintaining Instance. After the check completes, the status returns to Running.
-
Review the check report result:
-
Success or Warning: proceed to Step 2.
-
Failed: click View Information, fix the issues identified, and rerun the check.
Important- For a Warning result, fix all flagged items and rerun the check until the result is Success. - If you create a plugin on the primary instance after a successful check, run the check again before proceeding.
-
What's next
-
If you upgraded using the blue-green deployment (cutover) method, after confirming that your services run stably on the new instance, release the source instance. Convert the new instance's billing method to subscription to save costs.
Releasing a subscription instance before expiry may result in a financial loss. The new instance does not inherit any discounts from the source instance. Refunds are subject to the actual unsubscription bill and are not processed in real time.
-
(Optional) If you deleted a read-only instance before the upgrade, recreate it on the new instance:
-
Create a PostgreSQL read-only instance on the new instance.
-
In your application, update the endpoint to point to the new read-only instance.
-
API reference
| API operation | Description |
|---|---|
| UpgradeDBInstanceMajorVersionPrecheck | Runs a pre-upgrade check for a major version upgrade |
| DescribeUpgradeMajorVersionPrecheckTask | Queries the pre-upgrade check report |
| UpgradeDBInstanceMajorVersion | Upgrades the major engine version |
| DescribeUpgradeMajorVersionTasks | Queries the history of major version upgrade tasks |
References
FAQ
Can I modify the instance during a major version upgrade?
No. The instance cannot be modified while an upgrade is in progress. Modifications are available only after the upgrade completes.
Are automatic major version upgrades supported?
No. Major version upgrades must be triggered manually.
Are major version downgrades supported?
No. Downgrading is not supported after a major version upgrade. To run a lower version, purchase a new instance at that version and use Data Transmission Service (DTS) to migrate your data.
After a major version upgrade, I get a `raster_overviews` conflict when creating a view in the new instance. How do I fix this?
This issue occurs when the PostGIS version is earlier than 2.5.2 and you are upgrading from PostgreSQL 10 or 11 to PostgreSQL 12 without first upgrading the PostGIS plugin.
Step 1: Upgrade the PostGIS plugin on the source instance.
Run the following command twice to make sure the upgrade completes successfully:
SELECT PostGIS_Extensions_Upgrade();
SELECT PostGIS_Extensions_Upgrade();
Step 2: Choose the fix based on whether you use the PostGIS Raster plugin.
If the PostGIS Raster plugin is in use:
-
On the source instance, detach the
raster_overviewsview from the extension and replace it with a placeholder:ALTER EXTENSION PostGIS_Raster DROP VIEW raster_overviews; CREATE OR REPLACE VIEW raster_overviews AS SELECT 1; -
Upgrade the PostgreSQL instance to at least PostgreSQL 12.
-
After the upgrade, recreate the view on the new instance:
CREATE OR REPLACE VIEW raster_overviews AS SELECT current_database() AS o_table_catalog, n.nspname AS o_table_schema, c.relname AS o_table_name, a.attname AS o_raster_column, current_database() AS r_table_catalog, split_part( split_part(s.consrc, '''::name', 1), '''', 2 )::name AS r_table_schema, split_part( split_part(s.consrc, '''::name', 2), '''', 2 )::name AS r_table_name, split_part( split_part(s.consrc, '''::name', 3), '''', 2 )::name AS r_raster_column, trim( both from split_part(s.consrc, ',', 2) )::integer AS overview_factor FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n, ( SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc FROM pg_constraint ) AS s WHERE t.typname = 'raster'::name AND a.attisdropped = false AND a.atttypid = t.oid AND a.attrelid = c.oid AND c.relnamespace = n.oid AND c.relkind = ANY( ARRAY[ 'r'::char, 'v'::char, 'm'::char, 'f'::char ] ) AND s.connamespace = n.oid AND s.conrelid = c.oid AND s.consrc LIKE '%_overview_constraint(%' AND NOT pg_is_other_temp_schema(c.relnamespace) AND has_table_privilege(c.oid, 'SELECT'::text); ALTER EXTENSION PostGIS_Raster ADD VIEW raster_overviews;
If the PostGIS Raster plugin is not in use:
-
Drop the plugin on the source instance:
DROP EXTENSION PostGIS_Raster; -
Upgrade the PostgreSQL instance to at least PostgreSQL 12.
How do I prevent data inconsistency caused by replication slot preemption during an upgrade?
If the source instance is a replication slot subscriber, the replication slot may be preempted by the new instance during the upgrade, which can cause data inconsistency.
To keep subscription data on the source (lower-version) instance: make sure the source instance does not fail due to excessive load during the upgrade to prevent the replication slot from being preempted. After the upgrade completes, disable the subscription on the new instance:
\c your_database
ALTER SUBSCRIPTION your_subscription_name DISABLE;
To preserve subscription data on the new (higher-version) instance: disable the subscription on the source instance before starting the upgrade, then enable it on the new instance after the upgrade completes.
Disable on the source instance:
\c your_database
ALTER SUBSCRIPTION your_subscription_name DISABLE;
Enable on the new instance:
\c your_database
ALTER SUBSCRIPTION your_subscription_name ENABLE;
For more information, see Logical Subscription and Change Tracking.
How do I handle subscription data inconsistency after an upgrade?
If inconsistency has already occurred, use the following approach to reconcile:
-
On the new instance, delete the affected table data, recreate the subscription with
copy_data=true. For details, see ALTER SUBSCRIPTION. -
Use
ON CONFLICTto import data from the source instance. The following example shows how to handle different conflict scenarios:CREATE TABLE my_tbl(id INT PRIMARY KEY, t TIMESTAMP, val TEXT); INSERT INTO my_tbl VALUES (1, CURRENT_TIMESTAMP, 'a'); INSERT INTO my_tbl VALUES (2, CURRENT_TIMESTAMP, 'b'); INSERT INTO my_tbl VALUES (3, CURRENT_TIMESTAMP, 'c'); -- Newer timestamp: update the existing row INSERT INTO my_tbl VALUES (1, CURRENT_TIMESTAMP, 'd') ON CONFLICT(id) DO UPDATE SET t = excluded.t, val = excluded.val WHERE my_tbl.t < excluded.t; -- Older timestamp: keep the existing row INSERT INTO my_tbl VALUES (2, CURRENT_TIMESTAMP - '10 hours'::interval, 'e') ON CONFLICT(id) DO UPDATE SET t = excluded.t, val = excluded.val WHERE my_tbl.t < excluded.t; -- New row: insert directly INSERT INTO my_tbl VALUES (5, CURRENT_TIMESTAMP - '10 hours'::interval, 'f') ON CONFLICT(id) DO UPDATE SET t = excluded.t, val = excluded.val WHERE my_tbl.t < excluded.t;
Why do I need to delete read-only instances before the upgrade?
Read-only nodes and replication slots on the source instance are not automatically transferred to the new instance after the upgrade. Deleting the read-only instance before the upgrade prevents endpoint conflicts and ensures a clean cutover. After the upgrade, create a new read-only instance on the new instance and update your application endpoint accordingly.