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

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

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

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

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

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

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