Re: Per-table resync for logical replication subscriptions

From: Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com>
To: Cagri Biroglu <cagri(dot)biroglu(at)adyen(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Ajin Cherian <itsajin(at)gmail(dot)com>, "smithpb2250(at)gmail(dot)com" <smithpb2250(at)gmail(dot)com>, "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Subject: Re: Per-table resync for logical replication subscriptions
Date: 2026-11-03 12:37:19
Message-ID: CANhcyEW66sNdiie1GdSusUCh1njEbVcC7PkyfFSoh4Yx=GpTtA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, 3 Nov 2026 at 15:24, Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com> wrote:
>
> On Mon, 2 Nov 2026 at 01:35, Cagri Biroglu <cagri(dot)biroglu(at)adyen(dot)com> wrote:
> >
> > Hi Shlok ,
> >
> > thank you , fixed in v13, attached.
> >
> Hi Cagri,
>
> I further reviewed the v13 patch and found that ALTER SUBSCRIPTION ...
> REFRESH TABLE truncates the target table by calling
> ExecuteTruncateGuts(). Consequently, it executes BEFORE TRUNCATE and
> AFTER TRUNCATE statement-level triggers on that table.
> For example we have trigger:
> CREATE TRIGGER t1_truncate_trigger
> AFTER TRUNCATE ON t1
> FOR EACH STATEMENT EXECUTE FUNCTION log_t1_trigger();
>
> And if t1 is part of subscription sub1, 'ALTER SUBSCRIPTION sub1
> REFRESH TABLE t1;' can call the above trigger.
>
> Is this ok to allow triggers to be called when ALTER SUBSCRIPTION ...
> REFRESH TABLE executed?
>
> I checked if any other ALTER SUBSCRIPTION command can execute any
> triggers but I did not find any.
> I noticed that apply workers can execute row-level INSERT, UPDATE, and
> DELETE triggers, and statement-level TRUNCATE triggers, but only when
> the table is configured as ENABLE REPLICA or ENABLE ALWAYS.
> Should we have a similar way for the REFRESH TABLE case as well?
>
I did further testing and was able to hit an Assert.
A BEFORE TRUNCATE trigger can change the session replication origin
while REFRESH TABLE temporarily changes replorigin_xact_state.origin.
AlterSubscription_refresh_table() saves replorigin_xact_state.origin,
assigns the subscription origin while truncating and restores the
saved value afterward. But, the trigger can reset the corresponding
session state. Consequently, the saved origin ID is restored while
session_replication_state remains NULL.

During commit, replorigin_session_advance() can
hit:Assert(session_replication_state != NULL);
I have attached a perl test to reproduce the issue.

Thanks,
Shlok Kyal

Attachment Content-Type Size
test.pl application/octet-stream 2.0 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Manu 2026-11-03 12:48:08 Re: [(known) BUG] DELETE/UPDATE more than one row in partitioned foreign table
Previous Message Dean Rasheed 2026-11-03 12:14:48 Re: SSI: ON CONFLICT DO SELECT takes no predicate lock on the returned row