| From: | shveta malik <shveta(dot)malik(at)gmail(dot)com> |
|---|---|
| To: | Ajin Cherian <itsajin(at)gmail(dot)com> |
| Cc: | imchifan8(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, shveta malik <shvetamalik(at)gmail(dot)com> |
| Subject: | Re: BUG #19864: pg_get_publication_tables() gets cache lookup error after concurrent DROP PUBLICATION |
| Date: | 2026-11-13 08:42:17 |
| Message-ID: | CAJpy0uCscfiqdTnZqpCv6rQfsQmbbcjazsFpanqmXmVT9rZsvQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
On Fri, Nov 13, 2026 at 11:58 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> I found one more issue, which looks like an existing bug. The same
> window exists on master with GetPublication(). If the publication is
> dropped after get_publication_internal() has succeeded for the last
> table of the publication, the remaining lookups for that row
> (PUBLICATIONNAMESPACEMAP and PUBLICATIONRELMAP) find no entry, so the
> row is built as if there were no column list and no row filter (all
> columns and a NULL qual). For earlier tables the next row hits the new
> error, but for the last table there is no next row, so the query
> succeeds with a wrong result.
>
> Try with this setup:
> create table tab1(a int, b int, c int);
> create table tab2(a int, b int, c int);
> create table tab3(a int, b int, c int);
> create publication pub for table tab1(a) where (a > 1), tab2(b) where
> (b > 2), tab3(c) where (c > 3);
>
> Run this:
> SELECT * FROM pg_get_publication_tables('pub')
>
> When above query is reading last table tab3, drop the publication
> immediately in another session post get_publication_internal(). You
> will see that the output for 'attrs' and 'qual' is wrong for tab3. It
> gives all columns (1 2 3) and a NULL qual instead of col 3 and (c > 3)
> qual.
>
> While running this, the cache should be cold (the first query in the
> session). With a cold cache, these lookups open the catalogs, which
> processes the drop's invalidation. In an already-warm session/cache,
> the lookups hit the cache and the result is correct.
>
> I think this bug will impact tablesync in a way that it will end up
> syncing tab3 with all columns and all rows and will mark it ready.
>
> Thinking about a potential solution. If the fix is simple enough, we
> can address it in sae ethread, else we can raise a new bug,
I think the fix can be simple for this. When looking up
pg_publication_rel for a table after locking it (for non-ALL TABLES
and non-schema publications), we normally expect to find an entry. If
no entry is found, either the publication was dropped concurrently or
the entry is legitimately absent. For example, when partitions are
published via their parent with publish_via_partition_root = false,
pg_pub_rel contains only the parent, while pg_pub_tables contains the
partitions.
So, after SearchSysCacheCopy2(PUBLICATIONRELMAP, ...), if pubtuple is
invalid, check whether the publication still exists. If it doesn't,
raise the same error (or skip based on pub_missing_ok). If pubtuple is
valid, no further check is needed, since it represents the publication
definition from before the drop.
I have attached the top-up patch for this. It applies atop v3. Let me
know what you think.
thanks
Shveta
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-last-table-fetch-wrong-result-fix.patch | application/octet-stream | 1.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | Laurenz Albe | 2026-11-13 08:21:58 | Re: BUG #19893: REPLICA IDENTITY FULL: UPDATE/DELETE skipped when a subscriber-only column has a value |