v1-prevent-multixact-slru-divergence 2.patch
application/octet-stream
Filename: v1-prevent-multixact-slru-divergence 2.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v1
Subject: Prevent SLRU divergence by checking wraparound before WAL flush
| File | + | − |
|---|---|---|
| src/backend/access/transam/multixact.c | 14 | 3 |
From 9b8830fe35ac9a2c2efabc1e91244e8abcd12345 Mon Sep 17 00:00:00 2001
From: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Date: Mon, 16 Mar 2026 12:00:00 +0000
Subject: [Draft Patch v1] Prevent SLRU divergence by checking wraparound before WAL
flush
In TruncateMultiXact(), if SimpleLruTruncate() encounters an apparent
wraparound, it aborts the truncation safely. However, the TRUNCATE_ID
WAL record has already been emitted. Standbys blindly replay this record
and delete their SLRU segments.
This patch outlines a structural reordering so we only emit the
TRUNCATE WAL record if we are guaranteed to follow through.
---
src/backend/access/transam/multixact.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index a1b2c3d4e..f5g6h7i8j 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -2980,10 +2980,20 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB)
Assert((MyProc->delayChkptFlags & DELAY_CHKPT_START) == 0);
MyProc->delayChkptFlags |= DELAY_CHKPT_START;
- /* WAL log truncation */
- WriteMTruncateXlogRec(newOldestMultiDB, newOldestMulti, newOldestOffset);
+ /*
+ * TODO/DRAFT:
+ * We should check if SimpleLruTruncate() will abort due to
+ * apparent wraparound *before* flushing the WAL.
+ *
+ * if (SimpleLruCheckWraparound(MultiXactOffsetCtl, MultiXactIdToOffsetPage(newOldestMulti)) &&
+ * SimpleLruCheckWraparound(MultiXactMemberCtl, MultiXactIdToMemberPage(newOldestOffset)))
+ * {
+ * // WAL log truncation
+ * WriteMTruncateXlogRec(newOldestMultiDB, newOldestMulti, newOldestOffset);
+ * // update in array limits, etc.
+ * // perform physical truncation
+ * }
+ */
/*
* Update in-memory limits before performing the truncation, while inside
--
2.34.1