On 21.02.22 13:09, Euler Taveira wrote:
A new tool called pg_subscriber does this conversion and is tightly
integrated
with Postgres.
Are we comfortable with the name pg_subscriber? It seems too general.
Are we planning other subscriber-related operations in the future? If
so, we should at least make this one use a --create option or
something like that.
doc/src/sgml/ref/pg_subscriber.sgml
Attached is a patch that reorganizes the man page a bit. I moved the
description of the steps to the Notes section and formatted it
differently. I think the steps are interesting but not essential for
the using of the program, so I wanted to get them out of the main
description.
src/bin/pg_subscriber/pg_subscriber.c
+ if (made_temp_replslot)
+ {
+ conn = connect_database(dbinfo[0].pubconninfo, true);
+ drop_replication_slot(conn, &dbinfo[0], temp_replslot);
+ disconnect_database(conn);
+ }
Temp slots don't need to be cleaned up.
+/*
+ * Obtain the system identifier from control file. It will be used to
compare
+ * if a data directory is a clone of another one. This routine is used
locally
+ * and avoids a replication connection.
+ */
+static char *
+get_control_from_datadir(const char *datadir)
This could return uint64 directly, without string conversion.
get_sysid_from_conn() could then convert to uint64 internally.
+ {"verbose", no_argument, NULL, 'v'},
I'm not sure if the --verbose option is all that useful.
+ {"stop-subscriber", no_argument, NULL, 1},
This option doesn't seem to be otherwise supported or documented.
+ pub_sysid = pg_malloc(32);
+ pub_sysid = get_sysid_from_conn(dbinfo[0].pubconninfo);
+ sub_sysid = pg_malloc(32);
+ sub_sysid = get_control_from_datadir(subscriber_dir);
These mallocs don't appears to be of any use.
+ dbname_conninfo = pg_malloc(NAMEDATALEN);
This seems wrong.
Overall, this code could use a little bit more structuring. There are
a lot of helper functions that don't seem to do a lot and are mostly
duplicate runs-this-SQL-command calls. But the main() function is
still huge. There is room for refinement.
src/bin/pg_subscriber/t/001_basic.pl
Good start, but obviously, we'll need some real test cases here also.
src/bin/initdb/initdb.c
src/bin/pg_ctl/pg_ctl.c
src/common/file_utils.c
src/include/common/file_utils.h
I recommend skipping this refactoring. The readfile() function from
pg_ctl is not general enough to warrant the pride of place of a
globally available function. Note that it is specifically geared
toward some of pg_ctl's requirements, for example that the underlying
file can change while it is being read.
The requirements of pg_subscriber can be satisfied more easily: Just
call pg_ctl to start the server. You are already using that in
pg_subscriber. Is there a reason it can't be used here as well?
From a0ad5fdaddc17ef74594bfd3c65c777649d1544b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 15 Mar 2022 14:39:19 +0100
Subject: [PATCH] fixup! Create a new logical replica from a base backup or
standby server.
---
doc/src/sgml/ref/pg_subscriber.sgml | 172 ++++++++++++++++------------
1 file changed, 99 insertions(+), 73 deletions(-)
diff --git a/doc/src/sgml/ref/pg_subscriber.sgml
b/doc/src/sgml/ref/pg_subscriber.sgml
index e68a19092e..df63c6a993 100644
--- a/doc/src/sgml/ref/pg_subscriber.sgml
+++ b/doc/src/sgml/ref/pg_subscriber.sgml
@@ -43,79 +43,6 @@ <title>Description</title>
replication connections from the target server (known as subscriber server).
The target server should accept local logical replication connection.
</para>
-
- <para>
- The transformation proceeds in eight steps. First,
- <application>pg_subscriber</application> checks if the given target data
- directory has the same system identifier than the source data directory.
- Since it uses the recovery process as one of the steps, it starts the target
- server as a replica from the source server. If the system identifier is not
- the same, <application>pg_subscriber</application> will terminate with an
- error.
- </para>
-
- <para>
- Second, <application>pg_subscriber</application> checks if the target data
- directory is used by a standby server. Stop the standby server if it is
- running. One of the next steps is to add some recovery parameters that
- requires a server start. This step avoids an error.
- </para>
-
- <para>
- Next, <application>pg_subscriber</application> creates one replication slot
- for each specified database on the source server. The replication slot name
- contains a <literal>pg_subscriber</literal> prefix. These replication slots
- will be used by the subscriptions in a future step. Another replication
- slot is used to get a consistent start location. This consistent LSN will be
- used (a) as a stopping point in the <xref
- linkend="guc-recovery-target-lsn"/> parameter and (b) by the subscriptions
- as a replication starting point. It guarantees that no transaction will be
- lost.
- </para>
-
- <para>
- Next, write recovery parameters into the target data directory and start the
- target server. It specifies a LSN (consistent LSN that was obtained in the
- previous step) of write-ahead log location up to which recovery will
- proceed. It also specifies <literal>promote</literal> as the action that the
- server should take once the recovery target is reached. This step finishes
- once the server ends standby mode and is accepting read-write operations.
- </para>
-
- <para>
- Next, <application>pg_subscriber</application> creates one publication for
- each specified database on the source server. Each publication replicates
- changes for all tables in the database. The publication name contains a
- <literal>pg_subscriber</literal> prefix. These publication will be used by a
- corresponding subscription in a next step.
- </para>
-
- <para>
- Next, <application>pg_subscriber</application> creates one subscription for
- each specified database on the target server. Each subscription name
- contains a <literal>pg_subscriber</literal> prefix. The replication slot
- name is identical to the subscription name. It also does not copy existing
- data from the source server. It does not create a replication slot. Instead,
- it uses the replication slot that was created in a previous step. The
- subscription is created but it is not enabled yet. The reason is the
- replication progress must be set to the consistent LSN but replication
- origin name contains the subscription oid in its name. Hence, the
- subscription will be enabled in a separate step.
- </para>
-
- <para>
- Next, <application>pg_subscriber</application> sets the replication progress
- to the consistent LSN that was obtained in a previous step. When the target
- server started the recovery process, it caught up to the consistent LSN.
- This is the exact LSN to be used as a initial location for the logical
- replication.
- </para>
-
- <para>
- Finally, <application>pg_subscriber</application> enables the subscription
- for each specified database on the target server. The subscription starts
- streaming from the consistent LSN.
- </para>
</refsect1>
<refsect1>
@@ -209,6 +136,105 @@ <title>Options</title>
</refsect1>
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The transformation proceeds in the following steps:
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ <application>pg_subscriber</application> checks if the given target data
+ directory has the same system identifier than the source data directory.
+ Since it uses the recovery process as one of the steps, it starts the
+ target server as a replica from the source server. If the system
+ identifier is not the same, <application>pg_subscriber</application> will
+ terminate with an error.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ <application>pg_subscriber</application> checks if the target data
+ directory is used by a standby server. Stop the standby server if it is
+ running. One of the next steps is to add some recovery parameters that
+ requires a server start. This step avoids an error.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ <application>pg_subscriber</application> creates one replication slot for
+ each specified database on the source server. The replication slot name
+ contains a <literal>pg_subscriber</literal> prefix. These replication
+ slots will be used by the subscriptions in a future step. Another
+ replication slot is used to get a consistent start location. This
+ consistent LSN will be used (a) as a stopping point in the <xref
+ linkend="guc-recovery-target-lsn"/> parameter and (b) by the
+ subscriptions as a replication starting point. It guarantees that no
+ transaction will be lost.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ <application>pg_subscriber</application> writes recovery parameters into
+ the target data directory and start the target server. It specifies a LSN
+ (consistent LSN that was obtained in the previous step) of write-ahead
+ log location up to which recovery will proceed. It also specifies
+ <literal>promote</literal> as the action that the server should take once
+ the recovery target is reached. This step finishes once the server ends
+ standby mode and is accepting read-write operations.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Next, <application>pg_subscriber</application> creates one publication
+ for each specified database on the source server. Each publication
+ replicates changes for all tables in the database. The publication name
+ contains a <literal>pg_subscriber</literal> prefix. These publication
+ will be used by a corresponding subscription in a next step.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ <application>pg_subscriber</application> creates one subscription for
+ each specified database on the target server. Each subscription name
+ contains a <literal>pg_subscriber</literal> prefix. The replication slot
+ name is identical to the subscription name. It also does not copy
+ existing data from the source server. It does not create a replication
+ slot. Instead, it uses the replication slot that was created in a
+ previous step. The subscription is created but it is not enabled yet. The
+ reason is the replication progress must be set to the consistent LSN but
+ replication origin name contains the subscription oid in its name. Hence,
+ the subscription will be enabled in a separate step.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ <application>pg_subscriber</application> sets the replication progress to
+ the consistent LSN that was obtained in a previous step. When the target
+ server started the recovery process, it caught up to the consistent LSN.
+ This is the exact LSN to be used as a initial location for the logical
+ replication.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Finally, <application>pg_subscriber</application> enables the subscription
+ for each specified database on the target server. The subscription starts
+ streaming from the consistent LSN.
+ </para>
+ </step>
+ </procedure>
+ </refsect1>
+
<refsect1>
<title>Examples</title>
--
2.35.1