Re: [PATCH] Preserve replication origin OIDs in pg_upgrade

From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com>, Dilip Kumar <dilipbalaut(at)gmail(dot)com>, Ajin Cherian <itsajin(at)gmail(dot)com>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>, vignesh C <vignesh21(at)gmail(dot)com>, "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: [PATCH] Preserve replication origin OIDs in pg_upgrade
Date: 2026-06-15 11:31:21
Message-ID: CAA4eK1KzGSANd=g1S8xpcyiwh3M-c+Uaa4+447v-+N8chX7K3g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Jun 11, 2026 at 12:08 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> Ajin, Kuroda-san, and I discussed several possible approaches to address this:
>
> 1)
> Add a new subscription option, for example 'skip_origin_creation'.
> When set to true, CREATE SUBSCRIPTION would skip replication-origin
> creation. During binary upgrade, pg_dump would emit
> skip_origin_creation = true for source clusters running PG17 or later,
> and false otherwise.
>
> However, this approach requires introducing a new user-visible CREATE
> SUBSCRIPTION option.
>
> 2)
> Another idea could be to have a
> 'binary_upgrade_skip_subs_origin_creation' variable. We populate it
> during dumpSubscription if 'source_version >= PG17' and
> 'IsBinaryUpgrade' is true. So this will be dumped
>
> SELECT pg_catalog.binary_upgrade_set_skip_subs_origin_creation(true);
> CREATE SUBSCRIPTION ...
> SELECT pg_catalog.binary_upgrade_set_skip_subs_origin_creation(false);
>
> First call will set 'binary_upgrade_skip_subs_origin_creation' which
> will be used by Create Subscription to decide to skip origin. This is
> similar to how dumpACl decides whether to record priveleges into
> 'pg_init_privs' for objectes created by extensions. See
> binary_upgrade_set_record_init_privs() which sets
> binary_upgrade_record_init_privs which is then used by
> recordExtensionInitPriv().
>
> 3)
> Create origins and preserve origin IDs regardless of source version
>
> The current patch preserves origin IDs for upgrades from PG17 and later.
>
> One reason for choosing PG17 as the starting point for preserving
> origin-ids is that complete logical-replication setup migration was
> introduced in PG17. Prior to PG17, subscription state
> (pg_subscription_rel) and replication slots were not preserved during
> upgrade, so limiting origin-ID preservation to PG17 and later aligns
> with the broader logical-replication migration support.
>
> OTOH, replication-origin migration itself is supported for PG16
> upgrades. For PG16- upgrades (without this patch), subscriptions
> itself can be migrated, and corresponding origins can be created at
> that time. Therefore, even on versions prior to Pg17, it may also be
> reasonable to consider preserving origin IDs independently of the rest
> of the logical-replication configuration migration, and not tie it to
> the PG17 boundary.
>
> If we choose that approach, check_new_cluster_replication_origins()
> would likely need to run for upgrades from PG16 (and prior) as well.
> Subscription-ids also need to be preserved for the same versions. For
> reference, check_new_cluster_replication_slots() and
> check_new_cluster_subscription_configuration() currently run only for
> PG17 and later.
> ~~
>
> Given the need for a new user-visible parameter, I would rule out
> option 1. Between options 2 and 3, I prefer option 2, but I would be
> interested in hearing others' opinions.
>

I'd prefer option-3 (preserve origin IDs uniformly, including upgrades
from PG16), for two reasons. (a) First, the new-cluster check ("reject
if the new cluster already has replication origins") is a restriction
on the target, and adding restrictions on a newer target version
regardless of source version is well within how pg_upgrade already
behaves. In practice the new cluster is a fresh initdb with no
origins, so the check effectively never fires; the only scenario it
rejects is one where the user manually created subscriptions/origins
on the new cluster before upgrading, which we discourage for other
object types anyway. So I don't think preserving existing behavior
here is worth much. (b) Second, option-2 reintroduces source-version
branching at dump time (the skip_subs_origin_creation flag gated on
source >= 17). Since pg_commit_ts is only copied from PG19+, the exact
roident value only matters from PG19; for PG16-18 the value is
don't-care, so preserving it everywhere is harmless where it isn't
needed and required where it is. That lets us keep a single
always-preserve path instead of branching per source version.

Separately, I don't think we actually need to preserve the
subscription OID to meet the goal here. pg_commit_ts stores the
numeric roident, not the origin name or the sub OID, and conflict
detection compares roidents. So the invariant we must keep is "each
subscription owns the same roident after upgrade", which doesn't
depend on the name being stable.

--
With Regards,
Amit Kapila.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Dilip Kumar 2026-06-15 11:56:48 Re: Proposal: Conflict log history table for Logical Replication
Previous Message Nisha Moond 2026-06-15 11:30:50 Re: Support EXCEPT for TABLES IN SCHEMA publications