Skip to content

Commit 81d20fb

Browse files
committed
pg_createsubscriber: Remove failover replication slots on subscriber
After running pg_createsubscriber, these replication slots have no use on subscriber, so drop them. Author: Euler Taveira <euler.taveira@enterprisedb.com> Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com> Discussion: https://www.postgresql.org/message-id/776c5cac-5ef5-4001-b1bc-5b698bc0c62a%40app.fastmail.com
1 parent b963913 commit 81d20fb

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

doc/src/sgml/ref/pg_createsubscriber.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,15 @@ PostgreSQL documentation
482482
</para>
483483
</step>
484484

485+
<step>
486+
<para>
487+
If the standby server contains <link
488+
linkend="logicaldecoding-replication-slots-synchronization">failover
489+
replication slots</link>, they cannot be synchronized anymore, so drop
490+
them.
491+
</para>
492+
</step>
493+
485494
<step>
486495
<para>
487496
Update the system identifier on the target server. The

src/bin/pg_basebackup/pg_createsubscriber.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static void setup_recovery(const struct LogicalRepInfo *dbinfo, const char *data
8585
const char *lsn);
8686
static void drop_primary_replication_slot(struct LogicalRepInfo *dbinfo,
8787
const char *slotname);
88+
static void drop_failover_replication_slots(struct LogicalRepInfo *dbinfo);
8889
static char *create_logical_replication_slot(PGconn *conn,
8990
struct LogicalRepInfo *dbinfo);
9091
static void drop_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo,
@@ -1137,6 +1138,49 @@ drop_primary_replication_slot(struct LogicalRepInfo *dbinfo, const char *slotnam
11371138
}
11381139
}
11391140

1141+
/*
1142+
* Drop failover replication slots on subscriber. After the transformation,
1143+
* they have no use.
1144+
*
1145+
* XXX We do not fail here. Instead, we provide a warning so the user can drop
1146+
* them later.
1147+
*/
1148+
static void
1149+
drop_failover_replication_slots(struct LogicalRepInfo *dbinfo)
1150+
{
1151+
PGconn *conn;
1152+
PGresult *res;
1153+
1154+
conn = connect_database(dbinfo[0].subconninfo, false);
1155+
if (conn != NULL)
1156+
{
1157+
/* Get failover replication slot names */
1158+
res = PQexec(conn,
1159+
"SELECT slot_name FROM pg_catalog.pg_replication_slots WHERE failover");
1160+
1161+
if (PQresultStatus(res) == PGRES_TUPLES_OK)
1162+
{
1163+
/* Remove failover replication slots from subscriber */
1164+
for (int i = 0; i < PQntuples(res); i++)
1165+
drop_replication_slot(conn, &dbinfo[0], PQgetvalue(res, i, 0));
1166+
}
1167+
else
1168+
{
1169+
pg_log_warning("could not obtain failover replication slot information: %s",
1170+
PQresultErrorMessage(res));
1171+
pg_log_warning_hint("Drop the failover replication slots on subscriber soon to avoid retention of WAL files.");
1172+
}
1173+
1174+
PQclear(res);
1175+
disconnect_database(conn, false);
1176+
}
1177+
else
1178+
{
1179+
pg_log_warning("could not drop failover replication slot");
1180+
pg_log_warning_hint("Drop the failover replication slots on subscriber soon to avoid retention of WAL files.");
1181+
}
1182+
}
1183+
11401184
/*
11411185
* Create a logical replication slot and returns a LSN.
11421186
*
@@ -1268,7 +1312,7 @@ start_standby_server(const struct CreateSubscriberOptions *opt, bool restricted_
12681312
PQExpBuffer pg_ctl_cmd = createPQExpBuffer();
12691313
int rc;
12701314

1271-
appendPQExpBuffer(pg_ctl_cmd, "\"%s\" start -D \"%s\" -s",
1315+
appendPQExpBuffer(pg_ctl_cmd, "\"%s\" start -D \"%s\" -s -o \"-c sync_replication_slots=off\"",
12721316
pg_ctl_path, subscriber_dir);
12731317
if (restricted_access)
12741318
{
@@ -2065,6 +2109,9 @@ main(int argc, char **argv)
20652109
/* Remove primary_slot_name if it exists on primary */
20662110
drop_primary_replication_slot(dbinfo, primary_slot_name);
20672111

2112+
/* Remove failover replication slots if they exist on subscriber */
2113+
drop_failover_replication_slots(dbinfo);
2114+
20682115
/* Stop the subscriber */
20692116
pg_log_info("stopping the subscriber");
20702117
stop_standby_server(subscriber_dir);

src/bin/pg_basebackup/t/040_pg_createsubscriber.pl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888

8989
# Set up node P as primary
9090
my $node_p = PostgreSQL::Test::Cluster->new('node_p');
91+
my $pconnstr = $node_p->connstr;
9192
$node_p->init(allows_streaming => 'logical');
9293
$node_p->start;
9394

@@ -122,6 +123,8 @@
122123
$node_s->append_conf(
123124
'postgresql.conf', qq[
124125
primary_slot_name = '$slotname'
126+
primary_conninfo = '$pconnstr dbname=postgres'
127+
hot_standby_feedback = on
125128
]);
126129
$node_s->set_standby_mode();
127130
$node_s->start;
@@ -260,6 +263,16 @@
260263
# Restore default settings on both servers
261264
$node_p->restart;
262265

266+
# Create failover slot to test its removal
267+
my $fslotname = 'failover_slot';
268+
$node_p->safe_psql('pg1',
269+
"SELECT pg_create_logical_replication_slot('$fslotname', 'pgoutput', false, false, true)");
270+
$node_s->start;
271+
$node_s->safe_psql('postgres', "SELECT pg_sync_replication_slots()");
272+
my $result = $node_s->safe_psql('postgres', "SELECT slot_name FROM pg_replication_slots WHERE slot_name = '$fslotname' AND synced AND NOT temporary");
273+
is($result, 'failover_slot', 'failover slot is synced');
274+
$node_s->stop;
275+
263276
# dry run mode on node S
264277
command_ok(
265278
[
@@ -318,7 +331,7 @@
318331
'run pg_createsubscriber on node S');
319332

320333
# Confirm the physical replication slot has been removed
321-
my $result = $node_p->safe_psql('pg1',
334+
$result = $node_p->safe_psql('pg1',
322335
"SELECT count(*) FROM pg_replication_slots WHERE slot_name = '$slotname'"
323336
);
324337
is($result, qq(0),
@@ -343,6 +356,11 @@
343356
$node_s->wait_for_subscription_sync($node_p, $subnames[0]);
344357
$node_s->wait_for_subscription_sync($node_p, $subnames[1]);
345358

359+
# Confirm the failover slot has been removed
360+
$result = $node_s->safe_psql('pg1',
361+
"SELECT count(*) FROM pg_replication_slots WHERE slot_name = '$fslotname'");
362+
is($result, qq(0), 'failover slot was removed');
363+
346364
# Check result on database pg1
347365
$result = $node_s->safe_psql('pg1', 'SELECT * FROM tbl1');
348366
is( $result, qq(first row

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy