From 0328cad69ef7504ef7876c46a834be06973c7ca7 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Fri, 12 Nov 2021 12:30:10 -0800 Subject: [PATCH v1] Clear up ndeleted pgstats accounting. --- src/include/access/heapam.h | 2 +- src/backend/access/heap/pruneheap.c | 45 +++++++++++++++++----------- src/backend/access/heap/vacuumlazy.c | 3 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index e63b49fc3..417dd288e 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -186,7 +186,7 @@ extern int heap_page_prune(Relation relation, Buffer buffer, struct GlobalVisState *vistest, TransactionId old_snap_xmin, TimestampTz old_snap_ts_ts, - bool report_stats, + int *nnewlpdead, OffsetNumber *off_loc); extern void heap_page_prune_execute(Buffer buffer, OffsetNumber *redirected, int nredirected, diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 50ed76198..58991696b 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -182,10 +182,29 @@ heap_page_prune_opt(Relation relation, Buffer buffer) */ if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree) { - /* OK to prune */ - (void) heap_page_prune(relation, buffer, vistest, - limited_xmin, limited_ts, - true, NULL); + int nnewlpdead, + ndeleted; + + ndeleted = heap_page_prune(relation, buffer, vistest, limited_xmin, + limited_ts, &nnewlpdead, NULL); + + /* + * Report the number of tuples reclaimed to pgstats. This is + * ndeleted minus the number of newly-LP_DEAD-set items. + * + * We derive the number of dead tuples we have removed like this + * because we don't want to totally forget about items that were + * set to LP_DEAD, just because they no longer have tuple storage. + * We only want to count heap-only tuples that just became + * LP_UNUSED in our report. + * + * VACUUM doesn't have to compensate in the same way when it + * consumes ndeleted, since it will set the LP_DEAD items to + * LP_UNUSED in the near future anyway (after index vacuuming). + */ + if (ndeleted > nnewlpdead) + pgstat_update_heap_dead_tuples(relation, + ndeleted - nnewlpdead); } /* And release buffer lock */ @@ -212,10 +231,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer) * either have been set by TransactionIdLimitedForOldSnapshots, or * InvalidTransactionId/0 respectively. * - * If report_stats is true then we send the number of reclaimed heap-only - * tuples to pgstats. (This must be false during vacuum, since vacuum will - * send its own new total to pgstats, and we don't want this delta applied - * on top of that.) + * Sets *nnewlpdead for caller, indicating the number of items that were newly + * set to LP_DEAD during the prune. * * off_loc is the offset location required by the caller to use in error * callback. @@ -227,7 +244,7 @@ heap_page_prune(Relation relation, Buffer buffer, GlobalVisState *vistest, TransactionId old_snap_xmin, TimestampTz old_snap_ts, - bool report_stats, + int *nnewlpdead, OffsetNumber *off_loc) { int ndeleted = 0; @@ -285,6 +302,8 @@ heap_page_prune(Relation relation, Buffer buffer, ndeleted += heap_prune_chain(buffer, offnum, &prstate); } + /* Set number of newly-set-LP_DEAD items for caller */ + *nnewlpdead = prstate.ndead; /* Clear the offset information once we have processed the given page. */ if (off_loc) *off_loc = InvalidOffsetNumber; @@ -381,14 +400,6 @@ heap_page_prune(Relation relation, Buffer buffer, END_CRIT_SECTION(); - /* - * If requested, report the number of tuples reclaimed to pgstats. This is - * ndeleted minus ndead, because we don't want to count a now-DEAD root - * item as a deletion for this purpose. - */ - if (report_stats && ndeleted > prstate.ndead) - pgstat_update_heap_dead_tuples(relation, ndeleted - prstate.ndead); - return ndeleted; } diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 1dd162ab9..4ee1f1485 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -1712,6 +1712,7 @@ lazy_scan_prune(LVRelState *vacrel, new_dead_tuples, num_tuples, live_tuples; + int nnewlpdead; int nfrozen; OffsetNumber deadoffsets[MaxHeapTuplesPerPage]; xl_heap_freeze_tuple frozen[MaxHeapTuplesPerPage]; @@ -1737,7 +1738,7 @@ retry: * that were deleted from indexes. */ tuples_deleted = heap_page_prune(rel, buf, vistest, - InvalidTransactionId, 0, false, + InvalidTransactionId, 0, &nnewlpdead, &vacrel->offnum); /* -- 2.30.2