Assertion failure in GetSubscriptionRelations() with concurrent DROP TABLE

From: vignesh C <vignesh21(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Subject: Assertion failure in GetSubscriptionRelations() with concurrent DROP TABLE
Date: 2026-08-24 12:01:11
Message-ID: CALDaNm3eeKocRtQyUPdg2kaxJ-VAo5pwcNytDKNT1Yc0t2V_ug@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I found an issue in GetSubscriptionRelations() when a REFRESH
PUBLICATION is executed while a subscribed relation is dropped
concurrently.

GetSubscriptionRelations() scans pg_subscription_rel using the catalog
snapshot taken when the scan starts, and then looks up the relation's
relkind through the syscache. If the relation is dropped and the drop
commits, the pg_subscription_rel row can still be visible while the
corresponding pg_class row is already gone. In this case,
get_rel_relkind() returns '\0'.

This can be reproduced with the following steps:
I have reproduced it through debugger:
step 1: Prepare logical replication setup for table tbl1,
step 2: session 1: ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; -->
Hold this statement through debugger at GetSubscriptionRelations
function just before get_rel_relkind function call
step 3: session 2: DROP TABLE tbl1; --> Drop the table concurrently
while the session 1 is stopped at GetSubscriptionRelations
step 4: continue the execution to see the Assertion failure.

get_rel_relkind will return '\0' which causes the assertion failure at:
....
relkind = get_rel_relkind(subrel->srrelid);

Assert(relkind == RELKIND_SEQUENCE || relkind == RELKIND_RELATION ||
relkind == RELKIND_PARTITIONED_TABLE);
....

This caused the following assertion to fail in an assert-enabled build:
TRAP: failed Assert("relkind == RELKIND_SEQUENCE || relkind ==
RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE"), File:
"pg_subscription.c", Line: 699, PID: 32422
0 postgres 0x0000000102a47728
ExceptionalCondition + 216
1 postgres 0x00000001022ab850
GetSubscriptionRelations + 484
2 postgres 0x00000001023e52a8
AlterSubscription_refresh + 620

Attached is 0001-Test-to-reproduce-assertion-failure-in.patch, which
adds an injection-point test to reproduce the issue.

The fix is to skip the relation when get_rel_relkind() returns '\0',
since the relation has already been dropped and there is nothing left
to synchronise. The attached
v1-0001-Skip-relations-dropped-concurrently-in-GetSubscri.patch patch
has the fix for the same. This also needs to be fixed in the v19
branch, where get_rel_relkind() was introduced by commit
f0b3573c3aac6c0ea4cbc278f98178516579d370.

Regards,
Vignesh

Attachment Content-Type Size
v1-0001-Skip-relations-dropped-concurrently-in-GetSubscri.patch application/octet-stream 1.4 KB
0001-Test-to-reproduce-assertion-failure-in.patch application/octet-stream 7.7 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2026-08-24 12:25:20 Re: [PATCH] bufmgr: tighten LWLock:BufferMapping on InvalidateBuffer
Previous Message Nisha Moond 2026-08-24 11:38:22 Re: Support EXCEPT for TABLES IN SCHEMA publications