From d8a5e11dcc63406c86584cf08abd4f5a3c314605 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Mon, 17 Nov 2025 11:44:55 +0530 Subject: [PATCH v4 3/3] WIP: conflict log table docs --- doc/src/sgml/logical-replication.sgml | 126 +++++++++++++++++++++- doc/src/sgml/ref/alter_subscription.sgml | 11 +- doc/src/sgml/ref/create_subscription.sgml | 19 ++++ 3 files changed, 152 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index d64ed9dc36b..951a9bc0e3c 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -248,7 +248,9 @@ The subscription is added using CREATE SUBSCRIPTION and can be stopped/resumed at any time using the ALTER SUBSCRIPTION command and removed using - DROP SUBSCRIPTION. + DROP SUBSCRIPTION. If a + conflict_log_table was specified for the subscription, that internally + managed table is automatically dropped along with the subscription. @@ -284,6 +286,18 @@ option of CREATE SUBSCRIPTION for details. + + Conflicts that occur during replication are typically logged as plain text + in the server log, which can be difficult for automated monitoring and + analysis. The CREATE SUBSCRIPTION command provides the + conflict_log_table + option to specify a table name where detailed conflict information + is recorded in a structured, queryable format, significantly improving + post-mortem analysis and operational visibility of the replication setup. + This table is created and managed internally by the system and is owned + by the subscription owner. + + Replication Slot Management @@ -1762,7 +1776,9 @@ Publications: Additional logging is triggered, and the conflict statistics are collected (displayed in the pg_stat_subscription_stats view) - in the following conflict cases: + in the following conflict cases (If the subscription was created with the + conflict_log_table option, detailed conflict information is also inserted + into the specified table, providing a structured record of all conflicts). insert_exists @@ -1871,6 +1887,104 @@ Publications: log. + + When the conflict_log_table option is enabled, the system automatically creates + a new table with a predefined schema to log conflict details. This table is created in the + specified schema, is **owned by the subscription owner**, and logs system fields. The schema of this table is + detailed in . + + + + Conflict Log History Table Schema + + + + Column + Type + Description + + + + + relid + oid + The OID of the local table where the conflict occurred. + + + local_xid + xid + The local transaction ID involved in the conflict (NULL if local tuple missing). + + + remote_xid + xid + The remote transaction ID that caused the conflict. + + + remote_commit_lsn + pg_lsn + The final LSN of the remote transaction. + + + local_commit_ts + timestamptz + The local commit timestamp of the local conflicting row (NULL if local tuple missing). + + + remote_commit_ts + timestamptz + The remote commit timestamp of the remote transaction. + + + table_schema + text + The schema name of the conflicting table. + + + table_name + text + The name of the conflicting table. + + + conflict_type + text + The type of conflict that occurred (e.g., insert_exists). + + + local_origin + text + The origin of the local transaction (if applicable). + + + remote_origin + text + The origin of the remote transaction. + + + key_tuple + json + The JSON representation of the replica identity or primary key tuple involved. + + + local_tuple + json + The JSON representation of the local row before the conflict (NULL if missing). + + + remote_tuple + json + The JSON representation of the incoming remote row that caused the conflict. + + + +
+ + + The conflicting row data, including the original local tuple and + the remote tuple, is stored in JSON columns (local_tuple + and remote_tuple) for flexible querying and analysis. + + The log format for logical replication conflicts is as follows: @@ -2163,6 +2277,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER key or replica identity defined for it. + + + + The conflict log history table created using the conflict_log_table + option on a subscription is not published even if the publication is defined with + FOR ALL TABLES. + + diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 8ab3b7fbd37..e221fba8c57 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -265,8 +265,9 @@ ALTER SUBSCRIPTION name RENAME TO < origin, failover, two_phase, - retain_dead_tuples, and - max_retention_duration. + retain_dead_tuples, + max_retention_duration and, + conflict_log_table. Only a superuser can set password_required = false. @@ -324,6 +325,12 @@ ALTER SUBSCRIPTION name RENAME TO < pg_conflict_detection, created to retain dead tuples for conflict detection, will be dropped. + + + When altering the conflict_log_table, the target table must not + exist in the specified schema; attempting to set the parameter to an + existing table name will result in an error. + diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index ed82cf1809e..0923f2fc801 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -268,6 +268,25 @@ CREATE SUBSCRIPTION subscription_name + + conflict_log_table (string) + + + Specifies the qualified table name where detailed logical replication + conflict information will be recorded. The table specified by this option + must not exist when the subscription is created; if it does, an error will + be raised. This table is automatically created by the system, and it is + owned by the subscription owner. The table's predefined schema includes + fields for transaction details, LSNs, and JSON columns for the conflicting + local and remote tuples etc. + + + If this option is used, the table is automatically dropped when the subscription + is dropped. + + + + streaming (enum) -- 2.49.0