Re: Proposal: Conflict log history table for Logical Replication

shveta malik <shveta.malik@gmail.com>

From: shveta malik <shveta.malik@gmail.com>
To: Dilip Kumar <dilipbalaut@gmail.com>
Cc: vignesh C <vignesh21@gmail.com>, Amit Kapila <amit.kapila16@gmail.com>, Nisha Moond <nisha.moond412@gmail.com>, Peter Smith <smithpb2250@gmail.com>, Masahiko Sawada <sawada.mshk@gmail.com>, Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, shveta malik <shveta.malik@gmail.com>
Date: 2026-06-25T06:07:52Z
Lists: pgsql-hackers
Thanks for v56. A few comments:

0001:
1)
+ * We complain if either the old or new namespaces is a temporary schema,
+ * temporary toast schema, the TOAST schema, or the conflict schema.
  */
 void
 CheckSetNamespace(Oid oldNspOid, Oid nspOid)

Shall we remove this comment change now as the check has been removed?

2)
+ /*
+ * Conflict log tables are managed by the system to record logical
+ * replication conflicts.
+ */
+ if (IsConflictLogTableNamespace(RelationGetNamespace(rel)))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot lock rows in the conflict log table \"%s\"",
+ RelationGetRelationName(rel))));

postgres=# SELECT * FROM  pg_conflict.pg_conflict_log_16387 for UPDATE;
ERROR:  cannot lock rows in the conflict log table "pg_conflict_log_16387"

Why don't we add detail-message here as well, similar to all other cases:
errdetail("Conflict log tables are system-managed tables for logical
replication conflicts.")));

patch-0002
3)
+    SELECT 'pg_conflict.' || relname INTO tab_name
+    FROM pg_class c JOIN pg_subscription s ON c.relname =
'pg_conflict_log_' || s.oid
+    WHERE s.subname = 'regress_conflict_protection_test';

This query runs many times (10-15). Can we save the result into
clt_name and use it everywhere? This will reduce test-size.

SELECT 'pg_conflict.' || relname AS clt_name
FROM pg_class c JOIN pg_subscription s ON c.relname =
'pg_conflict_log_' || s.oid
WHERE s.subname = 'regress_conflict_protection_test'
\gset

DO
BEGIN
    EXECUTE 'CREATE TABLE public.conflict_child () INHERITS (' ||
:'clt_name' || ')';
....

DO
BEGIN
    EXECUTE 'ALTER TABLE ' || :'clt_name' || ' RENAME COLUMN relname
TO new_relname';
---

4)
We can also add a test for paritioning along with inheritance:
CREATE TABLE clt_partition PARTITION OF
pg_conflict.pg_conflict_log_16387 FOR VALUES FROM ('2026-01-01') TO
('2027-01-01');

thanks
Shveta



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Allow logical replication conflicts to be logged to a table.

  2. Avoid orphaned objects dependencies