v1-0001-Elimination-of-the-repetitive-code-at-SLRU-bootst.patch
text/x-patch
Filename: v1-0001-Elimination-of-the-repetitive-code-at-SLRU-bootst.patch
Type: text/x-patch
Part: 0
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 v1-0001
Subject: Elimination of the repetitive code at the SLRU bootstrap functions.
| File | + | − |
|---|---|---|
| src/backend/access/transam/clog.c | 10 | 33 |
| src/backend/access/transam/commit_ts.c | 9 | 29 |
| src/backend/access/transam/multixact.c | 12 | 59 |
| src/backend/access/transam/slru.c | 34 | 0 |
| src/backend/access/transam/subtrans.c | 14 | 21 |
| src/include/access/slru.h | 8 | 0 |
From 62762bf4a86af76d845755e41f46714d2b41bbe4 Mon Sep 17 00:00:00 2001
From: Evgeny Voropaev <evorop@gmail.com>
Date: Thu, 13 Feb 2025 12:43:20 +0800
Subject: [PATCH v1] Elimination of the repetitive code at the SLRU bootstrap
functions.
The functions bootstrapping SLRU pages had a lot of repetitive code. A new
realized function BootStrapSlruPage has moved a duplicating code into the
single place. Additionally, a new member ZeroFunc has been implemented in the
SlruCtlData structure. The ZeroFunc keeps a pointer to a function proper
for nullifying SLRU pages of a type defined by a corresponding SlruCtlData
object.
Author: Evgeny Voropaev <evgeny.voropaev@tantorlabs.com> <evorop@gmail.com>
---
src/backend/access/transam/clog.c | 43 ++++------------
src/backend/access/transam/commit_ts.c | 38 ++++----------
src/backend/access/transam/multixact.c | 71 +++++---------------------
src/backend/access/transam/slru.c | 34 ++++++++++++
src/backend/access/transam/subtrans.c | 35 +++++--------
src/include/access/slru.h | 8 +++
6 files changed, 87 insertions(+), 142 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 0d556c00b8c..d02a80378a1 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -102,14 +102,6 @@ TransactionIdToPage(TransactionId xid)
*/
#define THRESHOLD_SUBTRANS_CLOG_OPT 5
-/*
- * Link to shared-memory data structures for CLOG control
- */
-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);
@@ -130,6 +122,14 @@ static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids,
XLogRecPtr lsn, int64 pageno);
+/*
+ * Link to shared-memory data structures for CLOG control
+ */
+static SlruCtlData XactCtlData = { .ZeroPage = ZeroCLOGPage };
+
+#define XactCtl (&XactCtlData)
+
+
/*
* TransactionIdSetTreeStatus
*
@@ -832,19 +832,7 @@ 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);
+ BootStrapSlruPage(XactCtl, 0);
}
/*
@@ -1114,19 +1102,8 @@ 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);
+ BootStrapSlruPage(XactCtl, pageno);
}
else if (info == CLOG_TRUNCATE)
{
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 95049acd0b5..33ef6716535 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -77,13 +77,6 @@ TransactionIdToCTsPage(TransactionId xid)
#define TransactionIdToCTsEntry(xid) \
((xid) % (TransactionId) COMMIT_TS_XACTS_PER_PAGE)
-/*
- * Link to shared-memory data structures for CommitTs control
- */
-static SlruCtlData CommitTsCtlData;
-
-#define CommitTsCtl (&CommitTsCtlData)
-
/*
* We keep a cache of the last value set in shared memory.
*
@@ -121,6 +114,13 @@ static void DeactivateCommitTs(void);
static void WriteZeroPageXlogRec(int64 pageno);
static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXid);
+/*
+ * Link to shared-memory data structures for CommitTs control
+ */
+static SlruCtlData CommitTsCtlData = { .ZeroPage = ZeroCommitTsPage };
+
+#define CommitTsCtl (&CommitTsCtlData)
+
/*
* TransactionTreeSetCommitTsData
*
@@ -747,16 +747,7 @@ 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);
- }
+ BootStrapSlruPage(CommitTsCtl, pageno);
/* Change the activation status in shared memory. */
LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
@@ -1023,19 +1014,8 @@ 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);
+ BootStrapSlruPage(CommitTsCtl, pageno);
}
else if (info == COMMIT_TS_TRUNCATE)
{
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 27ccdf9500f..5fb688d19a1 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -223,15 +223,6 @@ PreviousMultiXactId(MultiXactId multi)
return multi == FirstMultiXactId ? MaxMultiXactId : multi - 1;
}
-/*
- * Links to shared-memory data structures for MultiXact control
- */
-static SlruCtlData MultiXactOffsetCtlData;
-static SlruCtlData MultiXactMemberCtlData;
-
-#define MultiXactOffsetCtl (&MultiXactOffsetCtlData)
-#define MultiXactMemberCtl (&MultiXactMemberCtlData)
-
/*
* MultiXact state shared across all backends. All this state is protected
* by MultiXactGenLock. (We also use SLRU bank's lock of MultiXactOffset and
@@ -420,6 +411,14 @@ static void WriteMTruncateXlogRec(Oid oldestMultiDB,
MultiXactOffset startTruncMemb,
MultiXactOffset endTruncMemb);
+/*
+ * Links to shared-memory data structures for MultiXact control
+ */
+static SlruCtlData MultiXactOffsetCtlData = { .ZeroPage = &ZeroMultiXactOffsetPage };
+static SlruCtlData MultiXactMemberCtlData = { .ZeroPage = &ZeroMultiXactMemberPage };
+
+#define MultiXactOffsetCtl (&MultiXactOffsetCtlData)
+#define MultiXactMemberCtl (&MultiXactMemberCtlData)
/*
* MultiXactIdCreate
@@ -2033,32 +2032,8 @@ 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);
+ BootStrapSlruPage(MultiXactOffsetCtl, 0);
+ BootStrapSlruPage(MultiXactMemberCtl, 0);
}
/*
@@ -3401,36 +3376,14 @@ 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);
+ BootStrapSlruPage(MultiXactOffsetCtl, pageno);
}
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);
+ BootStrapSlruPage(MultiXactMemberCtl, pageno);
}
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..b73bea16972 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -1850,3 +1850,37 @@ SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
errno = save_errno;
return result;
}
+
+/*
+ * BootStrapSlruPage is a workhorse for functions bootstraping
+ * SLRU pages, including:
+ * BootStrapMultiXact,
+ * BootStrapCLOG,
+ * ActivateCommitTs,
+ * multixact_redo,
+ * commit_ts_redo.
+ *
+ * It performs all of the rut such as acquiring a lock, zeroing,
+ * ensuring that bootstrapped page is written out, and releasing the lock.
+ *
+ * A caller has to provide a proper ZeroFunc in the ctl structure.
+ *
+ */
+void
+BootStrapSlruPage(SlruCtl ctl, int64 pageno)
+{
+ int slotno;
+ LWLock *lock;
+
+ lock = SimpleLruGetBankLock(ctl, pageno);
+ LWLockAcquire(lock, LW_EXCLUSIVE);
+
+ /* Create and zero the page in SLRU */
+ slotno = ctl->ZeroPage(pageno, false);
+
+ /* Make sure it's written out */
+ SimpleLruWritePage(ctl, slotno);
+ Assert(!ctl->shared->page_dirty[slotno]);
+
+ LWLockRelease(lock);
+}
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index 15153618fad..bad2c15951b 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -66,18 +66,18 @@ TransactionIdToPage(TransactionId xid)
#define TransactionIdToEntry(xid) ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)
+static int ZeroSUBTRANSPage(int64 pageno, bool unused);
+static bool SubTransPagePrecedes(int64 page1, int64 page2);
+
+
/*
* Link to shared-memory data structures for SUBTRANS control
*/
-static SlruCtlData SubTransCtlData;
+static SlruCtlData SubTransCtlData = { .ZeroPage = ZeroSUBTRANSPage };
#define SubTransCtl (&SubTransCtlData)
-static int ZeroSUBTRANSPage(int64 pageno);
-static bool SubTransPagePrecedes(int64 page1, int64 page2);
-
-
/*
* Record the parent of a subtransaction in the subtrans log.
*/
@@ -269,19 +269,7 @@ 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);
+ BootStrapSlruPage(SubTransCtl, 0);
}
/*
@@ -291,10 +279,15 @@ BootStrapSUBTRANS(void)
* The slot number of the new page is returned.
*
* Control lock must be held at entry, and will be held at exit.
+ *
+ * bool unused is a parameter required to provide matching of the
+ * ZeroSUBTRANSPage function to the SlruCtlData.ZeroPage function type.
*/
static int
-ZeroSUBTRANSPage(int64 pageno)
+ZeroSUBTRANSPage(int64 pageno, bool unused)
{
+ (void)unused; /* Supress compiler warning*/
+
return SimpleLruZeroPage(SubTransCtl, pageno);
}
@@ -335,7 +328,7 @@ StartupSUBTRANS(TransactionId oldestActiveXID)
prevlock = lock;
}
- (void) ZeroSUBTRANSPage(startPage);
+ (void) ZeroSUBTRANSPage(startPage, false);
if (startPage == endPage)
break;
@@ -395,7 +388,7 @@ ExtendSUBTRANS(TransactionId newestXact)
LWLockAcquire(lock, LW_EXCLUSIVE);
/* Zero the page */
- ZeroSUBTRANSPage(pageno);
+ ZeroSUBTRANSPage(pageno, false);
LWLockRelease(lock);
}
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index e142800aab2..ec48355ac74 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -161,6 +161,13 @@ typedef struct SlruCtlData
* it's always the same, it doesn't need to be in shared memory.
*/
char Dir[64];
+
+ /*
+ * Function for nulifying a page pointed by this SlruCtlData object
+ * Signature:
+ * int ZeroPage(int64 pageno, bool writeXlog);
+ */
+ int (*ZeroPage) (int64, bool);
} SlruCtlData;
typedef SlruCtlData *SlruCtl;
@@ -214,5 +221,6 @@ extern bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename,
extern bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage,
void *data);
extern bool check_slru_buffers(const char *name, int *newval);
+extern void BootStrapSlruPage(SlruCtl ctl, int64 pageno);
#endif /* SLRU_H */
--
2.47.1