From 885c15ba379da4fd5f0dd71ee4dc9b5e31108d6f Mon Sep 17 00:00:00 2001
From: Evgeny Voropaev <evorop@gmail.com>
Date: Sun, 23 Feb 2025 23:19:19 +0800
Subject: [PATCH v4] Elimination of the repetitive code at the SLRU
 bootstrapping and nullifying functions.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The functions bootstrapping and nullifying SLRU pages used to have a lot of
repetitive code. New functions realized by this commit (BootStrapSlruPage,
XLogSimpleInsert) have allowed to remove these repetitions.

Author: Evgeny Voropaev <evgeny.voropaev@tantorlabs.com> <evorop@gmail.com>
Reviewed by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed by: Aleksander Alekseev <aleksander@timescale.com>
Discussion: https://www.postgresql.org/message-id/flat/97820ce8-a1cd-407f-a02b-47368fadb14b%40tantorlabs.com
---
 src/backend/access/transam/clog.c       |  72 ++---------
 src/backend/access/transam/commit_ts.c  |  70 ++---------
 src/backend/access/transam/multixact.c  | 155 ++++++------------------
 src/backend/access/transam/slru.c       |  45 ++++++-
 src/backend/access/transam/subtrans.c   |  48 ++------
 src/backend/access/transam/xloginsert.c |  14 +++
 src/include/access/slru.h               |   2 +
 src/include/access/xloginsert.h         |   1 +
 8 files changed, 138 insertions(+), 269 deletions(-)

diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 48f10bec91e..c86129282fa 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -110,7 +110,6 @@ static SlruCtlData XactCtlData;
 #define XactCtl (&XactCtlData)
 
 
-static int	ZeroCLOGPage(int64 pageno, bool writeXlog);
 static bool CLOGPagePrecedes(int64 page1, int64 page2);
 static void WriteZeroPageXlogRec(int64 pageno);
 static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXact,
@@ -832,41 +831,11 @@ check_transaction_buffers(int *newval, void **extra, GucSource source)
 void
 BootStrapCLOG(void)
 {
-	int			slotno;
-	LWLock	   *lock = SimpleLruGetBankLock(XactCtl, 0);
-
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Create and zero the first page of the commit log */
-	slotno = ZeroCLOGPage(0, false);
-
-	/* Make sure it's written out */
-	SimpleLruWritePage(XactCtl, slotno);
-	Assert(!XactCtl->shared->page_dirty[slotno]);
-
-	LWLockRelease(lock);
-}
-
-/*
- * Initialize (or reinitialize) a page of CLOG to zeroes.
- * If writeXlog is true, also emit an XLOG record saying we did this.
- *
- * The page is not actually written, just set up in shared memory.
- * The slot number of the new page is returned.
- *
- * Control lock must be held at entry, and will be held at exit.
- */
-static int
-ZeroCLOGPage(int64 pageno, bool writeXlog)
-{
-	int			slotno;
-
-	slotno = SimpleLruZeroPage(XactCtl, pageno);
-
-	if (writeXlog)
-		WriteZeroPageXlogRec(pageno);
-
-	return slotno;
+	/*
+	 * Nullify the page (pageno = 0), don't insert an XLog record, 
+	 * save the page on a disk
+	 */
+	BootStrapSlruPage(XactCtl, 0, 0, true);
 }
 
 /*
@@ -959,7 +928,6 @@ void
 ExtendCLOG(TransactionId newestXact)
 {
 	int64		pageno;
-	LWLock	   *lock;
 
 	/*
 	 * No work except at first XID of a page.  But beware: just after
@@ -970,14 +938,12 @@ ExtendCLOG(TransactionId newestXact)
 		return;
 
 	pageno = TransactionIdToPage(newestXact);
-	lock = SimpleLruGetBankLock(XactCtl, pageno);
 
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Zero the page and make an XLOG entry about it */
-	ZeroCLOGPage(pageno, true);
-
-	LWLockRelease(lock);
+	/*
+	 * Zero the page, make an XLOG entry about it,
+	 * don't write the page on a disk
+	 */
+	BootStrapSlruPage(XactCtl, pageno, WriteZeroPageXlogRec, false);
 }
 
 
@@ -1073,9 +1039,7 @@ CLOGPagePrecedes(int64 page1, int64 page2)
 static void
 WriteZeroPageXlogRec(int64 pageno)
 {
-	XLogBeginInsert();
-	XLogRegisterData(&pageno, sizeof(pageno));
-	(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE);
+	XLogSimpleInsert(pageno, RM_CLOG_ID, CLOG_ZEROPAGE);
 }
 
 /*
@@ -1114,19 +1078,9 @@ clog_redo(XLogReaderState *record)
 	if (info == CLOG_ZEROPAGE)
 	{
 		int64		pageno;
-		int			slotno;
-		LWLock	   *lock;
-
 		memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
-
-		lock = SimpleLruGetBankLock(XactCtl, pageno);
-		LWLockAcquire(lock, LW_EXCLUSIVE);
-
-		slotno = ZeroCLOGPage(pageno, false);
-		SimpleLruWritePage(XactCtl, slotno);
-		Assert(!XactCtl->shared->page_dirty[slotno]);
-
-		LWLockRelease(lock);
+		/* Zero the page, don't make an XLOG entry about it, write the page on a disk */
+		BootStrapSlruPage(XactCtl, pageno, 0, true);
 	}
 	else if (info == CLOG_TRUNCATE)
 	{
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 113fae1437a..6c479133350 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -114,7 +114,6 @@ static void SetXidCommitTsInPage(TransactionId xid, int nsubxids,
 static void TransactionIdSetCommitTs(TransactionId xid, TimestampTz ts,
 									 RepOriginId nodeid, int slotno);
 static void error_commit_ts_disabled(void);
-static int	ZeroCommitTsPage(int64 pageno, bool writeXlog);
 static bool CommitTsPagePrecedes(int64 page1, int64 page2);
 static void ActivateCommitTs(void);
 static void DeactivateCommitTs(void);
@@ -602,28 +601,6 @@ BootStrapCommitTs(void)
 	 */
 }
 
-/*
- * Initialize (or reinitialize) a page of CommitTs to zeroes.
- * If writeXlog is true, also emit an XLOG record saying we did this.
- *
- * The page is not actually written, just set up in shared memory.
- * The slot number of the new page is returned.
- *
- * Control lock must be held at entry, and will be held at exit.
- */
-static int
-ZeroCommitTsPage(int64 pageno, bool writeXlog)
-{
-	int			slotno;
-
-	slotno = SimpleLruZeroPage(CommitTsCtl, pageno);
-
-	if (writeXlog)
-		WriteZeroPageXlogRec(pageno);
-
-	return slotno;
-}
-
 /*
  * This must be called ONCE during postmaster or standalone-backend startup,
  * after StartupXLOG has initialized TransamVariables->nextXid.
@@ -747,16 +724,8 @@ ActivateCommitTs(void)
 
 	/* Create the current segment file, if necessary */
 	if (!SimpleLruDoesPhysicalPageExist(CommitTsCtl, pageno))
-	{
-		LWLock	   *lock = SimpleLruGetBankLock(CommitTsCtl, pageno);
-		int			slotno;
-
-		LWLockAcquire(lock, LW_EXCLUSIVE);
-		slotno = ZeroCommitTsPage(pageno, false);
-		SimpleLruWritePage(CommitTsCtl, slotno);
-		Assert(!CommitTsCtl->shared->page_dirty[slotno]);
-		LWLockRelease(lock);
-	}
+		/* Zero the page, don't make an XLOG entry about it, write the page on a disk */
+		BootStrapSlruPage(CommitTsCtl, pageno, 0, true);
 
 	/* Change the activation status in shared memory. */
 	LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
@@ -842,7 +811,6 @@ void
 ExtendCommitTs(TransactionId newestXact)
 {
 	int64		pageno;
-	LWLock	   *lock;
 
 	/*
 	 * Nothing to do if module not enabled.  Note we do an unlocked read of
@@ -863,14 +831,13 @@ ExtendCommitTs(TransactionId newestXact)
 
 	pageno = TransactionIdToCTsPage(newestXact);
 
-	lock = SimpleLruGetBankLock(CommitTsCtl, pageno);
-
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Zero the page and make an XLOG entry about it */
-	ZeroCommitTsPage(pageno, !InRecovery);
-
-	LWLockRelease(lock);
+	/* 
+	 * Zero the page; 
+	 * if we are not doing recovery from XLOG, make an XLOG entry about it;
+	 * don't write the page on a disk.
+	 */
+	BootStrapSlruPage(CommitTsCtl, pageno,
+					  InRecovery ? 0 : WriteZeroPageXlogRec, false);
 }
 
 /*
@@ -988,9 +955,7 @@ CommitTsPagePrecedes(int64 page1, int64 page2)
 static void
 WriteZeroPageXlogRec(int64 pageno)
 {
-	XLogBeginInsert();
-	XLogRegisterData(&pageno, sizeof(pageno));
-	(void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_ZEROPAGE);
+	XLogSimpleInsert(pageno, RM_COMMIT_TS_ID, COMMIT_TS_ZEROPAGE);
 }
 
 /*
@@ -1023,19 +988,10 @@ commit_ts_redo(XLogReaderState *record)
 	if (info == COMMIT_TS_ZEROPAGE)
 	{
 		int64		pageno;
-		int			slotno;
-		LWLock	   *lock;
-
 		memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
-
-		lock = SimpleLruGetBankLock(CommitTsCtl, pageno);
-		LWLockAcquire(lock, LW_EXCLUSIVE);
-
-		slotno = ZeroCommitTsPage(pageno, false);
-		SimpleLruWritePage(CommitTsCtl, slotno);
-		Assert(!CommitTsCtl->shared->page_dirty[slotno]);
-
-		LWLockRelease(lock);
+		
+		/* Zero the page, don't make an XLOG entry about it, write the page on a disk */
+		BootStrapSlruPage(CommitTsCtl, pageno, 0, true);
 	}
 	else if (info == COMMIT_TS_TRUNCATE)
 	{
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index c1e2c42e1bb..c559447f3d9 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -401,8 +401,6 @@ static void mXactCachePut(MultiXactId multi, int nmembers,
 static char *mxstatus_to_string(MultiXactStatus status);
 
 /* management of SLRU infrastructure */
-static int	ZeroMultiXactOffsetPage(int64 pageno, bool writeXlog);
-static int	ZeroMultiXactMemberPage(int64 pageno, bool writeXlog);
 static bool MultiXactOffsetPagePrecedes(int64 page1, int64 page2);
 static bool MultiXactMemberPagePrecedes(int64 page1, int64 page2);
 static bool MultiXactOffsetPrecedes(MultiXactOffset offset1,
@@ -413,7 +411,9 @@ static bool MultiXactOffsetWouldWrap(MultiXactOffset boundary,
 									 MultiXactOffset start, uint32 distance);
 static bool SetOffsetVacuumLimit(bool is_startup);
 static bool find_multixact_start(MultiXactId multi, MultiXactOffset *result);
-static void WriteMZeroPageXlogRec(int64 pageno, uint8 info);
+static inline void WriteMZeroPageXlogRec(int64 pageno, uint8 info);
+static void WriteMMembersZeroPageXlogRec(int64 pageno);
+static void WriteMOffserZeroPageXlogRec(int64 pageno);
 static void WriteMTruncateXlogRec(Oid oldestMultiDB,
 								  MultiXactId startTruncOff,
 								  MultiXactId endTruncOff,
@@ -2033,70 +2033,12 @@ check_multixact_member_buffers(int *newval, void **extra, GucSource source)
 void
 BootStrapMultiXact(void)
 {
-	int			slotno;
-	LWLock	   *lock;
-
-	lock = SimpleLruGetBankLock(MultiXactOffsetCtl, 0);
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Create and zero the first page of the offsets log */
-	slotno = ZeroMultiXactOffsetPage(0, false);
-
-	/* Make sure it's written out */
-	SimpleLruWritePage(MultiXactOffsetCtl, slotno);
-	Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
-
-	LWLockRelease(lock);
-
-	lock = SimpleLruGetBankLock(MultiXactMemberCtl, 0);
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Create and zero the first page of the members log */
-	slotno = ZeroMultiXactMemberPage(0, false);
-
-	/* Make sure it's written out */
-	SimpleLruWritePage(MultiXactMemberCtl, slotno);
-	Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
-
-	LWLockRelease(lock);
-}
-
-/*
- * Initialize (or reinitialize) a page of MultiXactOffset to zeroes.
- * If writeXlog is true, also emit an XLOG record saying we did this.
- *
- * The page is not actually written, just set up in shared memory.
- * The slot number of the new page is returned.
- *
- * Control lock must be held at entry, and will be held at exit.
- */
-static int
-ZeroMultiXactOffsetPage(int64 pageno, bool writeXlog)
-{
-	int			slotno;
-
-	slotno = SimpleLruZeroPage(MultiXactOffsetCtl, pageno);
-
-	if (writeXlog)
-		WriteMZeroPageXlogRec(pageno, XLOG_MULTIXACT_ZERO_OFF_PAGE);
-
-	return slotno;
-}
-
-/*
- * Ditto, for MultiXactMember
- */
-static int
-ZeroMultiXactMemberPage(int64 pageno, bool writeXlog)
-{
-	int			slotno;
-
-	slotno = SimpleLruZeroPage(MultiXactMemberCtl, pageno);
-
-	if (writeXlog)
-		WriteMZeroPageXlogRec(pageno, XLOG_MULTIXACT_ZERO_MEM_PAGE);
-
-	return slotno;
+	/*
+	 * Nullify the page (pageno = 0), don't insert an XLog record, 
+	 * save the page on a disk
+	 */
+	BootStrapSlruPage(MultiXactOffsetCtl, 0, 0, true);
+	BootStrapSlruPage(MultiXactMemberCtl, 0, 0, true);
 }
 
 /*
@@ -2134,7 +2076,7 @@ MaybeExtendOffsetSlru(void)
 		 * with creating a new segment file even if the page we're writing is
 		 * not the first in it, so this is enough.
 		 */
-		slotno = ZeroMultiXactOffsetPage(pageno, false);
+		slotno = SimpleLruZeroPage(MultiXactOffsetCtl, pageno);
 		SimpleLruWritePage(MultiXactOffsetCtl, slotno);
 	}
 
@@ -2553,7 +2495,6 @@ static void
 ExtendMultiXactOffset(MultiXactId multi)
 {
 	int64		pageno;
-	LWLock	   *lock;
 
 	/*
 	 * No work except at first MultiXactId of a page.  But beware: just after
@@ -2564,14 +2505,8 @@ ExtendMultiXactOffset(MultiXactId multi)
 		return;
 
 	pageno = MultiXactIdToOffsetPage(multi);
-	lock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
-
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Zero the page and make an XLOG entry about it */
-	ZeroMultiXactOffsetPage(pageno, true);
-
-	LWLockRelease(lock);
+	/* Zero the page, make an XLOG entry about it, don't write the page on a disk */
+	BootStrapSlruPage(MultiXactOffsetCtl, pageno, WriteMOffserZeroPageXlogRec, false);
 }
 
 /*
@@ -2604,17 +2539,9 @@ ExtendMultiXactMember(MultiXactOffset offset, int nmembers)
 		if (flagsoff == 0 && flagsbit == 0)
 		{
 			int64		pageno;
-			LWLock	   *lock;
-
 			pageno = MXOffsetToMemberPage(offset);
-			lock = SimpleLruGetBankLock(MultiXactMemberCtl, pageno);
-
-			LWLockAcquire(lock, LW_EXCLUSIVE);
-
-			/* Zero the page and make an XLOG entry about it */
-			ZeroMultiXactMemberPage(pageno, true);
-
-			LWLockRelease(lock);
+			/* Zero the page, make an XLOG entry about it, don't write the page on a disk */
+			BootStrapSlruPage(MultiXactMemberCtl, pageno, WriteMMembersZeroPageXlogRec, false);
 		}
 
 		/*
@@ -3351,12 +3278,28 @@ MultiXactOffsetPrecedes(MultiXactOffset offset1, MultiXactOffset offset2)
  * Write an xlog record reflecting the zeroing of either a MEMBERs or
  * OFFSETs page (info shows which)
  */
-static void
+static inline void
 WriteMZeroPageXlogRec(int64 pageno, uint8 info)
 {
-	XLogBeginInsert();
-	XLogRegisterData(&pageno, sizeof(pageno));
-	(void) XLogInsert(RM_MULTIXACT_ID, info);
+	XLogSimpleInsert(pageno, RM_MULTIXACT_ID, info);
+}
+
+/*
+ * Write a ZEROPAGE xlog record of MEMBERs page
+ */
+static void
+WriteMMembersZeroPageXlogRec(int64 pageno)
+{
+	WriteMZeroPageXlogRec(pageno, XLOG_MULTIXACT_ZERO_MEM_PAGE);
+}
+
+/*
+ * Write a ZEROPAGE xlog record of OFFSETs page
+ */
+static void
+WriteMOffserZeroPageXlogRec(int64 pageno)
+{
+	WriteMZeroPageXlogRec(pageno, XLOG_MULTIXACT_ZERO_OFF_PAGE);
 }
 
 /*
@@ -3401,36 +3344,18 @@ multixact_redo(XLogReaderState *record)
 	if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
 	{
 		int64		pageno;
-		int			slotno;
-		LWLock	   *lock;
-
 		memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
-
-		lock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
-		LWLockAcquire(lock, LW_EXCLUSIVE);
-
-		slotno = ZeroMultiXactOffsetPage(pageno, false);
-		SimpleLruWritePage(MultiXactOffsetCtl, slotno);
-		Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
-
-		LWLockRelease(lock);
+		/* Zero the page, don't make an XLOG entry about it, 
+		 * write the page on a disk */
+		BootStrapSlruPage(MultiXactOffsetCtl, pageno, 0, true);
 	}
 	else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
 	{
 		int64		pageno;
-		int			slotno;
-		LWLock	   *lock;
-
 		memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
-
-		lock = SimpleLruGetBankLock(MultiXactMemberCtl, pageno);
-		LWLockAcquire(lock, LW_EXCLUSIVE);
-
-		slotno = ZeroMultiXactMemberPage(pageno, false);
-		SimpleLruWritePage(MultiXactMemberCtl, slotno);
-		Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
-
-		LWLockRelease(lock);
+		/* Zero the page, don't make an XLOG entry about it, 
+		 * write the page on a disk */
+		BootStrapSlruPage(MultiXactMemberCtl, pageno, 0, true);
 	}
 	else if (info == XLOG_MULTIXACT_CREATE_ID)
 	{
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 9ce628e62a5..e6c701121f3 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -190,7 +190,6 @@ static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename,
 static void SlruInternalDeleteSegment(SlruCtl ctl, int64 segno);
 static inline void SlruRecentlyUsed(SlruShared shared, int slotno);
 
-
 /*
  * Initialization of shared memory
  */
@@ -363,6 +362,50 @@ check_slru_buffers(const char *name, int *newval)
 	return false;
 }
 
+/*
+ * BootStrapSlruPage is one of the functions nullifying a SLRU page. 
+ * It performs:
+ * 		1. locking,
+ * 		2. nullifying,
+ * 		3. logging (optionally),
+ * 		4. writing out (optionally),
+ * 		5. releasing the lock.
+ *
+ * XLogInsertFunc is a parameter pointing to a function emitting an XLog
+ * record. The implementation of this function usually enclosed in 
+ * a corresponding SLRU-page module (commit_ts.c, multixaxt.c and others).
+ * If XLogInsertFunc equals to zero, XLog record emition is not going to 
+ * be accomplished. Caller must provide a correct XLogInsertFunc pointer
+ * or provide its equality to zero.  
+ * 
+ * The writePage parameter commands whether to write a page on a disk or not.
+ */
+void
+BootStrapSlruPage(SlruCtl ctl, int64 pageno,
+				  void (*XLogInsertFunc)(int64 pageno), bool writePage)
+{
+	int			slotno;
+	LWLock	   *lock;
+
+	lock = SimpleLruGetBankLock(ctl, pageno);
+	LWLockAcquire(lock, LW_EXCLUSIVE);
+
+	/* Create and zero the page*/
+	slotno = SimpleLruZeroPage(ctl, pageno);
+	
+	if (XLogInsertFunc)
+		XLogInsertFunc(pageno);
+
+	if (writePage != 0)
+	{
+		/* Make sure it's written out */
+		SimpleLruWritePage(ctl, slotno);
+		Assert(!ctl->shared->page_dirty[slotno]);
+	}
+
+	LWLockRelease(lock);
+}
+
 /*
  * Initialize (or reinitialize) a page to zeroes.
  *
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index 15153618fad..66f8301ef3d 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -74,7 +74,6 @@ static SlruCtlData SubTransCtlData;
 #define SubTransCtl  (&SubTransCtlData)
 
 
-static int	ZeroSUBTRANSPage(int64 pageno);
 static bool SubTransPagePrecedes(int64 page1, int64 page2);
 
 
@@ -269,33 +268,11 @@ check_subtrans_buffers(int *newval, void **extra, GucSource source)
 void
 BootStrapSUBTRANS(void)
 {
-	int			slotno;
-	LWLock	   *lock = SimpleLruGetBankLock(SubTransCtl, 0);
-
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Create and zero the first page of the subtrans log */
-	slotno = ZeroSUBTRANSPage(0);
-
-	/* Make sure it's written out */
-	SimpleLruWritePage(SubTransCtl, slotno);
-	Assert(!SubTransCtl->shared->page_dirty[slotno]);
-
-	LWLockRelease(lock);
-}
-
-/*
- * Initialize (or reinitialize) a page of SUBTRANS to zeroes.
- *
- * The page is not actually written, just set up in shared memory.
- * The slot number of the new page is returned.
- *
- * Control lock must be held at entry, and will be held at exit.
- */
-static int
-ZeroSUBTRANSPage(int64 pageno)
-{
-	return SimpleLruZeroPage(SubTransCtl, pageno);
+	/*
+	 * Nullify the page (pageno = 0), don't insert an XLog record, 
+	 * save the page on a disk
+	 */
+	BootStrapSlruPage(SubTransCtl, 0, 0, true);
 }
 
 /*
@@ -335,7 +312,7 @@ StartupSUBTRANS(TransactionId oldestActiveXID)
 			prevlock = lock;
 		}
 
-		(void) ZeroSUBTRANSPage(startPage);
+		(void) SimpleLruZeroPage(SubTransCtl, startPage);
 		if (startPage == endPage)
 			break;
 
@@ -379,7 +356,6 @@ void
 ExtendSUBTRANS(TransactionId newestXact)
 {
 	int64		pageno;
-	LWLock	   *lock;
 
 	/*
 	 * No work except at first XID of a page.  But beware: just after
@@ -391,13 +367,11 @@ ExtendSUBTRANS(TransactionId newestXact)
 
 	pageno = TransactionIdToPage(newestXact);
 
-	lock = SimpleLruGetBankLock(SubTransCtl, pageno);
-	LWLockAcquire(lock, LW_EXCLUSIVE);
-
-	/* Zero the page */
-	ZeroSUBTRANSPage(pageno);
-
-	LWLockRelease(lock);
+	/*
+	 * Zero the page, don't make an XLOG entry about it,
+	 * don't write the page on a disk
+	 */
+	BootStrapSlruPage(SubTransCtl, pageno, 0, false);
 }
 
 
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 14d583ae7ae..4a62e63cf92 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -1390,3 +1390,17 @@ InitXLogInsert(void)
 		hdr_scratch = MemoryContextAllocZero(xloginsert_cxt,
 											 HEADER_SCRATCH_SIZE);
 }
+
+/*
+ * Write a simple xlog record.
+ *
+ * Useful for SLRU zeropages. In this case the simpledata is usually the number of 
+ * a nullified SLRU page.
+ */
+void
+XLogSimpleInsert(int64 simpledata, RmgrId rmid, uint8 info)
+{
+	XLogBeginInsert();
+	XLogRegisterData(&simpledata, sizeof(simpledata));
+	(void) XLogInsert(rmid, info);
+}
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index e142800aab2..275c99b6131 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -186,6 +186,8 @@ extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
 						  const char *subdir, int buffer_tranche_id,
 						  int bank_tranche_id, SyncRequestHandler sync_handler,
 						  bool long_segment_names);
+extern void BootStrapSlruPage(SlruCtl ctl, int64 pageno,
+					void (*XLogInsertFunc)(int64 pageno), bool writePage);
 extern int	SimpleLruZeroPage(SlruCtl ctl, int64 pageno);
 extern int	SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok,
 							  TransactionId xid);
diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h
index cf057f033a2..249092e27d5 100644
--- a/src/include/access/xloginsert.h
+++ b/src/include/access/xloginsert.h
@@ -64,5 +64,6 @@ extern void log_newpage_range(Relation rel, ForkNumber forknum,
 extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std);
 
 extern void InitXLogInsert(void);
+extern void XLogSimpleInsert(int64 simpledata, RmgrId rmid, uint8 info);
 
 #endif							/* XLOGINSERT_H */
-- 
2.48.1

