Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 092c693

Browse files
committed
Set wal_receiver_create_temp_slot PGC_POSTMASTER
Commit 3297308 gave walreceiver the ability to create and use a temporary replication slot, and made it controllable by a GUC (enabled by default) that can be changed with SIGHUP. That's useful but has two problems: one, it's possible to cause the origin server to fill its disk if the slot doesn't advance in time; and also there's a disconnect between state passed down via the startup process and GUCs that walreceiver reads directly. We handle the first problem by setting the option to disabled by default. If the user enables it, its on their head to make sure that disk doesn't fill up. We handle the second problem by passing the flag via startup rather than having walreceiver acquire it directly, and making it PGC_POSTMASTER (which ensures a walreceiver always has the fresh value). A future commit can relax this (to PGC_SIGHUP again) by having the startup process signal walreceiver to shutdown whenever the value changes. Author: Sergei Kornilov <sk@zsrv.org> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/20200122055510.GH174860@paquier.xyz
1 parent fbc7a71 commit 092c693

File tree

8 files changed

+63
-50
lines changed

8 files changed

+63
-50
lines changed

doc/src/sgml/config.sgml

+1-5
Original file line numberDiff line numberDiff line change
@@ -4163,11 +4163,7 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
41634163
Specifies whether a WAL receiver should create a temporary replication
41644164
slot on the remote instance when no permanent replication slot to use
41654165
has been configured (using <xref linkend="guc-primary-slot-name"/>).
4166-
The default is on. The only reason to turn this off would be if the
4167-
remote instance is currently out of available replication slots. This
4168-
parameter can only be set in the <filename>postgresql.conf</filename>
4169-
file or on the server command line. Changes only take effect when the
4170-
WAL receiver process starts a new connection.
4166+
The default is off. This parameter can only be set at server start.
41714167
</para>
41724168
</listitem>
41734169
</varlistentry>

src/backend/access/transam/xlog.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ bool StandbyModeRequested = false;
290290
char *PrimaryConnInfo = NULL;
291291
char *PrimarySlotName = NULL;
292292
char *PromoteTriggerFile = NULL;
293+
bool wal_receiver_create_temp_slot = false;
293294

294295
/* are we currently in standby mode? */
295296
bool StandbyMode = false;
@@ -11975,7 +11976,8 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
1197511976
}
1197611977
curFileTLI = tli;
1197711978
RequestXLogStreaming(tli, ptr, PrimaryConnInfo,
11978-
PrimarySlotName);
11979+
PrimarySlotName,
11980+
wal_receiver_create_temp_slot);
1197911981
receivedUpto = 0;
1198011982
}
1198111983

src/backend/replication/walreceiver.c

+28-34
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
* WalRcv->receivedUpto variable in shared memory, to inform the startup
1616
* process of how far it can proceed with XLOG replay.
1717
*
18+
* A WAL receiver cannot directly load GUC parameters used when establishing
19+
* its connection to the primary. Instead it relies on parameter values
20+
* that are passed down by the startup process when streaming is requested.
21+
* This applies, for example, to the replication slot and the connection
22+
* string to be used for the connection with the primary.
23+
*
1824
* If the primary server ends streaming, but doesn't disconnect, walreceiver
1925
* goes into "waiting" mode, and waits for the startup process to give new
2026
* instructions. The startup process will treat that the same as
@@ -73,8 +79,11 @@
7379
#include "utils/timestamp.h"
7480

7581

76-
/* GUC variables */
77-
bool wal_receiver_create_temp_slot;
82+
/*
83+
* GUC variables. (Other variables that affect walreceiver are in xlog.c
84+
* because they're passed down from the startup process, for better
85+
* synchronization.)
86+
*/
7887
int wal_receiver_status_interval;
7988
int wal_receiver_timeout;
8089
bool hot_standby_feedback;
@@ -236,6 +245,12 @@ WalReceiverMain(void)
236245
startpoint = walrcv->receiveStart;
237246
startpointTLI = walrcv->receiveStartTLI;
238247

248+
/*
249+
* At most one of is_temp_slot and slotname can be set; otherwise,
250+
* RequestXLogStreaming messed up.
251+
*/
252+
Assert(!is_temp_slot || (slotname[0] == '\0'));
253+
239254
/* Initialise to a sanish value */
240255
walrcv->lastMsgSendTime =
241256
walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = now;
@@ -349,42 +364,21 @@ WalReceiverMain(void)
349364
WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI);
350365

351366
/*
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.)
367+
* Create temporary replication slot if requested, and update slot
368+
* name in shared memory. (Note the slot name cannot already be set
369+
* in this case.)
361370
*/
362-
if (slotname[0] == '\0' || is_temp_slot)
371+
if (is_temp_slot)
363372
{
364-
bool changed = false;
365-
366-
if (wal_receiver_create_temp_slot)
367-
{
368-
snprintf(slotname, sizeof(slotname),
369-
"pg_walreceiver_%lld",
370-
(long long int) walrcv_get_backend_pid(wrconn));
373+
snprintf(slotname, sizeof(slotname),
374+
"pg_walreceiver_%lld",
375+
(long long int) walrcv_get_backend_pid(wrconn));
371376

372-
walrcv_create_slot(wrconn, slotname, true, 0, NULL);
373-
changed = true;
374-
}
375-
else if (slotname[0] != '\0')
376-
{
377-
slotname[0] = '\0';
378-
changed = true;
379-
}
377+
walrcv_create_slot(wrconn, slotname, true, 0, NULL);
380378

381-
if (changed)
382-
{
383-
SpinLockAcquire(&walrcv->mutex);
384-
strlcpy(walrcv->slotname, slotname, NAMEDATALEN);
385-
walrcv->is_temp_slot = wal_receiver_create_temp_slot;
386-
SpinLockRelease(&walrcv->mutex);
387-
}
379+
SpinLockAcquire(&walrcv->mutex);
380+
strlcpy(walrcv->slotname, slotname, NAMEDATALEN);
381+
SpinLockRelease(&walrcv->mutex);
388382
}
389383

390384
/*

src/backend/replication/walreceiverfuncs.c

+23-5
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,19 @@ ShutdownWalRcv(void)
215215
/*
216216
* Request postmaster to start walreceiver.
217217
*
218-
* recptr indicates the position where streaming should begin, conninfo
219-
* is a libpq connection string to use, and slotname is, optionally, the name
220-
* of a replication slot to acquire.
218+
* "recptr" indicates the position where streaming should begin. "conninfo"
219+
* is a libpq connection string to use. "slotname" is, optionally, the name
220+
* of a replication slot to acquire. "create_temp_slot" indicates to create
221+
* a temporary slot when no "slotname" is given.
222+
*
223+
* WAL receivers do not directly load GUC parameters used for the connection
224+
* to the primary, and rely on the values passed down by the caller of this
225+
* routine instead. Hence, the addition of any new parameters should happen
226+
* through this code path.
221227
*/
222228
void
223229
RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
224-
const char *slotname)
230+
const char *slotname, bool create_temp_slot)
225231
{
226232
WalRcvData *walrcv = WalRcv;
227233
bool launch = false;
@@ -248,10 +254,22 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
248254
else
249255
walrcv->conninfo[0] = '\0';
250256

251-
if (slotname != NULL)
257+
/*
258+
* Use configured replication slot if present, and ignore the value
259+
* of create_temp_slot as the slot name should be persistent. Otherwise,
260+
* use create_temp_slot to determine whether this WAL receiver should
261+
* create a temporary slot by itself and use it, or not.
262+
*/
263+
if (slotname != NULL && slotname[0] != '\0')
264+
{
252265
strlcpy((char *) walrcv->slotname, slotname, NAMEDATALEN);
266+
walrcv->is_temp_slot = false;
267+
}
253268
else
269+
{
254270
walrcv->slotname[0] = '\0';
271+
walrcv->is_temp_slot = create_temp_slot;
272+
}
255273

256274
if (walrcv->walRcvState == WALRCV_STOPPED)
257275
{

src/backend/utils/misc/guc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2050,11 +2050,11 @@ static struct config_bool ConfigureNamesBool[] =
20502050
},
20512051

20522052
{
2053-
{"wal_receiver_create_temp_slot", PGC_SIGHUP, REPLICATION_STANDBY,
2053+
{"wal_receiver_create_temp_slot", PGC_POSTMASTER, REPLICATION_STANDBY,
20542054
gettext_noop("Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured."),
20552055
},
20562056
&wal_receiver_create_temp_slot,
2057-
true,
2057+
false,
20582058
NULL, NULL, NULL
20592059
},
20602060

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@
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
324+
#wal_receiver_create_temp_slot = off # Create temp slot if primary_slot_name
325+
# is not set.
326+
# (change requires restart)
325327
#wal_receiver_status_interval = 10s # send replies at least this often
326328
# 0 disables
327329
#hot_standby_feedback = off # send info from standby to prevent

src/include/access/xlog.h

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ extern int recoveryTargetAction;
129129
extern int recovery_min_apply_delay;
130130
extern char *PrimaryConnInfo;
131131
extern char *PrimarySlotName;
132+
extern bool wal_receiver_create_temp_slot;
132133

133134
/* indirectly set via GUC system */
134135
extern TransactionId recoveryTargetXid;

src/include/replication/walreceiver.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "utils/tuplestore.h"
2424

2525
/* user-settable parameters */
26-
extern bool wal_receiver_create_temp_slot;
2726
extern int wal_receiver_status_interval;
2827
extern int wal_receiver_timeout;
2928
extern bool hot_standby_feedback;
@@ -321,7 +320,8 @@ extern void ShutdownWalRcv(void);
321320
extern bool WalRcvStreaming(void);
322321
extern bool WalRcvRunning(void);
323322
extern void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr,
324-
const char *conninfo, const char *slotname);
323+
const char *conninfo, const char *slotname,
324+
bool create_temp_slot);
325325
extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI);
326326
extern int GetReplicationApplyDelay(void);
327327
extern int GetReplicationTransferLatency(void);

0 commit comments

Comments
 (0)