---
title: "YSQL major upgrade"
url: "https://docs.yugabyte.com/stable/manage/ysql-major-upgrade-logical-replication/"
---

# YSQL major upgrade

Upgrade logical replication streams to YugabyteDB version that supports PG 15

Upgrade YugabyteDB to a version that supports PG 15

Upgrading YugabyteDB from a version based on PostgreSQL 11 (all versions prior to v2.25) to a version based on PostgreSQL 15 (v2025.1 or later (stable) or v2.25 or later (preview)) requires additional steps. For instructions on upgrades within a major PostgreSQL version, refer to [Upgrade YugabyteDB](/stable/manage/upgrade-deployment/ "Upgrade YugabyteDB").

The upgrade is fully online. While the upgrade is in progress, you have full and uninterrupted read and write access to your cluster.

Performing a YSQL major upgrade on a universe with [CDC with logical replication](/stable/additional-features/change-data-capture/using-logical-replication/ "CDC with logical replication") requires additional steps.

- [![Server Icon](/icons/database.svg) Yugabyted](/stable/manage/ysql-major-upgrade-yugabyted/)
- [Manual](/stable/manage/ysql-major-upgrade-local/)
- [Logical Replication](/stable/manage/ysql-major-upgrade-logical-replication/)

Logical replication streams can be upgraded to YugabyteDB v2025.1.1 and later.

When performing a YSQL major upgrade on a universe with CDC using logical replication, perform the following additional steps.

## Before you begin

1. Determine a time (say `stop_ddl_time`), after which be no DDLs will be performed on the tables being replicated using logical replication.
   
   Do not make DDL changes
   
   Do not perform any DDLs on relevant tables or modify the publication(s) between `stop_ddl_time` and completing the upgrade of logical replication streams. Any such DDL will render the slot useless, and you will need to create a new slot, potentially requiring an initial snapshot.
2. Ensure that restart time of all the replication slots has crossed the `stop_ddl_time`. You can use the following query to find the restart time of a slot:
   
   ```sql
   SELECT to_timestamp((yb_restart_commit_ht / 4096) / 1000000) \
     AS yb_restart_time FROM pg_replication_slots;
   ```
   
   ```output
       yb_restart_time
   ------------------------
   2025-09-15 19:58:26+00
   (1 row)
   ```
3. After the `yb_restart_time` for all the slots has crossed `stop_ddl_time`, delete the connector and start the upgrade process.

## After finalizing the upgrade

After the upgrade is finalized and complete, do the following:

1. Note down the time at which the process was completed. Call it `upgrade_complete_time`.
2. Redeploy the connector, but add the following configuration to the existing list of configurations:
   
   ```yaml
   "ysql.major.upgrade":"true"
   ```
   
   If the connector is deployed without this configuration, you will see the following error:
   
   ```output
   ERROR:  catalog version for database 16640 was not found.
   HINT:  Database might have been dropped by another user
   STATEMENT:  START_REPLICATION SLOT "test_slot" LOGICAL 0/2D3B0 ("proto_version" '1', "publication_names" 'test_pub', "messages" 'true')
   ```
   
   This is not a problem as long as you deploy the connector with the specified configuration before the stream expires. The duration between killing the connector before upgrade and then redeploying it with the new configuration should be less than the expiry period.
   
   The connector will start streaming the records and covering up the lag which it accumulated. As the connector streams records, the restart time will move forward for the slot.
3. After the restart time of all the replication slots has exceeded `upgrade_complete_time`, restart the connector using the following:
   
   ```yaml
   "ysql.major.upgrade":"false"
   ```
   
   This marks the successful upgrade of the logical replication streams.
4. Resume the DDLs and make changes to the publications as desired.

## Verify the upgrade

After any upgrade, confirm the stream is healthy as follows:

- Connector status: `GET /connectors/<name>/status` returns `RUNNING` for the connector and its tasks, with no failures.
- Slot progressing: `restart_lsn` / `confirmed_flush_lsn` advance and lag drains.
  
  ```plpgsql
  SELECT slot_name, confirmed_flush_lsn,
         to_timestamp((yb_restart_commit_ht / 4096) / 1000000) AS yb_restart_time
  FROM pg_replication_slots;
  ```
- Events flowing: New changes appear on the expected Kafka topics; sink lag returns to normal.

## Rollback

Downgrade isn't supported. If a new version misbehaves:

- Prefer fixing forward to a later patch on the same line.
- If you must return to a previous version, [re-snapshot](/stable/additional-features/change-data-capture/using-logical-replication/upgrade-connector/#when-a-re-snapshot-is-required "re-snapshot") on that version (new slot, fresh snapshot) rather than pointing the previous connector at the existing slot.
