From c26defb3c50ceea9308b3441ac65bb28267e9f1c Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 22 Nov 2019 11:09:26 +0100 Subject: [PATCH 3/3] 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. --- doc/src/sgml/config.sgml | 20 +++++++++++++++++++ doc/src/sgml/monitoring.sgml | 9 ++++++++- .../libpqwalreceiver/libpqwalreceiver.c | 4 ++++ src/backend/replication/walreceiver.c | 14 +++++++++++++ src/backend/utils/misc/guc.c | 9 +++++++++ src/backend/utils/misc/postgresql.conf.sample | 1 + src/include/replication/walreceiver.h | 1 + 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index d4d1fe45cc..af700f1edf 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -4126,6 +4126,26 @@ Standby Servers + + wal_receiver_create_temp_slot (boolean) + + wal_receiver_create_temp_slot configuration parameter + + + + + 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 ). + 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 postgresql.conf + file or on the server command line. Changes only take effect when the + WAL receiver process starts a new connection. + + + + wal_receiver_status_interval (integer) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index a3c5f86b7e..eac7aa44b6 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -2113,7 +2113,14 @@ <structname>pg_stat_wal_receiver</structname> View slot_name text - Replication slot name used by this WAL receiver + + Replication slot name used by this WAL receiver. This is only set if a + permanent replication slot is set using . Otherwise, the WAL receiver may use + a temporary replication slot (determined by ), but these are not shown + here. + sender_host diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index ccc31f3cee..e1c4c78217 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -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); diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index f54ae7690d..b11ecc5a12 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -72,6 +72,7 @@ /* GUC variables */ +bool wal_receiver_create_temp_slot; int wal_receiver_status_interval; int wal_receiver_timeout; bool hot_standby_feedback; @@ -345,6 +346,19 @@ WalReceiverMain(void) */ WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI); + /* + * Create temporary replication slot if no slot name is configured, + * unless disabled. Note that we don't copy the slot name into shared + * memory, since it will go away when this walreceiver session ends. + */ + if (slotname[0] == '\0' && 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); + } + /* * Start streaming. * diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ba4edde71a..4f590ad5af 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1959,6 +1959,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 diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 46a06ffacd..501c4e49ac 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -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 diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 39be805172..0c06b5c3de 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -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; -- 2.24.0