Thread

  1. Re: Proposal: Conflict log history table for Logical Replication

    Dilip Kumar <dilipbalaut@gmail.com> — 2025-12-23T06:11:24Z

    On Tue, Dec 23, 2025 at 10:55 AM shveta malik <shveta.malik@gmail.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