Hello hackers!
> I think the overall idea here is good, but I didn't like the new
> WriteSlruZeroPageXlogRec helper function; it looks too much like a
> modularity violation (same for the fact that you have to pass the rmid
> and info from each caller into slru.c). I would not do that in slru.c
> but instead in every individual caller, and have this helper function in
> xloginsert.c where it can be caller XLogSimpleInsert or something like
> that.
Thank you Alvaro! I got your ideas and have tried to implement them.
In the v4 patch version:
1) WriteSlruZeroPageXlogRec has been renamed into XLogSimpleInsert and
moved to the xloginset.c.
2) With the purpose of excluding passing any resource manager’s
information into the slru.c module I propose to pass into the
BootStrapSlruPage the XLogInsertFunc parameter pointing to a function
accomplishing insertion of an XLog record. Implementations of these
functions are enclosed in a corresponding slru-page module (commit_ts.c,
multixaxt.c and so on). It preserves original modularity - the
BootStrapSlruPage and the slru.c still do not know anything about
resource managers. If the XLogInsertFunc parameter equals zero,
BootStrapSlruPage will not try to perform XLog recording.
3) In addition, let’s also implement in the BootStrapSlruPage a new
parameter writePage. It commands whether to write a page onto a disk or
not. As a result, the BootStrapSlruPage become apt to be used in a
larger number of places of code.
> Also, please do not document a bunch of functions together in a single
> comment. Instead, have one comment for each function.
> This is not our style, and I don't think it's very ergonomical.
I got it. And since
4) The SimpleLruZeroAndLogPage is subject to deletion now.
comments are formatted as well.
> sometimes I read source from bottom to top
Probably, we all should profess this approach!
Best regards,
Evgeny Voropaev,
Tantor Labs LLC.
From 885c15ba379da4fd5f0dd71ee4dc9b5e31108d6f Mon Sep 17 00:00:00 2001
From: Evgeny Voropaev <evo...@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.vorop...@tantorlabs.com> <evo...@gmail.com>
Reviewed by: Álvaro Herrera <alvhe...@alvh.no-ip.org>
Reviewed by: Andrey Borodin <x4...@yandex-team.ru>
Reviewed by: Aleksander Alekseev <aleksan...@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