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:
parent
ee4ac46c8e
commit
3297308278
@ -4124,6 +4124,26 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="guc-wal-receiver-create-temp-slot" xreflabel="wal_receiver_create_temp_slot">
|
||||||
|
<term><varname>wal_receiver_create_temp_slot</varname> (<type>boolean</type>)
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>wal_receiver_create_temp_slot</varname> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies whether a WAL receiver should create a temporary replication
|
||||||
|
slot on the remote instance when no permanent replication slot to use
|
||||||
|
has been configured (using <xref linkend="guc-primary-slot-name"/>).
|
||||||
|
The default is on. The only reason to turn this off would be if the
|
||||||
|
remote instance is currently out of available replication slots. This
|
||||||
|
parameter can only be set in the <filename>postgresql.conf</filename>
|
||||||
|
file or on the server command line. Changes only take effect when the
|
||||||
|
WAL receiver process starts a new connection.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="guc-wal-receiver-status-interval" xreflabel="wal_receiver_status_interval">
|
<varlistentry id="guc-wal-receiver-status-interval" xreflabel="wal_receiver_status_interval">
|
||||||
<term><varname>wal_receiver_status_interval</varname> (<type>integer</type>)
|
<term><varname>wal_receiver_status_interval</varname> (<type>integer</type>)
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -834,6 +834,10 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfoString(&cmd, " PHYSICAL RESERVE_WAL");
|
||||||
|
}
|
||||||
|
|
||||||
res = libpqrcv_PQexec(conn->streamConn, cmd.data);
|
res = libpqrcv_PQexec(conn->streamConn, cmd.data);
|
||||||
pfree(cmd.data);
|
pfree(cmd.data);
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* GUC variables */
|
/* GUC variables */
|
||||||
|
bool wal_receiver_create_temp_slot;
|
||||||
int wal_receiver_status_interval;
|
int wal_receiver_status_interval;
|
||||||
int wal_receiver_timeout;
|
int wal_receiver_timeout;
|
||||||
bool hot_standby_feedback;
|
bool hot_standby_feedback;
|
||||||
@ -169,6 +170,7 @@ WalReceiverMain(void)
|
|||||||
char conninfo[MAXCONNINFO];
|
char conninfo[MAXCONNINFO];
|
||||||
char *tmp_conninfo;
|
char *tmp_conninfo;
|
||||||
char slotname[NAMEDATALEN];
|
char slotname[NAMEDATALEN];
|
||||||
|
bool is_temp_slot;
|
||||||
XLogRecPtr startpoint;
|
XLogRecPtr startpoint;
|
||||||
TimeLineID startpointTLI;
|
TimeLineID startpointTLI;
|
||||||
TimeLineID primaryTLI;
|
TimeLineID primaryTLI;
|
||||||
@ -230,6 +232,7 @@ WalReceiverMain(void)
|
|||||||
walrcv->ready_to_display = false;
|
walrcv->ready_to_display = false;
|
||||||
strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
|
strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
|
||||||
strlcpy(slotname, (char *) walrcv->slotname, NAMEDATALEN);
|
strlcpy(slotname, (char *) walrcv->slotname, NAMEDATALEN);
|
||||||
|
is_temp_slot = walrcv->is_temp_slot;
|
||||||
startpoint = walrcv->receiveStart;
|
startpoint = walrcv->receiveStart;
|
||||||
startpointTLI = walrcv->receiveStartTLI;
|
startpointTLI = walrcv->receiveStartTLI;
|
||||||
|
|
||||||
@ -345,6 +348,44 @@ WalReceiverMain(void)
|
|||||||
*/
|
*/
|
||||||
WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI);
|
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.
|
* Start streaming.
|
||||||
*
|
*
|
||||||
|
@ -1969,6 +1969,15 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
NULL, NULL, NULL
|
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 */
|
/* End-of-list marker */
|
||||||
{
|
{
|
||||||
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
|
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
|
||||||
|
@ -321,6 +321,7 @@
|
|||||||
#max_standby_streaming_delay = 30s # max delay before canceling queries
|
#max_standby_streaming_delay = 30s # max delay before canceling queries
|
||||||
# when reading streaming WAL;
|
# when reading streaming WAL;
|
||||||
# -1 allows indefinite delay
|
# -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
|
#wal_receiver_status_interval = 10s # send replies at least this often
|
||||||
# 0 disables
|
# 0 disables
|
||||||
#hot_standby_feedback = off # send info from standby to prevent
|
#hot_standby_feedback = off # send info from standby to prevent
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "utils/tuplestore.h"
|
#include "utils/tuplestore.h"
|
||||||
|
|
||||||
/* user-settable parameters */
|
/* user-settable parameters */
|
||||||
|
extern bool wal_receiver_create_temp_slot;
|
||||||
extern int wal_receiver_status_interval;
|
extern int wal_receiver_status_interval;
|
||||||
extern int wal_receiver_timeout;
|
extern int wal_receiver_timeout;
|
||||||
extern bool hot_standby_feedback;
|
extern bool hot_standby_feedback;
|
||||||
@ -121,6 +122,12 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
char slotname[NAMEDATALEN];
|
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) */
|
/* set true once conninfo is ready to display (obfuscated pwds etc) */
|
||||||
bool ready_to_display;
|
bool ready_to_display;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user