Skip to content

Commit 3297308

Browse files
committed
walreceiver uses a temporary replication slot by default
If no permanent replication slot is configured using primary_slot_name, the walreceiver now creates and uses a temporary replication slot. A new setting wal_receiver_create_temp_slot can be used to disable this behavior, for example, if the remote instance is out of replication slots. Reviewed-by: Masahiko Sawada <masahiko.sawada@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/CA%2Bfd4k4dM0iEPLxyVyme2RAFsn8SUgrNtBJOu81YqTY4V%2BnqZA%40mail.gmail.com
1 parent ee4ac46 commit 3297308

File tree

6 files changed

+82
-0
lines changed

6 files changed

+82
-0
lines changed

doc/src/sgml/config.sgml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4124,6 +4124,26 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
41244124
</listitem>
41254125
</varlistentry>
41264126

4127+
<varlistentry id="guc-wal-receiver-create-temp-slot" xreflabel="wal_receiver_create_temp_slot">
4128+
<term><varname>wal_receiver_create_temp_slot</varname> (<type>boolean</type>)
4129+
<indexterm>
4130+
<primary><varname>wal_receiver_create_temp_slot</varname> configuration parameter</primary>
4131+
</indexterm>
4132+
</term>
4133+
<listitem>
4134+
<para>
4135+
Specifies whether a WAL receiver should create a temporary replication
4136+
slot on the remote instance when no permanent replication slot to use
4137+
has been configured (using <xref linkend="guc-primary-slot-name"/>).
4138+
The default is on. The only reason to turn this off would be if the
4139+
remote instance is currently out of available replication slots. This
4140+
parameter can only be set in the <filename>postgresql.conf</filename>
4141+
file or on the server command line. Changes only take effect when the
4142+
WAL receiver process starts a new connection.
4143+
</para>
4144+
</listitem>
4145+
</varlistentry>
4146+
41274147
<varlistentry id="guc-wal-receiver-status-interval" xreflabel="wal_receiver_status_interval">
41284148
<term><varname>wal_receiver_status_interval</varname> (<type>integer</type>)
41294149
<indexterm>

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,10 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname,
834834
break;
835835
}
836836
}
837+
else
838+
{
839+
appendStringInfoString(&cmd, " PHYSICAL RESERVE_WAL");
840+
}
837841

838842
res = libpqrcv_PQexec(conn->streamConn, cmd.data);
839843
pfree(cmd.data);

src/backend/replication/walreceiver.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373

7474

7575
/* GUC variables */
76+
bool wal_receiver_create_temp_slot;
7677
int wal_receiver_status_interval;
7778
int wal_receiver_timeout;
7879
bool hot_standby_feedback;
@@ -169,6 +170,7 @@ WalReceiverMain(void)
169170
char conninfo[MAXCONNINFO];
170171
char *tmp_conninfo;
171172
char slotname[NAMEDATALEN];
173+
bool is_temp_slot;
172174
XLogRecPtr startpoint;
173175
TimeLineID startpointTLI;
174176
TimeLineID primaryTLI;
@@ -230,6 +232,7 @@ WalReceiverMain(void)
230232
walrcv->ready_to_display = false;
231233
strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
232234
strlcpy(slotname, (char *) walrcv->slotname, NAMEDATALEN);
235+
is_temp_slot = walrcv->is_temp_slot;
233236
startpoint = walrcv->receiveStart;
234237
startpointTLI = walrcv->receiveStartTLI;
235238

@@ -345,6 +348,44 @@ WalReceiverMain(void)
345348
*/
346349
WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI);
347350

351+
/*
352+
* Create temporary replication slot if no slot name is configured or
353+
* the slot from the previous run was temporary, unless
354+
* wal_receiver_create_temp_slot is disabled. We also need to handle
355+
* the case where the previous run used a temporary slot but
356+
* wal_receiver_create_temp_slot was changed in the meantime. In that
357+
* case, we delete the old slot name in shared memory. (This would
358+
* all be a bit easier if we just didn't copy the slot name into
359+
* shared memory, since we won't need it again later, but then we
360+
* can't see the slot name in the stats views.)
361+
*/
362+
if (slotname[0] == '\0' || is_temp_slot)
363+
{
364+
bool changed = false;
365+
366+
if (wal_receiver_create_temp_slot)
367+
{
368+
snprintf(slotname, sizeof(slotname),
369+
"pg_walreceiver_%d", walrcv_get_backend_pid(wrconn));
370+
371+
walrcv_create_slot(wrconn, slotname, true, 0, NULL);
372+
changed = true;
373+
}
374+
else if (slotname[0] != '\0')
375+
{
376+
slotname[0] = '\0';
377+
changed = true;
378+
}
379+
380+
if (changed)
381+
{
382+
SpinLockAcquire(&walrcv->mutex);
383+
strlcpy(walrcv->slotname, slotname, NAMEDATALEN);
384+
walrcv->is_temp_slot = wal_receiver_create_temp_slot;
385+
SpinLockRelease(&walrcv->mutex);
386+
}
387+
}
388+
348389
/*
349390
* Start streaming.
350391
*

src/backend/utils/misc/guc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,15 @@ static struct config_bool ConfigureNamesBool[] =
19691969
NULL, NULL, NULL
19701970
},
19711971

1972+
{
1973+
{"wal_receiver_create_temp_slot", PGC_SIGHUP, REPLICATION_STANDBY,
1974+
gettext_noop("Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured."),
1975+
},
1976+
&wal_receiver_create_temp_slot,
1977+
true,
1978+
NULL, NULL, NULL
1979+
},
1980+
19721981
/* End-of-list marker */
19731982
{
19741983
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@
321321
#max_standby_streaming_delay = 30s # max delay before canceling queries
322322
# when reading streaming WAL;
323323
# -1 allows indefinite delay
324+
#wal_receiver_create_temp_slot = on # create temp slot if primary_slot_name not set
324325
#wal_receiver_status_interval = 10s # send replies at least this often
325326
# 0 disables
326327
#hot_standby_feedback = off # send info from standby to prevent

src/include/replication/walreceiver.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "utils/tuplestore.h"
2424

2525
/* user-settable parameters */
26+
extern bool wal_receiver_create_temp_slot;
2627
extern int wal_receiver_status_interval;
2728
extern int wal_receiver_timeout;
2829
extern bool hot_standby_feedback;
@@ -121,6 +122,12 @@ typedef struct
121122
*/
122123
char slotname[NAMEDATALEN];
123124

125+
/*
126+
* If it's a temporary replication slot, it needs to be recreated when
127+
* connecting.
128+
*/
129+
bool is_temp_slot;
130+
124131
/* set true once conninfo is ready to display (obfuscated pwds etc) */
125132
bool ready_to_display;
126133

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