0001-Fix-InstallXLogFileSegment-concurrency-bug.patch

application/octet-stream

Filename: 0001-Fix-InstallXLogFileSegment-concurrency-bug.patch
Type: application/octet-stream
Part: 0
Message: InstallXLogFileSegment() vs concurrent WAL flush

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0001
Subject: Fix InstallXLogFileSegment() concurrency bug.
File+
src/backend/access/transam/xlog.c 13 0
From a70c79191567d51fefe71b07f7ef4afabaf0eb84 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 7 Jan 2024 12:40:57 +1300
Subject: [PATCH 1/2] Fix InstallXLogFileSegment() concurrency bug.

If the checkpointer is recycling a WAL segment file or another backend
is installing a new file, we mustn't allow other processes to write data
into the file before its name is durable.  Otherwise the data could
become unreachable in recovery after a power loss.
---
 src/backend/access/transam/xlog.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 478377c4a2..d76cfbb66e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3062,7 +3062,20 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
 					 errmsg("could not open file \"%s\": %m", path)));
 	}
 	else
+	{
+		/*
+		 * The file is there, but it is possible that InstallXLogFileSegment()
+		 * has recently renamed it and not yet made the new name durable.  We
+		 * don't want to be able to flush data into a file whose name might
+		 * not survive power loss, since it would become unreachable in
+		 * recovery.  Since InstallXlogFileSegment() holds ControlFileLock,
+		 * acquiring it here is enough to wait for any durable_rename() call
+		 * that might have started before we opened the file.
+		 */
+		LWLockAcquire(ControlFileLock, LW_SHARED);
+		LWLockRelease(ControlFileLock);
 		return fd;
+	}
 
 	/*
 	 * Initialize an empty (all zeroes) segment.  NOTE: it is possible that
-- 
2.39.3 (Apple Git-145)