mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +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:
		@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user