v1-0001-Avoid-race-condition-in-resetting-XLogCtl-Install.patch

application/octet-stream

Filename: v1-0001-Avoid-race-condition-in-resetting-XLogCtl-Install.patch
Type: application/octet-stream
Part: 0
Message: Re: Assertion failure in WaitForWALToBecomeAvailable state machine

Patch

Format: format-patch
Series: patch v1-0001
Subject: Avoid race condition in resetting XLogCtl->InstallXLogFileSegmentActive
File+
src/backend/access/transam/xlog.c 7 8
src/backend/access/transam/xlogrecovery.c 12 5
src/include/access/xlog.h 1 1
From 92924b28fc28038ecf694381250a6cea52bafd90 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Thu, 11 Aug 2022 16:27:05 +0000
Subject: [PATCH v1] Avoid race condition in resetting
 XLogCtl->InstallXLogFileSegmentActive

---
 src/backend/access/transam/xlog.c         | 15 +++++++--------
 src/backend/access/transam/xlogrecovery.c | 17 ++++++++++++-----
 src/include/access/xlog.h                 |  2 +-
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 9cedd6876f..52a22c944c 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8836,26 +8836,25 @@ GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 	LWLockRelease(ControlFileLock);
 }
 
-/* Thin wrapper around ShutdownWalRcv(). */
+/* Enable WAL file recycling and preallocation. */
 void
-XLogShutdownWalRcv(void)
+SetInstallXLogFileSegmentActive(void)
 {
-	ShutdownWalRcv();
-
 	LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
-	XLogCtl->InstallXLogFileSegmentActive = false;
+	XLogCtl->InstallXLogFileSegmentActive = true;
 	LWLockRelease(ControlFileLock);
 }
 
-/* Enable WAL file recycling and preallocation. */
+/* Disable WAL file recycling and preallocation. */
 void
-SetInstallXLogFileSegmentActive(void)
+ResetInstallXLogFileSegmentActive(void)
 {
 	LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
-	XLogCtl->InstallXLogFileSegmentActive = true;
+	XLogCtl->InstallXLogFileSegmentActive = false;
 	LWLockRelease(ControlFileLock);
 }
 
+
 bool
 IsInstallXLogFileSegmentActive(void)
 {
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index a59a0e826b..651191e93c 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -1395,7 +1395,7 @@ FinishWalRecovery(void)
 	 * over these records and subsequent ones if it's still alive when we
 	 * start writing WAL.
 	 */
-	XLogShutdownWalRcv();
+	ShutdownWalRcv();
 
 	/*
 	 * We are now done reading the xlog from stream. Turn off streaming
@@ -1403,7 +1403,7 @@ FinishWalRecovery(void)
 	 * recovery, e.g., timeline history file) from archive or pg_wal.
 	 *
 	 * Note that standby mode must be turned off after killing WAL receiver,
-	 * i.e., calling XLogShutdownWalRcv().
+	 * i.e., calling ShutdownWalRcv().
 	 */
 	Assert(!WalRcvStreaming());
 	StandbyMode = false;
@@ -3469,7 +3469,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 					 */
 					if (StandbyMode && CheckForStandbyTrigger())
 					{
-						XLogShutdownWalRcv();
+						ShutdownWalRcv();
 						return XLREAD_FAIL;
 					}
 
@@ -3517,7 +3517,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 					 * WAL that we restore from archive.
 					 */
 					if (WalRcvStreaming())
-						XLogShutdownWalRcv();
+						ShutdownWalRcv();
 
 					/*
 					 * Before we sleep, re-scan for possible new timelines if
@@ -3604,6 +3604,13 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 				 */
 				Assert(!WalRcvStreaming());
 
+				/*
+				 * WAL segment installation conflicts with archive recovery.
+				 * Make sure it is turned off.
+				 */
+				if (currentSource == XLOG_FROM_ARCHIVE)
+					ResetInstallXLogFileSegmentActive();
+
 				/* Close any old file we might have open. */
 				if (readFile >= 0)
 				{
@@ -3647,7 +3654,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 					 */
 					if (pendingWalRcvRestart && !startWalReceiver)
 					{
-						XLogShutdownWalRcv();
+						ShutdownWalRcv();
 
 						/*
 						 * Re-scan for possible new timelines if we were
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index cd674c3c23..52cd01b974 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -256,8 +256,8 @@ extern bool XLogCheckpointNeeded(XLogSegNo new_segno);
 extern void SwitchIntoArchiveRecovery(XLogRecPtr EndRecPtr, TimeLineID replayTLI);
 extern void ReachedEndOfBackup(XLogRecPtr EndRecPtr, TimeLineID tli);
 extern void SetInstallXLogFileSegmentActive(void);
+extern void ResetInstallXLogFileSegmentActive(void);
 extern bool IsInstallXLogFileSegmentActive(void);
-extern void XLogShutdownWalRcv(void);
 
 /*
  * Routines to start, stop, and get status of a base backup.
-- 
2.34.1