Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1whJUG-0009De-0C for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Jul 2026 04:02:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1whJUE-004cp1-1A for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Jul 2026 04:02:15 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1whJUD-004cot-33 for pgsql-hackers@lists.postgresql.org; Wed, 08 Jul 2026 04:02:14 +0000 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1whJUC-000000005pk-28Wh for pgsql-hackers@lists.postgresql.org; Wed, 08 Jul 2026 04:02:13 +0000 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-38125cebfdaso314622a91.1 for ; Tue, 07 Jul 2026 21:02:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1783483332; cv=none; d=google.com; s=arc-20260327; b=MgpOn+5tP76EjHHpogthNUG5OA+M/Y8nU8xM91EfYe/TCZTMDBU8YTKQeu2LPGrsxR T1IVn+Bnwp//5sjeHrrcJxWvbMYPVS+E1l7In4LkcqqeQOjaRVuDJxW/ylKGNa3OyHUk j0xgZSPQ2mf5EH7vvlFl92hlkQVbfh3S+zdKlGCiQElrap7tw1XGIvjjkCFZro3+klVB 6731NFdG3Obs4G/J0Ky5Klsyj4Cfu1eVQDJ7WfsalRwogt1ZgjFeTkCuGE51ZDMnsaIh /NkfShGBcdX038s39kzoKpDB2V+Mzx3exLzIYMyMqaCqrhfsbmEGfCKhiTmdpNEo7SLG e3og== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=Z9usDgdGIooLrbItXWogRIacsokxads/rlKsEsJYd7U=; fh=OZ1UjgOUpL3oV+ia+hQZ/3puEcutZ21qBcPANsSn8ZE=; b=dyPhxN0Cn01VbU7V8BldnZA3ypkX3QwYXsAZFt6BV3Y/Mvo1IJ11INTjaGXCFJj6ZY EJswFO32ALU/LA1L7UV3qXHuYpJkzJjJYmahY8rJNriUswk2v4DOr6cEgs4jfAGOPhJc elEkxhY5mQhVESUvH6vY7VrCwGQNxDyG9qtGjE5n1DXqtGGxJThbgjwTMVGKYLAzAlCd xEA1E3XMKsSv3nb+1jrH7P7We2Lf19ya+SMbRvHKeBCGD3GShXSafSkJYZVnmPTQoQXQ LI/IHDdkP7p4hd3d5jEwr7ymfh6SVcVgCM8dXi1BwnDxrVG42gBWELhUCZE4isiFmPsA b/OA==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783483332; x=1784088132; darn=lists.postgresql.org; h=content-transfer-encoding:content-type:cc:to:subject:message-id :date:from:in-reply-to:references:mime-version:from:to:cc:subject :date:message-id:reply-to:content-type; bh=Z9usDgdGIooLrbItXWogRIacsokxads/rlKsEsJYd7U=; b=mGXmQjmyM+71QfNa8dbZDQMdwITFZbK77kW4evpKFBbEkQ+JTewoR5BC7RUQrhZz9u ltaahfVxVKAXybErc0WrFzoLuuLLfnEQ9gJGMDL1zFzUvsA3Psq7Sw9Lf2Rk3/0ahU06 WO7Kcv8XAoIPdALhCq9Frm5phq4N/UsdHmTO458iLKxGEtXDZcB8kz96PjRUsypMQkS4 n4wtRkO4c5yYzoFRZrDKHu6b7V5Ex5F0qWZf6IDxKNXmoP8VqQx5/gH/qj0OMaUqtR0v TaC+1oDXr4kzVe7xpZbrgmSgFqujYqrhz24Zn9QNX49rG5c0tEnAdA6s47ITH3BLmt+l qLqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783483332; x=1784088132; h=content-transfer-encoding:content-type:cc:to:subject:message-id :date:from:in-reply-to:references:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Z9usDgdGIooLrbItXWogRIacsokxads/rlKsEsJYd7U=; b=GgHtKPynJd0L+xixFaPBkaZp0FhG7GEWM29+mwWmqTszpA0Xf9OiBsmsyWeDzbFY4V OftT0Ai8dGd+p6fOJFB61sVDp+rF2CWEzmS0q1eHdpMQ0+FovyAxG1N7ZCS70Fl8Zt1+ /ykUAxaDPz8ilV00WiZaPk8mMHK2UlIqK1nPpV0PTytk32UscWlzvu336oA+4Dv3OQOX u3XQiAN0SWJhp/CwT9/Grt3f73AZ2RZbfVKcJv79dhKVElffOPTdJwaBYjrhZ67sKWNN 4HFFsmeNO2iDdPxPVKI5m9zTCuyUtw7JnmYyfxPk7FBbyb9+RDW/mb0L2j76YIJOx6nI 4R4A== X-Forwarded-Encrypted: i=1; AHgh+Rowa4uimZf0RtGODluk3LZexVFvwpQEjaNN/tgn9f9ebVXKksbloZXT1lstdm6dS6fGHKEHKKQICnOD9D46@lists.postgresql.org X-Gm-Message-State: AOJu0Yw7BU5VNIpVBy4/93O1bH/ST2dPENsghTiDFTnAzdOi7MYFEfbv fUYqK4rrVWSxSx3W6uhkH7grmJ5n6EJCijxfplHttV5us7xQRScsvgJPVSBXuiIXBbd093oAwot bohfoWW1ROH8oWHgGOs4zBGYREHlS0Ig= X-Gm-Gg: AfdE7cl34Ki87U4dz6pi9Pv38OauYY/Gmtb0VbtAfoDdw7G+8HS6TqQ5UmcN7lC6Hst PwJmOzqDJZyMyu72C5nGeOPh+0/NIAAtz8p4ruq13uwf1Os4daNM326J2Wli84ThMsP5pQ9aJlY HNq2r4RSA74GuL7+v4uEAmPbXYHyxhII/4lcms4849unZDEi7nm2+71GmM3hcO2j0cxvWAYs5YR u8z928jVp1WFyrx0ozmrEMnejalKNTSMrlaosYFd5PedJJC5uskZpLuRFGIR3vmQBqivjnKkih1 /sBFZTi1fsC8AoC/5YAKZM6v/zcoBuoiMYSImBDpknjscGQx8puUHg== X-Received: by 2002:a17:90b:4a11:b0:366:132:fda7 with SMTP id 98e67ed59e1d1-38940150894mr813229a91.10.1783483331881; Tue, 07 Jul 2026 21:02:11 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: shveta malik Date: Wed, 8 Jul 2026 09:31:59 +0530 X-Gm-Features: AVVi8CfK1504jgdnuiMyi4SLfKW_543g1nhxhNkPNe4v-wPi6j83HDO5VsCsNec Message-ID: Subject: Re: [PATCH] Preserve replication origin OIDs in pg_upgrade To: Shlok Kyal Cc: Ajin Cherian , Zsolt Parragi , pgsql-hackers@lists.postgresql.org, shveta malik Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, Jul 6, 2026 at 12:10=E2=80=AFPM Shlok Kyal wrote: > > > All the above changes are updated in patch v10. > > > I noticed that we can create user defined replication origin even if the > total count of replication origins exceeds the max_active_replication_ori= gins > Example: > postgres=3D# show max_active_replication_origins; > max_active_replication_origins > -------------------------------- > 1 > > postgres=3D# select * from pg_replication_origin; > roident | roname > ---------+---------- > 1 | pg_16387 > > postgres=3D# SELECT pg_replication_origin_create('origin1'); > pg_replication_origin_create > ------------------------------ > 2 > > postgres=3D# select * from pg_replication_origin; > roident | roname > ---------+---------- > 1 | pg_16387 > 2 | origin1 > > postgres=3D# select * from pg_replication_origin_status; > local_id | external_id | remote_lsn | local_lsn > ----------+-------------+------------+------------ > 1 | pg_16387 | 0/00000000 | 0/00000000 > > The documentation for max_active_replication_origins says: > ``` > Specifies how many replication origins (see > ) can be tracked simultaneously, > effectively limiting how many logical replication subscriptions can > be created on the server. Setting it to a lower value than the current > number of tracked replication origins (reflected in > pg_replication_origin= _status) > will prevent the server from starting. It defaults to 10. This parameter > can only be set at server start. > ``` > Since the user-created replication origin above is not > actively tracked in pg_replication_origin_status, no error is reported. > > But with this patch, during pg_upgrade we are checking the > 'max_active_replication_origins' against 'old_cluster.nrepl_origins' > + if (old_cluster.nrepl_origins > max_active_replication_origins) > pg_fatal("\"max_active_replication_origins\" (%d) must be greater > than or equal to the number of " > - "subscriptions (%d) in the old cluster", > - max_active_replication_origins, old_cluster.nsubs); > + "replication origins (%d) in the old cluster", > + max_active_replication_origins, old_cluster.nrepl_origins); > > Since old_cluster.nrepl_origins counts all replication origins, including > user-created ones that may not be tracked, should this check instead comp= are > max_active_replication_origins with 'the number of rows in > pg_replication_origin_status in old cluster' (i.e., the number of > tracked replication origins)? > Thanks Shlok for exploring this scenario. I had a look at it. Please find my analysis. I was under the assumption that subscription creation (which internally creates a replication origin) would fail if max_active_replication_origins was exceeded. However, that is not the case. See the following experiment: postgres=3D# show max_active_replication_origins; max_active_replication_origins -------------------------------- 2 Al these commands succeed: postgres=3D# create subscription sub1 ... postgres=3D# create subscription sub2 .. postgres=3D# SELECT pg_replication_origin_create('user_origin1'); postgres=3D# SELECT pg_replication_origin_create('user_origin2'); postgres=3D# SELECT pg_replication_origin_create('user_origin3'); postgres=3D# SELECT pg_replication_origin_create('user_origin4'); postgres=3D# create subscription sub3 .. postgres=3D# create subscription sub4... postgres=3D# select * from pg_replication_origin_status; local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+------------ 1 | pg_16384 | 0/00000000 | 0/00000000 2 | pg_16385 | 0/00000000 | 0/00000000 (2 rows) postgres=3D# select * from pg_replication_origin; roident | roname ---------+-------------- 1 | pg_16384 2 | pg_16385 3 | user_origin1 4 | user_origin2 5 | user_origin3 6 | user_origin4 7 | pg_16387 8 | pg_16388 (8 rows) As shown above, sub3 and sub4 are created successfully, but their replication origins are not tracked because there are no free active replication origin slots. The apply workers for these subscriptions also fail to start: LOG: logical replication apply worker for subscription "sub3" has started ERROR: could not find free replication state slot for replication origin with ID 7 HINT: Increase "max_active_replication_origins" and try again. LOG: background worker "logical replication apply worker" (PID 277193) exited with exit code 1 This means that if we implement the check suggested by Shlok: Although pg_upgrade would succeed, it could leave some subscriptions on the new cluster in non-functional state. I agree that this situation (non-functional subscriptions) is also possible on the old cluster. However, this would also deviate from the previous implementation, where check_new_cluster_subscription_configuration() compared old_cluster.nsubs against 'max_active_replication_origins' on the new cluster, rather than comparing the number of entries in pg_replication_origin_status. For this reason, my inclination is to revert to the previous implementation, where we compare old_cluster.nsubs with max_active_replication_origins. But I'd like to hear what others think before we make this change. thanks Shveta