Re: Proposal: Conflict log history table for Logical Replication

From: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: vignesh C <vignesh21(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Proposal: Conflict log history table for Logical Replication
Date: 2025-12-23 06:11:24
Message-ID: CAFiTN-sRzHHU3JU9_X50y2ERrTEn3cmTCMAoCOX5uwOgkyzWUg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Dec 23, 2025 at 10:55 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> One approach could be to use something similar to
> PERFORM_DELETION_SKIP_EXTENSIONS in our case, but only for recursive
> drops. The effect would be that 'DROP SCHEMA ... CASCADE' would
> proceed without error, i.e., it would drop the tables as well without
> including the subscription in the dependency list. But if we try to
> drop a table directly (e.g., DROP TABLE CLT), it will still result in:
> ERROR: cannot drop table because subscription sub1 requires it
>
> The behavior will resemble a dependency somewhere between type 'n' and
> type 'i'. That said, I’m not sure if this is worth the effort, even
> though it prevents direct drop of table, it still does not prevent
> table from being dropped as part of a schema drop.

Yeah but that would be inconsistent behavior. Anyway here is what I
got with what I was proposing yesterday.[1], so basically drop schema
and drop table are giving the same behavior as expected and drop
subscription is internally dropping the table as we would want.
Although this need more thought to see what else it might break.

postgres[1553010]=# CREATE SCHEMA s1;
postgres[1553010]=# SET search_path TO s1;
postgres[1553010]=# CREATE SUBSCRIPTION sub1 CONNECTION
'dbname=postgres port=5432' PUBLICATION pub WITH
(conflict_log_destination = table);
postgres[1553010]=# \d
List of relations
Schema | Name | Type | Owner
--------+--------------------------+-------+-------------
s1 | conflict_log_table_16428 | table | dilipkumarb
(1 row)

postgres[1553010]=# DROP SCHEMA s1;
ERROR: 2BP01: cannot drop table conflict_log_table_16428 because
subscription sub1 requires it
HINT: You can drop subscription sub1 instead.
LOCATION: findDependentObjects, dependency.c:843

postgres[1553010]=# DROP TABLE conflict_log_table_16428 ;
ERROR: 2BP01: cannot drop table conflict_log_table_16428 because
subscription sub1 requires it
HINT: You can drop subscription sub1 instead.
LOCATION: findDependentObjects, dependency.c:843

postgres[1553010]=# DROP SUBSCRIPTION sub1;
NOTICE: 00000: dropped replication slot
"pg_16428_sync_16385_7586930395971240479" on publisher
LOCATION: ReplicationSlotDropAtPubNode, subscriptioncmds.c:2469
NOTICE: 00000: dropped replication slot "sub1" on publisher
LOCATION: ReplicationSlotDropAtPubNode, subscriptioncmds.c:2469
DROP SUBSCRIPTION

[1]
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 7489bbd5fb3..14184d076d3 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -662,6 +662,11 @@ findDependentObjects(const ObjectAddress *object,
* However, no inconsistency can
result: since we're at outer
* level, there is no object depending
on this one.
*/
+ if
(IsSharedRelation(otherObject.classId) && !(flags &
PERFORM_DELETION_INTERNAL))
+ {
+ owningObject = otherObject;
+ break;
+ }
if (stack == NULL)
{
if (pendingObjects &&

--
Regards,
Dilip Kumar
Google

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message vignesh C 2025-12-23 06:15:48 Re: Proposal: Conflict log history table for Logical Replication
Previous Message Hayato Kuroda (Fujitsu) 2025-12-23 05:55:41 RE: Two issues with version checks in CREATE SUBSCRIPTION