On 18.01.22 07:05, Masahiko Sawada wrote:
I've attached a rebased patch.

I think this is now almost done. Attached I have a small fixup patch with some documentation proof-reading, and removing some comments I felt are redundant. Some others have also sent you some documentation updates, so feel free to merge mine in with them.

Some other comments:

parse_subscription_options() and AlterSubscriptionStmt mixes regular options and skip options in ways that confuse me. It seems to work correctly, though. I guess for now it's okay, but if we add more skip options, it might be better to separate those more cleanly.

I think the superuser check in AlterSubscription() might no longer be appropriate. Subscriptions can now be owned by non-superusers. Please check that.

The display order in psql \dRs+ is a bit odd. I would put it at the end, certainly not between Two phase commit and Synchronous commit.

Please run pgperltidy over 028_skip_xact.pl.

Is the setting of logical_decoding_work_mem in the test script required? If so, comment why.

Please document arguments origin_lsn and origin_timestamp of
stop_skipping_changes().  Otherwise, one has to dig quite deep to find
out what they are for.

This is all minor stuff, so I think when this and the nearby comments are addressed, this is fine by me.
From 751be8216317f1d996c7b4f9f0e915adff805567 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 20 Jan 2022 17:03:27 +0100
Subject: [PATCH] fixup! Add ALTER SUBSCRIPTION ... SKIP to skip the
 transaction on subscriber nodes

---
 doc/src/sgml/logical-replication.sgml      | 12 ++++--------
 doc/src/sgml/ref/alter_subscription.sgml   | 16 ++++++++--------
 src/backend/commands/subscriptioncmds.c    |  2 +-
 src/backend/replication/logical/worker.c   |  7 -------
 src/test/regress/expected/subscription.out |  6 +++---
 src/test/subscription/t/028_skip_xact.pl   |  8 +++++---
 6 files changed, 21 insertions(+), 30 deletions(-)

diff --git a/doc/src/sgml/logical-replication.sgml 
b/doc/src/sgml/logical-replication.sgml
index de4f83bbcc..873530db99 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -355,11 +355,10 @@ <title>Conflicts</title>
    The resolution can be done either by changing data or permissions on the 
subscriber so
    that it does not conflict with the incoming changes or by skipping the
    the transaction that conflicts with the existing data.  When a conflict
-   produces an error, it is shown in
+   produces an error, it is shown in the
    <structname>pg_stat_subscription_workers</structname> view as follows:
-  </para>
 
-  <programlisting>
+<programlisting>
 postgres=# SELECT * FROM pg_stat_subscription_workers;
 -[ RECORD 1 ]------+-----------------------------------------------------------
 subid              | 16391
@@ -373,9 +372,7 @@ <title>Conflicts</title>
 last_error_time    | 2021-09-29 15:52:45.165754+00
 </programlisting>
 
-  <para>
    and it is also shown in subscriber's server log as follows:
-  </para>
 
 <screen>
 ERROR:  duplicate key value violates unique constraint "test_pkey"
@@ -383,7 +380,6 @@ <title>Conflicts</title>
 CONTEXT:  processing remote data during "INSERT" for replication target 
relation "public.test" in transaction 716 at 2021-09-29 15:52:45.165754+00
 </screen>
 
-  <para>
    The transaction ID that contains the change violating the constraint can be
    found from those outputs (transaction ID 716 in the above case).  The 
transaction
    can be skipped by using <command>ALTER SUBSCRIPTION ... SKIP</command> on 
the
@@ -401,9 +397,9 @@ <title>Conflicts</title>
    that it doesn't conflict with incoming changes, or dropping the conflicting 
constraint
    or unique index, or writing a trigger on the subscriber to suppress or 
redirect
    conflicting incoming changes, or as a last resort, by skipping the whole 
transaction.
-   Skipping the whole transaction includes skipping changes that may not 
violate
+   Skipping the whole transaction includes skipping changes that might not 
violate
    any constraint.  This can easily make the subscriber inconsistent, 
especially if
-   a user specifies the wrong transaction ID or the position of origin.
+   a user specifies the wrong transaction ID or the wrong position of origin.
   </para>
  </sect1>
 
diff --git a/doc/src/sgml/ref/alter_subscription.sgml 
b/doc/src/sgml/ref/alter_subscription.sgml
index 8b4568ddab..7e0eb55653 100644
--- a/doc/src/sgml/ref/alter_subscription.sgml
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -212,16 +212,16 @@ <title>Parameters</title>
     <term><literal>SKIP ( <replaceable 
class="parameter">skip_option</replaceable> = <replaceable 
class="parameter">value</replaceable> [, ... ] )</literal></term>
     <listitem>
      <para>
-      Skips applying all changes of the specified transaction.  If incoming 
data
-      violates any constraints, the logical replication will stop until it is
+      Skips applying all changes of the specified remote transaction.  If 
incoming data
+      violates any constraints, logical replication will stop until it is
       resolved.  The resolution can be done either by changing data on the
       subscriber so that it doesn't conflict with incoming changes or by 
skipping
-      the whole transaction.  Using <command> ALTER SUBSCRIPTION ... SKIP 
</command>
+      the whole transaction.  Using the <command>ALTER SUBSCRIPTION ... 
SKIP</command>
       command, the logical replication worker skips all data modification 
changes
-      within the specified transaction including changes that may not violate
+      within the specified transaction, including changes that might not 
violate
       the constraint, so, it should only be used as a last resort. This option 
has
       no effect on the transactions that are already prepared by enabling
-      <literal>two_phase</literal> on subscriber.  After the logical 
replication
+      <literal>two_phase</literal> on subscriber.  After logical replication
       successfully skips the transaction, the transaction ID (stored in
       
<structname>pg_subscription</structname>.<structfield>subskipxid</structfield>)
       is cleared.  See <xref linkend="logical-replication-conflicts"/> for
@@ -237,9 +237,9 @@ <title>Parameters</title>
         <term><literal>xid</literal> (<type>xid</type>)</term>
         <listitem>
          <para>
-          Specifies the ID of the transaction whose changes are to be skipped
-          by the logical replication worker.  We don't support skipping
-          individual subtransactions.  Setting <literal>NONE</literal>
+          Specifies the ID of the remote transaction whose changes are to be 
skipped
+          by the logical replication worker.  Skipping
+          individual subtransactions is not supported.  Setting 
<literal>NONE</literal>
           resets the transaction ID.
          </para>
         </listitem>
diff --git a/src/backend/commands/subscriptioncmds.c 
b/src/backend/commands/subscriptioncmds.c
index 0ff0e00f19..b8fb7130a6 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -273,7 +273,7 @@ parse_subscription_options(ParseState *pstate, List 
*stmt_options,
                                if (!TransactionIdIsNormal(xid))
                                        ereport(ERROR,
                                                        
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                                        errmsg("invalid 
transaction id: %s", xid_str)));
+                                                        errmsg("invalid 
transaction ID: %s", xid_str)));
                        }
 
                        opts->specified_opts |= SUBOPT_XID;
diff --git a/src/backend/replication/logical/worker.c 
b/src/backend/replication/logical/worker.c
index 0264e30112..0b6d9a203a 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -814,9 +814,6 @@ apply_handle_begin(StringInfo s)
 
        remote_final_lsn = begin_data.final_lsn;
 
-       /*
-        * Enable skipping all changes of this transaction if specified.
-        */
        maybe_start_skipping_changes(begin_data.xid);
 
        in_remote_transaction = true;
@@ -871,9 +868,6 @@ apply_handle_begin_prepare(StringInfo s)
 
        remote_final_lsn = begin_data.prepare_lsn;
 
-       /*
-        * Enable skipping all changes of this transaction if specified
-        */
        maybe_start_skipping_changes(begin_data.xid);
 
        in_remote_transaction = true;
@@ -1429,7 +1423,6 @@ apply_spooled_messages(TransactionId xid, XLogRecPtr lsn)
 
        remote_final_lsn = lsn;
 
-       /* Enable skipping all changes of this transaction if specified */
        maybe_start_skipping_changes(xid);
 
        /*
diff --git a/src/test/regress/expected/subscription.out 
b/src/test/regress/expected/subscription.out
index 892b6739bc..82733eed98 100644
--- a/src/test/regress/expected/subscription.out
+++ b/src/test/regress/expected/subscription.out
@@ -111,11 +111,11 @@ SELECT subname, subskipxid FROM pg_subscription WHERE 
subname = 'regress_testsub
 
 -- fail
 ALTER SUBSCRIPTION regress_testsub SKIP (xid = 0);
-ERROR:  invalid transaction id: 0
+ERROR:  invalid transaction ID: 0
 ALTER SUBSCRIPTION regress_testsub SKIP (xid = 1);
-ERROR:  invalid transaction id: 1
+ERROR:  invalid transaction ID: 1
 ALTER SUBSCRIPTION regress_testsub SKIP (xid = 2);
-ERROR:  invalid transaction id: 2
+ERROR:  invalid transaction ID: 2
 -- fail - must be superuser
 SET SESSION AUTHORIZATION 'regress_subscription_user2';
 ALTER SUBSCRIPTION regress_testsub SKIP (xid = 100);
diff --git a/src/test/subscription/t/028_skip_xact.pl 
b/src/test/subscription/t/028_skip_xact.pl
index 4c107fc8f5..efe28c71af 100644
--- a/src/test/subscription/t/028_skip_xact.pl
+++ b/src/test/subscription/t/028_skip_xact.pl
@@ -8,8 +8,8 @@
 use Test::More tests => 7;
 
 # Test skipping the transaction. This function must be called after the caller
-# inserting data that conflict with the subscriber.  After waiting for the
-# subscription worker stats are updated, we skip the transaction in question
+# has inserted data that conflicts with the subscriber.  After waiting for the
+# subscription worker stats to be updated, we skip the transaction in question
 # by ALTER SUBSCRIPTION ... SKIP. Then, check if logical replication can 
continue
 # working by inserting $nonconflict_data on the publisher.
 sub test_skip_xact
@@ -17,6 +17,8 @@ sub test_skip_xact
     my ($node_publisher, $node_subscriber, $subname, $relname, 
$nonconflict_data,
        $expected, $xid, $msg) = @_;
 
+       local $Test::Builder::Level = $Test::Builder::Level + 1;
+
     # Wait for worker error
     $node_subscriber->poll_query_until(
        'postgres',
@@ -83,7 +85,7 @@ sub test_skip_xact
 ]);
 $node_subscriber->start;
 
-# Initial table setup on both publisher and subscriber. On subscriber we
+# Initial table setup on both publisher and subscriber. On the subscriber, we
 # create the same tables but with primary keys. Also, insert some data that
 # will conflict with the data replicated from publisher later.
 $node_publisher->safe_psql(
-- 
2.34.1

Reply via email to