v27-0002-Use-latest-replication-slot-position-as-replicat.patch
application/octet-stream
Filename: v27-0002-Use-latest-replication-slot-position-as-replicat.patch
Type: application/octet-stream
Part: 3
Message:
Re: speed up a logical replica setup
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v27-0002
Subject: Use latest replication slot position as replication start point
| File | + | − |
|---|---|---|
| src/bin/pg_basebackup/pg_createsubscriber.c | 29 | 31 |
From 6dcabb444b56dd36c49d7add2ced19d78b520a52 Mon Sep 17 00:00:00 2001
From: Euler Taveira <euler@eulerto.com>
Date: Wed, 6 Mar 2024 17:50:01 -0300
Subject: [PATCH v27 2/5] Use latest replication slot position as replication
start point
Instead of using a temporary replication slot, use the latest
replication slot position (LSN).
---
src/bin/pg_basebackup/pg_createsubscriber.c | 60 ++++++++++-----------
1 file changed, 29 insertions(+), 31 deletions(-)
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index 3ccf3348a2..d9797ed8f4 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -74,11 +74,12 @@ static void modify_subscriber_sysid(const char *pg_resetwal_path,
struct CreateSubscriberOptions *opt);
static bool server_is_in_recovery(PGconn *conn);
static void check_publisher(struct LogicalRepInfo *dbinfo);
-static void setup_publisher(struct LogicalRepInfo *dbinfo);
+static char *setup_publisher(struct LogicalRepInfo *dbinfo);
static void check_subscriber(struct LogicalRepInfo *dbinfo);
static void setup_subscriber(struct LogicalRepInfo *dbinfo,
const char *consistent_lsn);
-static char *setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir);
+static void setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir,
+ char *lsn);
static void drop_primary_replication_slot(struct LogicalRepInfo *dbinfo,
char *slotname);
static char *create_logical_replication_slot(PGconn *conn,
@@ -574,11 +575,15 @@ modify_subscriber_sysid(const char *pg_resetwal_path, struct CreateSubscriberOpt
/*
* Create the publications and replication slots in preparation for logical
- * replication.
+ * replication. Returns the LSN from latest replication slot. It will be the
+ * replication start point that is used to adjust the subscriptions (see
+ * set_replication_progress).
*/
-static void
+static char *
setup_publisher(struct LogicalRepInfo *dbinfo)
{
+ char *lsn = NULL;
+
for (int i = 0; i < num_dbs; i++)
{
PGconn *conn;
@@ -641,8 +646,10 @@ setup_publisher(struct LogicalRepInfo *dbinfo)
dbinfo[i].subname = pg_strdup(replslotname);
/* Create replication slot on publisher */
- if (create_logical_replication_slot(conn, &dbinfo[i], false) != NULL ||
- dry_run)
+ if (lsn)
+ pg_free(lsn);
+ lsn = create_logical_replication_slot(conn, &dbinfo[i], false);
+ if (lsn != NULL || dry_run)
pg_log_info("create replication slot \"%s\" on publisher",
replslotname);
else
@@ -650,6 +657,8 @@ setup_publisher(struct LogicalRepInfo *dbinfo)
disconnect_database(conn, false);
}
+
+ return lsn;
}
/*
@@ -995,14 +1004,11 @@ setup_subscriber(struct LogicalRepInfo *dbinfo, const char *consistent_lsn)
}
/*
- * Get a replication start location and write the required recovery parameters
- * into the configuration file. Returns the replication start location that is
- * used to adjust the subscriptions (see set_replication_progress).
+ * Write the required recovery parameters.
*/
-static char *
-setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir)
+static void
+setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir, char *lsn)
{
- char *consistent_lsn;
PGconn *conn;
PQExpBuffer recoveryconfcontents;
@@ -1016,15 +1022,12 @@ setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir)
/*
* Write recovery parameters.
*
- * Despite of the recovery parameters will be written to the subscriber,
- * use a publisher connection for the following recovery functions. The
- * connection is only used to check the current server version (physical
- * replica, same server version). The subscriber is not running yet. In
- * dry run mode, the recovery parameters *won't* be written. An invalid
- * LSN is used for printing purposes. Additional recovery parameters are
- * added here. It avoids unexpected behavior such as end of recovery as
- * soon as a consistent state is reached (recovery_target) and failure due
- * to multiple recovery targets (name, time, xid, LSN).
+ * The subscriber is not running yet. In dry run mode, the recovery
+ * parameters *won't* be written. An invalid LSN is used for printing
+ * purposes. Additional recovery parameters are added here. It avoids
+ * unexpected behavior such as end of recovery as soon as a consistent
+ * state is reached (recovery_target) and failure due to multiple recovery
+ * targets (name, time, xid, LSN).
*/
recoveryconfcontents = GenerateRecoveryConfig(conn, NULL);
appendPQExpBuffer(recoveryconfcontents, "recovery_target = ''\n");
@@ -1048,14 +1051,12 @@ setup_recovery(struct LogicalRepInfo *dbinfo, char *datadir)
else
{
appendPQExpBuffer(recoveryconfcontents, "recovery_target_lsn = '%s'\n",
- consistent_lsn);
+ lsn);
WriteRecoveryConfig(conn, datadir, recoveryconfcontents);
}
disconnect_database(conn, false);
pg_log_debug("recovery parameters:\n%s", recoveryconfcontents->data);
-
- return consistent_lsn;
}
/*
@@ -1988,13 +1989,10 @@ main(int argc, char **argv)
* primary slot is in use. We could use an extra connection for it but it
* doesn't seem worth.
*/
- setup_publisher(dbinfo);
+ consistent_lsn = setup_publisher(dbinfo);
- /*
- * Get the replication start point and write the required recovery
- * parameters into the configuration file.
- */
- consistent_lsn = setup_recovery(dbinfo, opt.subscriber_dir);
+ /* Write the required recovery parameters */
+ setup_recovery(dbinfo, opt.subscriber_dir, consistent_lsn);
/*
* Restart subscriber so the recovery parameters will take effect. Wait
@@ -2010,7 +2008,7 @@ main(int argc, char **argv)
/*
* Create the subscription for each database on subscriber. It does not
* enable it immediately because it needs to adjust the replication start
- * point to the LSN reported by setup_recovery(). It also cleans up
+ * point to the LSN reported by setup_publisher(). It also cleans up
* publications created by this tool and replication to the standby.
*/
setup_subscriber(dbinfo, consistent_lsn);
--
2.41.0.windows.3