From b584717e9de72c1ac084698453667cb301551e36 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 21 Mar 2023 14:40:43 -0700 Subject: [PATCH v1] Record which PRUNE records are from VACUUM. --- src/include/access/heapam.h | 2 +- src/include/access/heapam_xlog.h | 8 +++++++- src/backend/access/heap/pruneheap.c | 25 +++++++++++++++---------- src/backend/access/rmgrdesc/heapdesc.c | 3 +++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index faf502651..2eedd7efd 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -289,7 +289,7 @@ extern int heap_page_prune(Relation relation, Buffer buffer, TransactionId old_snap_xmin, TimestampTz old_snap_ts, int *nnewlpdead, - OffsetNumber *off_loc); + OffsetNumber *off_loc_vacuum); extern void heap_page_prune_execute(Buffer buffer, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h index a2c67d1cd..3372d1938 100644 --- a/src/include/access/heapam_xlog.h +++ b/src/include/access/heapam_xlog.h @@ -48,7 +48,7 @@ * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes * are associated with RM_HEAP2_ID, but are not logically different from * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to - * these, too. + * these, too. The BYVACUUM bit is used in place of RM_HEAP_ID's init bit. */ #define XLOG_HEAP2_REWRITE 0x00 #define XLOG_HEAP2_PRUNE 0x10 @@ -59,6 +59,12 @@ #define XLOG_HEAP2_LOCK_UPDATED 0x60 #define XLOG_HEAP2_NEW_CID 0x70 +/* + * RM_HEAP2_ID operations that take place during VACUUM set the BYVACUUM bit + * as instrumentation. Only set in XLOG_HEAP2_PRUNE records, for now. + */ +#define XLOG_HEAP2_BYVACUUM 0x80 + /* * xl_heap_insert/xl_heap_multi_insert flag values, 8 bits are available. */ diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 4e65cbcad..5f4ef384e 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -257,8 +257,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer) * Sets *nnewlpdead for caller, indicating the number of items that were * newly set LP_DEAD during prune operation. * - * off_loc is the offset location required by the caller to use in error - * callback. + * off_loc_vacuum is the offset location required by VACUUM caller to use in + * error callback. Opportunistic pruning caller should pass NULL. * * Returns the number of tuples deleted from the page during this call. */ @@ -268,7 +268,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId old_snap_xmin, TimestampTz old_snap_ts, int *nnewlpdead, - OffsetNumber *off_loc) + OffsetNumber *off_loc_vacuum) { int ndeleted = 0; Page page = BufferGetPage(buffer); @@ -345,8 +345,8 @@ heap_page_prune(Relation relation, Buffer buffer, * Set the offset number so that we can display it along with any * error that occurred while processing this tuple. */ - if (off_loc) - *off_loc = offnum; + if (off_loc_vacuum) + *off_loc_vacuum = offnum; prstate.htsv[offnum] = heap_prune_satisfies_vacuum(&prstate, &tup, buffer); @@ -364,8 +364,8 @@ heap_page_prune(Relation relation, Buffer buffer, continue; /* see preceding loop */ - if (off_loc) - *off_loc = offnum; + if (off_loc_vacuum) + *off_loc_vacuum = offnum; /* Nothing to do if slot is empty or already dead */ itemid = PageGetItemId(page, offnum); @@ -377,8 +377,8 @@ heap_page_prune(Relation relation, Buffer buffer, } /* Clear the offset information once we have processed the given page. */ - if (off_loc) - *off_loc = InvalidOffsetNumber; + if (off_loc_vacuum) + *off_loc_vacuum = InvalidOffsetNumber; /* Any error while applying the changes is critical */ START_CRIT_SECTION(); @@ -416,6 +416,7 @@ heap_page_prune(Relation relation, Buffer buffer, if (RelationNeedsWAL(relation)) { xl_heap_prune xlrec; + uint8 info = XLOG_HEAP2_PRUNE; XLogRecPtr recptr; xlrec.snapshotConflictHorizon = prstate.snapshotConflictHorizon; @@ -445,7 +446,11 @@ heap_page_prune(Relation relation, Buffer buffer, XLogRegisterBufData(0, (char *) prstate.nowunused, prstate.nunused * sizeof(OffsetNumber)); - recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_PRUNE); + /* Set bit indicating pruning by VACUUM where appropriate */ + if (off_loc_vacuum) + info |= XLOG_HEAP2_BYVACUUM; + + recptr = XLogInsert(RM_HEAP2_ID, info); PageSetLSN(BufferGetPage(buffer), recptr); } diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c index 628f7e821..9231b7411 100644 --- a/src/backend/access/rmgrdesc/heapdesc.c +++ b/src/backend/access/rmgrdesc/heapdesc.c @@ -235,6 +235,9 @@ heap2_identify(uint8 info) case XLOG_HEAP2_PRUNE: id = "PRUNE"; break; + case XLOG_HEAP2_PRUNE | XLOG_HEAP2_BYVACUUM: + id = "PRUNE+BYVACUUM"; + break; case XLOG_HEAP2_VACUUM: id = "VACUUM"; break; -- 2.39.2