public inbox for [email protected]  
help / color / mirror / Atom feed
From: Dilip Kumar <[email protected]>
To: Amit Kapila <[email protected]>
Cc: Nisha Moond <[email protected]>
Cc: vignesh C <[email protected]>
Cc: Peter Smith <[email protected]>
Cc: shveta malik <[email protected]>
Cc: Masahiko Sawada <[email protected]>
Cc: Bharath Rupireddy <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Cc: shveta malik <[email protected]>
Subject: Re: Proposal: Conflict log history table for Logical Replication
Date: Sat, 30 May 2026 06:01:05 +0530
Message-ID: <CAFiTN-u5pcgAhXyJgj+p7-xmShtp0i8xA000tzjCLFQp_zMXUA@mail.gmail.com> (raw)
In-Reply-To: <CAFiTN-sx=k+Th=uYsrLcS6YMZbPVi9Wrggn1w2Nzf9MLEU7YRQ@mail.gmail.com>
References: <CAFiTN-u5D5o_AGNbHRZHaOqAMWkxLf+hSk_r9X3gv6HbLOB5+g@mail.gmail.com>
	<CALj2ACViThGQDYi-yeqUeHqG2Pozn2AiyvtDtjE6zhhbM0KsEA@mail.gmail.com>
	<CAA4eK1+44b3vd_OWfiaVNtjf5Njb5cek09pmKRmttBByeg0NoA@mail.gmail.com>
	<CAFiTN-v3L0WacCDx5dkOSonaZQbJfstXL4HrCPD1ahRdUsRnSg@mail.gmail.com>
	<CALj2ACW63uuxh0fSoxEAF8OMWhz1dJKSkp268WJDzf5BUqCf5g@mail.gmail.com>
	<CAFiTN-s9WWLOhW1TO27NtJwGf0bh2+MWyp3NEkZFeN_S5_p_rA@mail.gmail.com>
	<CAA4eK1LxnsEx5sMbQkK5MHAgXKPROMQXQ0n=fKMwz+UsfKQaMQ@mail.gmail.com>
	<CAD21AoDj+c4LXf2y4ESR-gVyv9d8V0G4R8R9pn-PcmT5zPzYcg@mail.gmail.com>
	<CAA4eK1KokmAwNOL6bS-ip_E3F96PiQTjC4j-M+5vD1T6uUyi3Q@mail.gmail.com>
	<CAFiTN-vFKE8E_N6h+peX9DP92mxCeFdm5A9Esn4DkLmNcZ-dOA@mail.gmail.com>
	<CAFiTN-shLYf-fOTQ_dBf3Xfx05gxs_8d93MHZXyyz6w2Bg5geQ@mail.gmail.com>
	<CAFiTN-tEgkKQHUikn6iBFCYf7XOObR7ncUq=OVh7WEk=6P4ymw@mail.gmail.com>
	<CAFiTN-tQiakd8m+-d6WN6RpJXSv_JcropZ2oGzme4d1JudQhYg@mail.gmail.com>
	<CAJpy0uDKbYWt+YPADj=4fHEvrGEWgnG1n_YsiGT_EZiZf0VSAw@mail.gmail.com>
	<CAFiTN-t82BiXen+HfdR9jZyOpuSO92xonnUK=khXsiZWBfOxMA@mail.gmail.com>
	<CAJpy0uAu2paxGAEffD=vaBTW9Jqbtxxawb8K8FgiASfeKPnGog@mail.gmail.com>
	<CAJpy0uC0ZWgHOivJ102A1fMkppwK3RuSMafRPKyjwkmJrjhVUw@mail.gmail.com>
	<CAFiTN-vFV9-zajrwjYHYyFnyQsooOAXW4CpxB5f-iT3APjOtoQ@mail.gmail.com>
	<CAJpy0uBeU1dZgaqsSVKc=P=EVUKxRgVuHR8jDXFL-HLibbE-kQ@mail.gmail.com>
	<CAA4eK1+FOkOxhzVLAnDymoNjp4i98H-L1+ZsWDgJEv-ndnTzTA@mail.gmail.com>
	<CAFiTN-sVK6Bp+BawCJU_WpAXQSTX4OkKmce5EE4YNBgD-XSjZw@mail.gmail.com>
	<CAA4eK1LbjV0bctib9wUnBpEkC+2rZFPnGuRtrKuc5AtUAzum+A@mail.gmail.com>
	<CAFiTN-vq50N3QP9p3_SH+tJ8Pn=uRDb0X4qEcQZYcGW9AX88rQ@mail.gmail.com>
	<CAFiTN-u3+zRGPESP5kUUfa6NxaWh1HL-gd1225KJ0Uvzi1urow@mail.gmail.com>
	<CAA4eK1L4iNk6mNTC83PbYrRfUdtivH4U961PkdFfOO7mvc=USg@mail.gmail.com>
	<CAFiTN-v+Mh64UfR5zb5rwgyGm6HS80XRSZ_XeaWkg8=+s9o3Kg@mail.gmail.com>
	<CAFiTN-s3ZFHteQsiC3H4=AjTWxuwN-w69XQ3xL5X6YOMTua4pA@mail.gmail.com>
	<CAJpy0uDe724nY59j-8hMapZ_Fru1Wo-NucF4Ea1B3Jrw=+J+UQ@mail.gmail.com>
	<CAFiTN-uR=86L_5tyiA7n73EXCSCuDfQKfL5O=c8n7zZom8_ONQ@mail.gmail.com>
	<CAD21AoDfOS-J0M9WbM3D20eGbSPzbfLQ-9XoYkxO4AZ9twqyvg@mail.gmail.com>
	<CAFiTN-vMTg2X7vwfHLr5Gvy8ViV63_iaEcpHmM8V5GpA9-u8cg@mail.gmail.com>
	<CAA4eK1+b2Ws0e_ZYJsgZAPn7VWndxAK_YM_QMKcfXst3e7F6Jg@mail.gmail.com>
	<CAFiTN-v6hFKMPrSyTBsz=AtEETYMbOxrqvhZJsPQqKgQc4WCLw@mail.gmail.com>
	<CAA4eK1KV3rYkaxys5fh-PtE9kq5xrFbiaRpOSPoRgQG494ek+g@mail.gmail.com>
	<CAFiTN-utvu=QjY1QQ1a_TvkpkpvesMWo9M8wTFYLaOTPdpOJvw@mail.gmail.com>
	<CAA4eK1+HoSOEqNwT3twArPNx4_D7hSUoEg2LnYhX8n9iUwhXgQ@mail.gmail.com>
	<CAFiTN-tqmsfW0Sk=1RhzuduxqLrf9KEc8VOvBae+4aYxWTJwuA@mail.gmail.com>
	<CAA4eK1JmCQ=DHe3HsqpX+P3mGDUd_Z7E7oAxdstK6822W6tuCw@mail.gmail.com>
	<CAFiTN-uE4eAUYewuq3c5deAt3TtVork+H6rkUHRv68cOGr5rmQ@mail.gmail.com>
	<CAFiTN-sJbhPX+LbA8YuQeYJpfGA2XA+OKXf8jCm04RoJOyzLvw@mail.gmail.com>
	<CAJpy0uBPOyWj9itFjHzGXfrUuYS8KGmAvgdcV_9FPjWZ0EZz_w@mail.gmail.com>
	<CAFiTN-s=iLE4qM4qmw9yXKqW09R_c_HqaSGeZXJ2EaTVfXss+g@mail.gmail.com>
	<CAA4eK1KYo0vZpPSRc_4gVpa06-J39gxjs3tHFyckgkBfYJSfFA@mail.gmail.com>
	<CAFiTN-vrKc6OWzrg6yvpwYcj79k=zkrDp3uwiZzjwrWLJAq6tw@mail.gmail.com>
	<CAA4eK1LmvrfEgn1NUZZ=E3yMCjQdNZ5=_SBEry73-EmF6jM_PQ@mail.gmail.com>
	<CAFiTN-vjfub5b3PqPQzfOw9BSjm8jt28ott+Hoz9CrRxJHzYkg@mail.gmail.com>
	<CAFiTN-v=ANapYvRK+SOy2wJb4CSuD6Vb6_bTGuReM9Dv+3tucA@mail.gmail.com>
	<CALDaNm1zEYoSdf2Ns-=UJRw95E5sbfpB0oaNUWtRJN27Q1Knhw@mail.gmail.com>
	<CALDaNm3USsXVNBsfdpkp60HVgrTV4taWMk1xZYNBa7QUF=V0jg@mail.gmail.com>
	<CAFiTN-sNg9ghLNkB2Kn0SwBGOub9acc99XZZU_d5NAcyW-yrEg@mail.gmail.com>
	<CAJpy0uAF3EYcYdpTHdKMeXfvaPbNvnWrZUATrSLL1hqjao=33A@mail.gmail.com>
	<CAFiTN-uikggCKp2LscTorKY5d3KF9j93DW0xebDcRX86G+ZsSw@mail.gmail.com>
	<CAJpy0uDaOoVK8S3_xxTAcTDpfK1AY7tApw7nPOZG_gUz+DMi=Q@mail.gmail.com>
	<CAA4eK1+AdeC5B9xrAXSKWGtTh-0d8xdD=fZttmOBm+c8o8thAQ@mail.gmail.com>
	<CAFiTN-skBQAeuzuUd+PDK0Gqc8g+4x9ypBMwJhOrmW8ZCFKGSA@mail.gmail.com>
	<CAJpy0uCdrsW5T+okq7xTOVxagje7FW3DOeY5B0CGKYa5VqF_tQ@mail.gmail.com>
	<CAFiTN-u+_mFj9caYYFO7=_YHFXk5y=vvOm2H2=5hctYktmAVGA@mail.gmail.com>
	<CALDaNm1aivk9KgQ5daeF6YZzuE+0wWc2yb7wb6qikNyvfPN0Sg@mail.gmail.com>
	<CAJpy0uD6fTEUYJx3+yDbvB=VW7c5AaGoeSd7iwHdYYO=kYGn3g@mail.gmail.com>
	<CALDaNm2YOOdJ25X1sJ+DYz37K6Qi4g0ZNFHb_pQMF9UqancnEA@mail.gmail.com>
	<CAHut+PtMS5bENS0DVtBj+s3kUEOq61+hSkqLODjFB78egB0imQ@mail.gmail.com>
	<CAFiTN-s_M83sfs+MHHbUrMesjsCPN4JWxY5MChCEiY1U-u7=9g@mail.gmail.com>
	<CAFiTN-vj8NTm9w_L2XdhxJCub_RZw__YVUgfXa1B1kJzJctRNw@mail.gmail.com>
	<CAJpy0uBDLnfhuSiev8W9ZMFNTzUmqhds2dKayUpLoN-z1dtsLA@mail.gmail.com>
	<CAFiTN-uL9f0X+=Ep4BbAPvaTJA7S4XHM--G4BsnPJw4uJW7EGQ@mail.gmail.com>
	<CAJpy0uDG=t-y_m8t1zpBzfz9viP3K8dyQgkruaraVT85UtTkrg@mail.gmail.com>
	<CAFiTN-tR8Rhs8uhfbck0Ac4dd1MopvvYgjK39nWyNXRp9Z3Qww@mail.gmail.com>
	<CAA4eK1Kf15UpNmpTTE2XyX=9PE_oTpOoy5xqg3rFWbxwwP4Rbg@mail.gmail.com>
	<CAFiTN-tNqb0vjuadDz-as67ksSXa=aEK+JW=4b54RVmkUK1m2Q@mail.gmail.com>
	<CAFiTN-vDCxx6ydUFo59L8qNBbierg4as3TGPPiavR7UZjYurzA@mail.gmail.com>
	<CAHut+PsWms218ENALnytLEV4NpxjOrAYhChLDaMaeE65-vNgrQ@mail.gmail.com>
	<CAFiTN-v9i9RmDvdUmtMUow4=b+nr0k7LKMyEQ+6ZF=EVdfBhBA@mail.gmail.com>
	<CALDaNm2YTKwPDjt9OV49RgM0zbkWhMhNu228bj_7f+zzcPb-ew@mail.gmail.com>
	<CAFiTN-t_4XvofM3an-WmykqnPE+9wf9U+o2M7p1CWd9eXkN88Q@mail.gmail.com>
	<CAHut+PuaqNDfDu_3xkZR4OYxw-B7ew_WjpLXCBvMcSBJz2K6Xg@mail.gmail.com>
	<CAFiTN-uqNN9S_hRuda_th5MEpywa15g+XO00yM6tNJ-spGRRJw@mail.gmail.com>
	<CABdArM6QxXatkGefTHy__HgaYHBvbKesffeXzT8Vn-kvcvGK4w@mail.gmail.com>
	<CAFiTN-tgMWr=TGPhs9BxaPuSC_jhM7sJJ4fHedE5W6=h40jLfA@mail.gmail.com>
	<CABdArM5fgzfyC2mH3YGB8t8cJBHWqAG1BS6rJMk7mX-8=9d=Cg@mail.gmail.com>
	<CABdArM568KF4WXdFX_aZkCiDK8R71Wpep0gC2a+cV8BMobwkrg@mail.gmail.com>
	<CAFiTN-vQ0tu18BD3UmKPb0rzZyFMQAVgGbdpMA8iYLX7PZOqOA@mail.gmail.com>
	<CALDaNm20PDtmG2E3qaTC+YuL5twv+c9k573wL3sb=OwgmZphxQ@mail.gmail.com>
	<CAA4eK1LhOHa_TEznw+gFoq+w0vMvvsDG2g9Xq8Mwa8xZMY73og@mail.gmail.com>
	<CAFiTN-vPDqrQ2rHykNgd+groFxqwBYFQF97R-Co2EmtUkV6MTg@mail.gmail.com>
	<CAFiTN-vsd=wNiEPXPQhZnipAb--+mBUC01M-pcjBjbRockgCUA@mail.gmail.com>
	<CAJpy0uCjSq_gUCJBfURhqtB6bLvkKSUL-sVXpaGKjEapv5+t+Q@mail.gmail.com>
	<CAFiTN-uZ-LaStAY3NuCY-nb7GCB9joiHX7HtHEMseJ0xfnqVSg@mail.gmail.com>
	<CAFiTN-vhJxRW5NQ628oidnk0KtHwKt11dW9-+vxqpXLTgjiYiA@mail.gmail.com>
	<CALDaNm1cJURibYKY4+DuNosjM72C9oGheUF-roMyff__+AsKBw@mail.gmail.com>
	<CAJpy0uD1_77TDAFc4jE-94X-WUus7Q3gGU0pXfC+Tticq1hFvA@mail.gmail.com>
	<CAA4eK1LFcSc4XCj4mU-cv27F_6n6=+ehJ=YAsAnyBbz4Sv_tVg@mail.gmail.com>
	<CAFiTN-s5ZtjXKrSbam7TNWJ9Ax-kCancXcestAnx2by7dK0-UA@mail.gmail.com>
	<CAFiTN-u=Da32mXyz8jocEGtuLSG4ccXXj_aEzUTPp2zkLb3MVA@mail.gmail.com>
	<CALDaNm1qY5e0thfsDB2uWXqZn4hgTWTxiUDwcF1hWA-jodsKYg@mail.gmail.com>
	<CALDaNm1nFtv3dtdRdbqWo2Rf_av7XbxDfK1Orqjcqs_Su_cLRQ@mail.gmail.com>
	<CABdArM7R498qC5Fr42aU_q-2Sc5QsT4dyKgmO_f6Uy=8oCAFXA@mail.gmail.com>
	<CAFiTN-sRZ+Z_9B3ue2L4zkbcfmPjjcAjcR1C+px1PyAs+HGsSg@mail.gmail.com>
	<CAFiTN-sdcjf9xJ2M-=ab5e4y662tTmFFiP4gHL44tC9PcQozcw@mail.gmail.com>
	<CALDaNm2WNjaNxUijVkvT6y69D62rfCu8OMwU-Pf-84un2r_=ig@mail.gmail.com>
	<CAHut+PvEP5uUR13xJ3gbNKGU49=Rg32DXMGZ2wL9jTcKHyN_=Q@mail.gmail.com>
	<CALDaNm3Jb5AQTsFJFxYZZJCaheT7qToCZkEALfW-vsMMFxjOyQ@mail.gmail.com>
	<CAHut+PtQn5U9i00qvBmjo0KBxyb+ZmBb38NzF91KnX4J86Jg_g@mail.gmail.com>
	<CALDaNm1a1gzy0L38U394_4OFwGUS8ALgSONYj++VLimY0g9piQ@mail.gmail.com>
	<CABdArM5X63AdtS99QKGjVijUd_Q_dV8QUDSo4nTHKJjn3JwtAg@mail.gmail.com>
	<CAA4eK1+h=QV4Zi=PW8Zt2D6be5ki5Mu2HgdXcfUophptx6Mt_A@mail.gmail.com>
	<CAFiTN-s-tuxar9Dp5He0CFa1pzfy1fmiwcBj6PtwD0hDodE5ng@mail.gmail.com>
	<CAFiTN-sx=k+Th=uYsrLcS6YMZbPVi9Wrggn1w2Nzf9MLEU7YRQ@mail.gmail.com>

On Sat, May 30, 2026 at 3:36 AM Dilip Kumar <[email protected]> wrote:
>
> On Sat, May 30, 2026 at 3:24 AM Dilip Kumar <[email protected]> wrote:
> >
> > On Fri, May 29, 2026 at 5:11 AM Amit Kapila <[email protected]> wrote:
> > >
> > > On Thu, May 21, 2026 at 9:51 PM Nisha Moond <[email protected]> wrote:
> > > >
> > > > On Wed, May 20, 2026 at 3:05 PM vignesh C <[email protected]> wrote:
> > > > >
> > > > > Rest of the comments were fixed.
> > > > > The attached v37 version patch has the changes for the same. Also
> > > > > Peter's comments on the documentation patch from [1] and Shveta's
> > > > > comments from [2] are addressed in the attached patch.
> > > > >
> > > >
> > > > Here are few comments based on v37 testing:
> > > >
> > > > 1) Should we consider using TOAST tables for tuple-data columns like
> > > > remote_tuple and local_conflicts (the JSON columns)?
> > > > This may be a corner case, but if the tuple data becomes too large to
> > > > fit into an 8KB heap tuple, then the apply worker keeps failing while
> > > > inserting into the CLT with errors like:
> > > >
> > > >   ERROR: row is too big: size 19496, maximum size 8160
> > > >   LOG: background worker "logical replication apply worker" (PID
> > > > 41226) exited with exit code 1
> > > >
> > >
> > > In the docs, it is mentioned: "column_value is the column value. The
> > > large column values are truncated to 64 bytes." [1], so I wonder, if
> > > we follow this why we need toast entries? Did you tried any case where
> > > you are getting above ERROR?
> >
> > But in this case we are talking about the JSON column of the CLT which
> > might contain a full local tuple or even multiple local tuples if a
> > remote tuple conflicts with multiple local rows.  So, IMHO, we need a
> > toast table. Nisha, have you already tested the scenario? If yes, can
> > you share your test case?
>
> After putting more thought, I think instead of executing a three-step
> process i.e. inserting the pg_subscription tuple, creating the table
> with its dependency, and then going back to update the tuple with the
> new relation ID, it is much cleaner to do it linearly, i.e. we should
> create the conflict log table first to get its OID, insert the
> subscription tuple pre-populated with that ID, and then record the
> dependency. This achieves the exact same state in a single direct
> sequence without the redundant catalog update within the same command.
> I agree with that code we would have to keep the record dependency
> code in CreateSubscription and AlterSubscription functions, but after
> putting more thought I think in thoese function we are already
> recording subscription dependencies with other object so wouldn't it
> be more natural to add this depednecy as well at the same place?
>
> Anyway I am ready to change that if we have strong opinion against
> this approach.
>
> Here is the updated patch and changes are
> 1. 0003 and 0004 are merged on 0001
> 2. Merged Amit's v41_amit_1.patch.txt to 0002
> 3. Fix the dependency order issue (i.e. create dependency after
> inserting subscription tuple) and merged in 0002
>
> Open Items:
> 1. Need to create toast table for CLT after testing with larger JSON row
> 2. Fixed review comments of Shveta on 0004 and 0005
> 3.  Rebase Vignesh's patch of
> "v41-0007-Preserve-conflict-log-destination-and-subscripti" I think we
> can do that once we have concensus on whether to create conflict log
> table first or insert the subscription row first as based on this
> change we would have to rebase this patch again.
> 4. Once we rebase
> "v41-0007-Preserve-conflict-log-destination-and-subscripti" after
> dependency order consensus I would rebase doc patch and \dRs+ change
> patch of Vignesh.

Here is a topup patch so create conflict log table after inserting
subscription tuple and then update the tuple with clt relid..

Main changes will look like this[1]

[1]
/*
* If logging to a table is required, physically create it now. We create
* the conflict log table here. Also update the pg_subscription row
* after creating the conflict log table with its reloid.
*/
if (CONFLICTS_LOGGED_TO_TABLE(opts.conflictlogdest))
{
bool replaces[Natts_pg_subscription];
Oid logrelid =
create_conflict_log_table(subid, stmt->subname, owner);

/* Form a new tuple. */
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
memset(replaces, false, sizeof(replaces));

values[Anum_pg_subscription_subconflictlogrelid - 1] =
ObjectIdGetDatum(logrelid);
replaces[Anum_pg_subscription_subconflictlogrelid - 1] =
true;

/* Make subscription tuple visible before updating it. */
CommandCounterIncrement();

tup = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls,
replaces);

CatalogTupleUpdate(rel, &tup->t_self, tup);
}


-- 
Regards,
Dilip Kumar
Google

From a8e1329bb58436b44d4f0daadc5240daebd39bae Mon Sep 17 00:00:00 2001
From: Dilip Kumar <[email protected]>
Date: Sat, 30 May 2026 05:33:21 +0530
Subject: [PATCH v42] Create conflict log table after inserting subscription
 row

---
 src/backend/commands/subscriptioncmds.c    | 73 ++++++++++------------
 src/backend/replication/logical/conflict.c | 17 +++++
 2 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 88f22bbb286..67311a65e29 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -651,7 +651,6 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 	uint32		supported_opts;
 	SubOpts		opts = {0};
 	AclResult	aclresult;
-	Oid			logrelid = InvalidOid;
 
 	/*
 	 * Parse and check options.
@@ -844,22 +843,45 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 	values[Anum_pg_subscription_subconflictlogdest - 1] =
 		CStringGetTextDatum(ConflictLogDestNames[opts.conflictlogdest]);
 
+	values[Anum_pg_subscription_subconflictlogrelid - 1] =
+									ObjectIdGetDatum(InvalidOid);
+
+	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
+
+	/* Insert tuple into catalog. */
+	CatalogTupleInsert(rel, tup);
+	//heap_freetuple(tup);
+
 	/*
 	 * If logging to a table is required, physically create it now. We create
-	 * the conflict log table here so its relation OID can be stored when
-	 * inserting the pg_subscription tuple below.
+	 * the conflict log table here.  Also update the pg_subscription row
+	 * after creating the conflict log table with its reloid.
 	 */
 	if (CONFLICTS_LOGGED_TO_TABLE(opts.conflictlogdest))
-		logrelid = create_conflict_log_table(subid, stmt->subname, owner);
+	{
+		bool		replaces[Natts_pg_subscription];
+		Oid			logrelid =
+				create_conflict_log_table(subid, stmt->subname, owner);
 
-	/* Store table OID in the catalog. */
-	values[Anum_pg_subscription_subconflictlogrelid - 1] =
-						ObjectIdGetDatum(logrelid);
+		/* Form a new tuple. */
+		memset(values, 0, sizeof(values));
+		memset(nulls, false, sizeof(nulls));
+		memset(replaces, false, sizeof(replaces));
 
-	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
+		values[Anum_pg_subscription_subconflictlogrelid - 1] =
+									ObjectIdGetDatum(logrelid);
+		replaces[Anum_pg_subscription_subconflictlogrelid - 1] =
+									true;
+
+		/* Make subscription tuple visible before updating it. */
+		CommandCounterIncrement();
+
+		tup = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls,
+								replaces);
+
+		CatalogTupleUpdate(rel, &tup->t_self, tup);
+	}
 
-	/* Insert tuple into catalog. */
-	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	recordDependencyOnOwner(SubscriptionRelationId, subid, owner);
@@ -876,25 +898,6 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
 	}
 
-	/*
-	 * If conflicts are logs to table establish an internal dependency
-	 * between the conflict log table and the subscription.
-	 *
-	 * We use DEPENDENCY_INTERNAL to signify that the table's lifecycle is
-	 * strictly tied to the subscription, similar to how a TOAST table relates
-	 * to its main table or a sequence relates to an identity column.
-	 *
-	 * This ensures the conflict log table is automatically reaped during a
-	 * DROP SUBSCRIPTION via performDeletion().
-	 */
-	if (CONFLICTS_LOGGED_TO_TABLE(opts.conflictlogdest))
-	{
-		ObjectAddress clt;
-
-		ObjectAddressSet(clt, RelationRelationId, logrelid);
-		recordDependencyOn(&clt, &myself, DEPENDENCY_INTERNAL);
-	}
-
 	/*
 	 * A replication origin is currently created for all subscriptions,
 	 * including those that only contain sequences or are otherwise empty.
@@ -1507,20 +1510,8 @@ alter_sub_conflictlogdestination(Subscription *sub, ConflictLogDest logdest,
 		/* There was no previous conflict log table. */
 		if (want_table)
 		{
-			ObjectAddress clt;
-			ObjectAddress subobj;
-
 			relid = create_conflict_log_table(sub->oid, sub->name, sub->owner);
 			update_relid = true;
-
-			/*
-			 * Establish an internal dependency between the conflict log table
-			 * and the subscription.  For details refer comments in
-			 * CreateSubscription function.
-			 */
-			ObjectAddressSet(clt, RelationRelationId, relid);
-			ObjectAddressSet(subobj, SubscriptionRelationId, sub->oid);
-			recordDependencyOn(&clt, &subobj, DEPENDENCY_INTERNAL);
 		}
 	}
 
diff --git a/src/backend/replication/logical/conflict.c b/src/backend/replication/logical/conflict.c
index 15b0ef7f3ca..0f077b28678 100644
--- a/src/backend/replication/logical/conflict.c
+++ b/src/backend/replication/logical/conflict.c
@@ -175,6 +175,8 @@ create_conflict_log_table(Oid subid, char *subname, Oid subowner)
 {
 	TupleDesc	tupdesc;
 	Oid			relid;
+	ObjectAddress	myself;
+	ObjectAddress	subaddr;
 	char    	relname[NAMEDATALEN];
 
 	snprintf(relname, NAMEDATALEN, "pg_conflict_log_for_subid_%u", subid);
@@ -218,6 +220,21 @@ create_conflict_log_table(Oid subid, char *subname, Oid subowner)
 									 NULL); /* typaddress */
 	Assert(OidIsValid(relid));
 
+	/*
+	 * Establish an internal dependency between the conflict log table and
+	 * the subscription.
+	 *
+	 * We use DEPENDENCY_INTERNAL to signify that the table's lifecycle is
+	 * strictly tied to the subscription, similar to how a TOAST table relates
+	 * to its main table or a sequence relates to an identity column.
+	 *
+	 * This ensures the conflict log table is automatically reaped during a
+	 * DROP SUBSCRIPTION via performDeletion().
+	 */
+	ObjectAddressSet(myself, RelationRelationId, relid);
+	ObjectAddressSet(subaddr, SubscriptionRelationId, subid);
+	recordDependencyOn(&myself, &subaddr, DEPENDENCY_INTERNAL);
+
 	/* Release tuple descriptor memory. */
 	FreeTupleDesc(tupdesc);
 
-- 
2.49.0



Attachments:

  [text/plain] v42-topup-Create-conflict-log-table-after-inserting-subscr.patch.txt (5.8K, 2-v42-topup-Create-conflict-log-table-after-inserting-subscr.patch.txt)
  download | inline diff:
From a8e1329bb58436b44d4f0daadc5240daebd39bae Mon Sep 17 00:00:00 2001
From: Dilip Kumar <[email protected]>
Date: Sat, 30 May 2026 05:33:21 +0530
Subject: [PATCH v42] Create conflict log table after inserting subscription
 row

---
 src/backend/commands/subscriptioncmds.c    | 73 ++++++++++------------
 src/backend/replication/logical/conflict.c | 17 +++++
 2 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 88f22bbb286..67311a65e29 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -651,7 +651,6 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 	uint32		supported_opts;
 	SubOpts		opts = {0};
 	AclResult	aclresult;
-	Oid			logrelid = InvalidOid;
 
 	/*
 	 * Parse and check options.
@@ -844,22 +843,45 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 	values[Anum_pg_subscription_subconflictlogdest - 1] =
 		CStringGetTextDatum(ConflictLogDestNames[opts.conflictlogdest]);
 
+	values[Anum_pg_subscription_subconflictlogrelid - 1] =
+									ObjectIdGetDatum(InvalidOid);
+
+	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
+
+	/* Insert tuple into catalog. */
+	CatalogTupleInsert(rel, tup);
+	//heap_freetuple(tup);
+
 	/*
 	 * If logging to a table is required, physically create it now. We create
-	 * the conflict log table here so its relation OID can be stored when
-	 * inserting the pg_subscription tuple below.
+	 * the conflict log table here.  Also update the pg_subscription row
+	 * after creating the conflict log table with its reloid.
 	 */
 	if (CONFLICTS_LOGGED_TO_TABLE(opts.conflictlogdest))
-		logrelid = create_conflict_log_table(subid, stmt->subname, owner);
+	{
+		bool		replaces[Natts_pg_subscription];
+		Oid			logrelid =
+				create_conflict_log_table(subid, stmt->subname, owner);
 
-	/* Store table OID in the catalog. */
-	values[Anum_pg_subscription_subconflictlogrelid - 1] =
-						ObjectIdGetDatum(logrelid);
+		/* Form a new tuple. */
+		memset(values, 0, sizeof(values));
+		memset(nulls, false, sizeof(nulls));
+		memset(replaces, false, sizeof(replaces));
 
-	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
+		values[Anum_pg_subscription_subconflictlogrelid - 1] =
+									ObjectIdGetDatum(logrelid);
+		replaces[Anum_pg_subscription_subconflictlogrelid - 1] =
+									true;
+
+		/* Make subscription tuple visible before updating it. */
+		CommandCounterIncrement();
+
+		tup = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls,
+								replaces);
+
+		CatalogTupleUpdate(rel, &tup->t_self, tup);
+	}
 
-	/* Insert tuple into catalog. */
-	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	recordDependencyOnOwner(SubscriptionRelationId, subid, owner);
@@ -876,25 +898,6 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
 	}
 
-	/*
-	 * If conflicts are logs to table establish an internal dependency
-	 * between the conflict log table and the subscription.
-	 *
-	 * We use DEPENDENCY_INTERNAL to signify that the table's lifecycle is
-	 * strictly tied to the subscription, similar to how a TOAST table relates
-	 * to its main table or a sequence relates to an identity column.
-	 *
-	 * This ensures the conflict log table is automatically reaped during a
-	 * DROP SUBSCRIPTION via performDeletion().
-	 */
-	if (CONFLICTS_LOGGED_TO_TABLE(opts.conflictlogdest))
-	{
-		ObjectAddress clt;
-
-		ObjectAddressSet(clt, RelationRelationId, logrelid);
-		recordDependencyOn(&clt, &myself, DEPENDENCY_INTERNAL);
-	}
-
 	/*
 	 * A replication origin is currently created for all subscriptions,
 	 * including those that only contain sequences or are otherwise empty.
@@ -1507,20 +1510,8 @@ alter_sub_conflictlogdestination(Subscription *sub, ConflictLogDest logdest,
 		/* There was no previous conflict log table. */
 		if (want_table)
 		{
-			ObjectAddress clt;
-			ObjectAddress subobj;
-
 			relid = create_conflict_log_table(sub->oid, sub->name, sub->owner);
 			update_relid = true;
-
-			/*
-			 * Establish an internal dependency between the conflict log table
-			 * and the subscription.  For details refer comments in
-			 * CreateSubscription function.
-			 */
-			ObjectAddressSet(clt, RelationRelationId, relid);
-			ObjectAddressSet(subobj, SubscriptionRelationId, sub->oid);
-			recordDependencyOn(&clt, &subobj, DEPENDENCY_INTERNAL);
 		}
 	}
 
diff --git a/src/backend/replication/logical/conflict.c b/src/backend/replication/logical/conflict.c
index 15b0ef7f3ca..0f077b28678 100644
--- a/src/backend/replication/logical/conflict.c
+++ b/src/backend/replication/logical/conflict.c
@@ -175,6 +175,8 @@ create_conflict_log_table(Oid subid, char *subname, Oid subowner)
 {
 	TupleDesc	tupdesc;
 	Oid			relid;
+	ObjectAddress	myself;
+	ObjectAddress	subaddr;
 	char    	relname[NAMEDATALEN];
 
 	snprintf(relname, NAMEDATALEN, "pg_conflict_log_for_subid_%u", subid);
@@ -218,6 +220,21 @@ create_conflict_log_table(Oid subid, char *subname, Oid subowner)
 									 NULL); /* typaddress */
 	Assert(OidIsValid(relid));
 
+	/*
+	 * Establish an internal dependency between the conflict log table and
+	 * the subscription.
+	 *
+	 * We use DEPENDENCY_INTERNAL to signify that the table's lifecycle is
+	 * strictly tied to the subscription, similar to how a TOAST table relates
+	 * to its main table or a sequence relates to an identity column.
+	 *
+	 * This ensures the conflict log table is automatically reaped during a
+	 * DROP SUBSCRIPTION via performDeletion().
+	 */
+	ObjectAddressSet(myself, RelationRelationId, relid);
+	ObjectAddressSet(subaddr, SubscriptionRelationId, subid);
+	recordDependencyOn(&myself, &subaddr, DEPENDENCY_INTERNAL);
+
 	/* Release tuple descriptor memory. */
 	FreeTupleDesc(tupdesc);
 
-- 
2.49.0



reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Proposal: Conflict log history table for Logical Replication
  In-Reply-To: <CAFiTN-u5pcgAhXyJgj+p7-xmShtp0i8xA000tzjCLFQp_zMXUA@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox