Thread

  1. [PATCH v4 2/5] Apply walrcv_shutdown_deblocking_v2-2.patch

    Heikki Linnakangas <heikki.linnakangas@iki.fi> — 2024-01-23T09:01:25Z

    >From https://www.postgresql.org/message-id/20240123.172410.1596193222420636986.horikyota.ntt%40gmail.com
    ---
     .../libpqwalreceiver/libpqwalreceiver.c       |  4 +-
     src/backend/replication/walreceiver.c         | 53 +++++++++----------
     src/backend/tcop/postgres.c                   |  5 ++
     src/include/replication/walreceiver.h         |  2 +-
     4 files changed, 32 insertions(+), 32 deletions(-)
    
    diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    index dbee2f8f0e..41cf3dc853 100644
    --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    @@ -753,7 +753,7 @@ libpqrcv_PQgetResult(PGconn *streamConn)
     		if (rc & WL_LATCH_SET)
     		{
     			ResetLatch(MyLatch);
    -			ProcessWalRcvInterrupts();
    +			CHECK_FOR_INTERRUPTS();
     		}
     
     		/* Consume whatever data is available from the socket */
    @@ -1093,7 +1093,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres,
     	{
     		char	   *cstrs[MaxTupleAttributeNumber];
     
    -		ProcessWalRcvInterrupts();
    +		CHECK_FOR_INTERRUPTS();
     
     		/* Do the allocations in temporary context. */
     		oldcontext = MemoryContextSwitchTo(rowcontext);
    diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
    index e29a6196a3..110d96a4e6 100644
    --- a/src/backend/replication/walreceiver.c
    +++ b/src/backend/replication/walreceiver.c
    @@ -147,39 +147,34 @@ static void XLogWalRcvSendReply(bool force, bool requestReply);
     static void XLogWalRcvSendHSFeedback(bool immed);
     static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
     static void WalRcvComputeNextWakeup(WalRcvWakeupReason reason, TimestampTz now);
    +static void WalRcvShutdownSignalHandler(SIGNAL_ARGS);
     
    -/*
    - * Process any interrupts the walreceiver process may have received.
    - * This should be called any time the process's latch has become set.
    - *
    - * Currently, only SIGTERM is of interest.  We can't just exit(1) within the
    - * SIGTERM signal handler, because the signal might arrive in the middle of
    - * some critical operation, like while we're holding a spinlock.  Instead, the
    - * signal handler sets a flag variable as well as setting the process's latch.
    - * We must check the flag (by calling ProcessWalRcvInterrupts) anytime the
    - * latch has become set.  Operations that could block for a long time, such as
    - * reading from a remote server, must pay attention to the latch too; see
    - * libpqrcv_PQgetResult for example.
    - */
     void
    -ProcessWalRcvInterrupts(void)
    +WalRcvShutdownSignalHandler(SIGNAL_ARGS)
     {
    -	/*
    -	 * Although walreceiver interrupt handling doesn't use the same scheme as
    -	 * regular backends, call CHECK_FOR_INTERRUPTS() to make sure we receive
    -	 * any incoming signals on Win32, and also to make sure we process any
    -	 * barrier events.
    -	 */
    -	CHECK_FOR_INTERRUPTS();
    +	int			save_errno = errno;
     
    -	if (ShutdownRequestPending)
    +	/* Don't joggle the elbow of proc_exit */
    +	if (!proc_exit_inprogress)
     	{
    -		ereport(FATAL,
    -				(errcode(ERRCODE_ADMIN_SHUTDOWN),
    -				 errmsg("terminating walreceiver process due to administrator command")));
    +		InterruptPending = true;
    +		ProcDiePending = true;
     	}
    +
    +	SetLatch(MyLatch);
    +
    +	errno = save_errno;
    +	
     }
     
    +/*
    + * Is current process a wal receiver?
    + */
    +bool
    +IsWalReceiver(void)
    +{
    +	return MyBackendType == B_WAL_RECEIVER;
    +}
     
     /* Main entry point for walreceiver process */
     void
    @@ -277,7 +272,7 @@ WalReceiverMain(void)
     	pqsignal(SIGHUP, SignalHandlerForConfigReload); /* set flag to read config
     													 * file */
     	pqsignal(SIGINT, SIG_IGN);
    -	pqsignal(SIGTERM, SignalHandlerForShutdownRequest); /* request shutdown */
    +	pqsignal(SIGTERM, WalRcvShutdownSignalHandler); /* request shutdown */
     	/* SIGQUIT handler was already set up by InitPostmasterChild */
     	pqsignal(SIGALRM, SIG_IGN);
     	pqsignal(SIGPIPE, SIG_IGN);
    @@ -456,7 +451,7 @@ WalReceiverMain(void)
     							 errmsg("cannot continue WAL streaming, recovery has already ended")));
     
     				/* Process any requests or signals received recently */
    -				ProcessWalRcvInterrupts();
    +				CHECK_FOR_INTERRUPTS();
     
     				if (ConfigReloadPending)
     				{
    @@ -552,7 +547,7 @@ WalReceiverMain(void)
     				if (rc & WL_LATCH_SET)
     				{
     					ResetLatch(MyLatch);
    -					ProcessWalRcvInterrupts();
    +					CHECK_FOR_INTERRUPTS();
     
     					if (walrcv->force_reply)
     					{
    @@ -691,7 +686,7 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI)
     	{
     		ResetLatch(MyLatch);
     
    -		ProcessWalRcvInterrupts();
    +		CHECK_FOR_INTERRUPTS();
     
     		SpinLockAcquire(&walrcv->mutex);
     		Assert(walrcv->walRcvState == WALRCV_RESTARTING ||
    diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
    index 1a34bd3715..2ce24d8a9a 100644
    --- a/src/backend/tcop/postgres.c
    +++ b/src/backend/tcop/postgres.c
    @@ -59,6 +59,7 @@
     #include "replication/logicallauncher.h"
     #include "replication/logicalworker.h"
     #include "replication/slot.h"
    +#include "replication/walreceiver.h"
     #include "replication/walsender.h"
     #include "rewrite/rewriteHandler.h"
     #include "storage/bufmgr.h"
    @@ -3286,6 +3287,10 @@ ProcessInterrupts(void)
     			 */
     			proc_exit(1);
     		}
    +		else if (IsWalReceiver())
    +			ereport(FATAL,
    +					(errcode(ERRCODE_ADMIN_SHUTDOWN),
    +					 errmsg("terminating walreceiver process due to administrator command")));
     		else if (IsBackgroundWorker)
     			ereport(FATAL,
     					(errcode(ERRCODE_ADMIN_SHUTDOWN),
    diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
    index f566a99ba1..916d7b84fe 100644
    --- a/src/include/replication/walreceiver.h
    +++ b/src/include/replication/walreceiver.h
    @@ -470,8 +470,8 @@ walrcv_clear_result(WalRcvExecResult *walres)
     }
     
     /* prototypes for functions in walreceiver.c */
    +extern bool IsWalReceiver(void);
     extern void WalReceiverMain(void) pg_attribute_noreturn();
    -extern void ProcessWalRcvInterrupts(void);
     extern void WalRcvForceReply(void);
     
     /* prototypes for functions in walreceiverfuncs.c */
    -- 
    2.39.3
    
    
    ----Next_Part(Mon_Jan_29_16_32_06_2024_387)--
    Content-Type: Text/X-Patch; charset=us-ascii
    Content-Transfer-Encoding: 7bit
    Content-Disposition: attachment;
     filename="v4-0003-Use-libpq-be-fe-helpers.h-wrappers-more.patch"