Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+9
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

+48-1
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

+19-1
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)