1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

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
This commit is contained in:
Peter Eisentraut
2020-01-14 14:07:11 +01:00
parent ee4ac46c8e
commit 3297308278
6 changed files with 82 additions and 0 deletions

View File

@ -834,6 +834,10 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname,
break;
}
}
else
{
appendStringInfoString(&cmd, " PHYSICAL RESERVE_WAL");
}
res = libpqrcv_PQexec(conn->streamConn, cmd.data);
pfree(cmd.data);

View File

@ -73,6 +73,7 @@
/* GUC variables */
bool wal_receiver_create_temp_slot;
int wal_receiver_status_interval;
int wal_receiver_timeout;
bool hot_standby_feedback;
@ -169,6 +170,7 @@ WalReceiverMain(void)
char conninfo[MAXCONNINFO];
char *tmp_conninfo;
char slotname[NAMEDATALEN];
bool is_temp_slot;
XLogRecPtr startpoint;
TimeLineID startpointTLI;
TimeLineID primaryTLI;
@ -230,6 +232,7 @@ WalReceiverMain(void)
walrcv->ready_to_display = false;
strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
strlcpy(slotname, (char *) walrcv->slotname, NAMEDATALEN);
is_temp_slot = walrcv->is_temp_slot;
startpoint = walrcv->receiveStart;
startpointTLI = walrcv->receiveStartTLI;
@ -345,6 +348,44 @@ WalReceiverMain(void)
*/
WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI);
/*
* Create temporary replication slot if no slot name is configured or
* the slot from the previous run was temporary, unless
* wal_receiver_create_temp_slot is disabled. We also need to handle
* the case where the previous run used a temporary slot but
* wal_receiver_create_temp_slot was changed in the meantime. In that
* case, we delete the old slot name in shared memory. (This would
* all be a bit easier if we just didn't copy the slot name into
* shared memory, since we won't need it again later, but then we
* can't see the slot name in the stats views.)
*/
if (slotname[0] == '\0' || is_temp_slot)
{
bool changed = false;
if (wal_receiver_create_temp_slot)
{
snprintf(slotname, sizeof(slotname),
"pg_walreceiver_%d", walrcv_get_backend_pid(wrconn));
walrcv_create_slot(wrconn, slotname, true, 0, NULL);
changed = true;
}
else if (slotname[0] != '\0')
{
slotname[0] = '\0';
changed = true;
}
if (changed)
{
SpinLockAcquire(&walrcv->mutex);
strlcpy(walrcv->slotname, slotname, NAMEDATALEN);
walrcv->is_temp_slot = wal_receiver_create_temp_slot;
SpinLockRelease(&walrcv->mutex);
}
}
/*
* Start streaming.
*

View File

@ -1969,6 +1969,15 @@ static struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
{
{"wal_receiver_create_temp_slot", PGC_SIGHUP, REPLICATION_STANDBY,
gettext_noop("Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured."),
},
&wal_receiver_create_temp_slot,
true,
NULL, NULL, NULL
},
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL

View File

@ -321,6 +321,7 @@
#max_standby_streaming_delay = 30s # max delay before canceling queries
# when reading streaming WAL;
# -1 allows indefinite delay
#wal_receiver_create_temp_slot = on # create temp slot if primary_slot_name not set
#wal_receiver_status_interval = 10s # send replies at least this often
# 0 disables
#hot_standby_feedback = off # send info from standby to prevent

View File

@ -23,6 +23,7 @@
#include "utils/tuplestore.h"
/* user-settable parameters */
extern bool wal_receiver_create_temp_slot;
extern int wal_receiver_status_interval;
extern int wal_receiver_timeout;
extern bool hot_standby_feedback;
@ -121,6 +122,12 @@ typedef struct
*/
char slotname[NAMEDATALEN];
/*
* If it's a temporary replication slot, it needs to be recreated when
* connecting.
*/
bool is_temp_slot;
/* set true once conninfo is ready to display (obfuscated pwds etc) */
bool ready_to_display;