RE: Per-table resync for logical replication subscriptions

From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Cagri Biroglu' <cagri(dot)biroglu(at)adyen(dot)com>
Cc: 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-10-23 06:36:34
Message-ID: OS7PR01MB1831757BF5C212B9E04F7E615F5642@OS7PR01MB18317.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Cagri,

Sorry for the late reply. I have been busy for PG19 open items.

> Rejecting partitioned roots removes only about fifty lines. It does not
> remove the ancestor locking or the ancestor half of the cross-subscription
> check, which are needed when a leaf is the subscribed table, as it is whenever
> publish_via_partition_root is off. Both problems you found here were in that
> code, so it would stay in 0001 and 0002 would add the easy part. I would
> rather keep one patch, but I will split it if you prefer.

I still prefer the separated patch to make review easier.

> thank you. With C -> B -> A and A on origin = none, the same
> copy made CREATE SUBSCRIPTION warn and REFRESH TABLE stay silent.
> check_publications_origin_tables() skips the tables a subscription already
> has, because those come throuqgh WAL where origins are known, and this command
> is the one thing that puts such a table back through a copy. v10 runs the
> check and passes the subscription's other tables as the skip list, so it warns
> for a table another subscription writes and stays quiet otherwise.

Assuming that there is a bidirectional setup A <-> B, and REFRESH TABLE is done
on node A. In this case the TRUNCATE can be replicated to the node B and table
on both nodes are empty. Tuples are lost after the subscription is enabled
because the copy source does not have ones anymore. Isn't it problematic?
Is there a good method to fix?
My primitive idea is to reject REFRESH command if the target tables are included
in a publication.

Below are new comments:
01.
Assuming that there is a cascading replication: A->B->C and origin=any, and the
publication on B does not publish TRUNCATE. If the REFRESH TABLE is done on B,
the TRUNCATE cannot be replicated but the re-synced data can be replicated again,
can cause the data conflict. Should we solve the issue? Rejecting the REFRESH TABLE
on the intermediate node can solve the issue but may be too aggressive.

02.
Assuming the normal logical replication system A->B, and the REFRESH TABLE is
done while the srsubstate is still FINISHCOPY. If the command fails after dropping
the replication origin and replication slot, the tablesync worker will assume
the slot exists and tries to stream via the slot, it can cause the ERROR.

I think we need to clarify that the REFRESH must be done again if it fails.
Or should we reject the case if the table-sync is ongoing?

Best regards,
Hayato Kuroda
FUJITSU LIMITED

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2026-10-23 07:01:00 Re: Proposal: Conflict log history table for Logical Replication
Previous Message Dmitry Fomin 2026-10-23 06:03:08 Re: [PATCH v1 0/7] Wait event timing and tracing instrumentation