From 7806a193b32a20a11096815a86c405eee639baf0 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sun, 14 Feb 2021 17:38:34 -0800 Subject: [PATCH v4 3/3] Add pages_newly_deleted to VACUUM VERBOSE. pages_newly_deleted reports on the number of pages deleted by the current VACUUM operation. The pages_deleted field continues to report on the total number of deleted pages in the index (as well as pages that are recyclable due to being zeroed in rare cases), without regard to whether or not this VACUUM operation deleted them. --- src/include/access/genam.h | 11 ++++++++--- src/backend/access/gin/ginvacuum.c | 1 + src/backend/access/gist/gistvacuum.c | 4 +++- src/backend/access/heap/vacuumlazy.c | 4 +++- src/backend/access/nbtree/nbtpage.c | 4 ++++ src/backend/access/nbtree/nbtree.c | 12 +++++++++--- src/backend/access/spgist/spgvacuum.c | 1 + 7 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/include/access/genam.h b/src/include/access/genam.h index ffa1a4c80d..13971c8b2a 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -63,8 +63,12 @@ typedef struct IndexVacuumInfo * of which this is just the first field; this provides a way for ambulkdelete * to communicate additional private data to amvacuumcleanup. * - * Note: pages_deleted and pages_free refer to free space within the index - * file. Some index AMs may compute num_index_tuples by reference to + * Note: pages_newly_deleted is the number of pages in the index that were + * deleted by the current vacuum operation. pages_deleted and pages_free + * refer to free space within the index file (and so pages_deleted must be >= + * pages_newly_deleted). + * + * Note: Some index AMs may compute num_index_tuples by reference to * num_heap_tuples, in which case they should copy the estimated_count field * from IndexVacuumInfo. */ @@ -74,7 +78,8 @@ typedef struct IndexBulkDeleteResult bool estimated_count; /* num_index_tuples is an estimate */ double num_index_tuples; /* tuples remaining */ double tuples_removed; /* # removed during vacuum operation */ - BlockNumber pages_deleted; /* # unused pages in index */ + BlockNumber pages_newly_deleted; /* # pages marked deleted by us */ + BlockNumber pages_deleted; /* # pages marked deleted (could be by us) */ BlockNumber pages_free; /* # pages available for reuse */ } IndexBulkDeleteResult; diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index a0453b36cd..a276eb020b 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -231,6 +231,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn END_CRIT_SECTION(); + gvs->result->pages_newly_deleted++; gvs->result->pages_deleted++; } diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index ddecb8ab18..196678d91f 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -138,6 +138,7 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, */ stats->estimated_count = false; stats->num_index_tuples = 0; + stats->pages_newly_deleted = 0; stats->pages_deleted = 0; stats->pages_free = 0; @@ -281,8 +282,8 @@ restart: { /* Okay to recycle this page */ RecordFreeIndexPage(rel, blkno); - vstate->stats->pages_free++; vstate->stats->pages_deleted++; + vstate->stats->pages_free++; } else if (GistPageIsDeleted(page)) { @@ -636,6 +637,7 @@ gistdeletepage(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* mark the page as deleted */ MarkBufferDirty(leafBuffer); GistPageSetDeleted(leafPage, txid); + stats->pages_newly_deleted++; stats->pages_deleted++; /* remove the downlink from the parent */ diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index e9bd6dba80..7348f91a2e 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -2521,9 +2521,11 @@ lazy_cleanup_index(Relation indrel, (*stats)->num_index_tuples, (*stats)->num_pages), errdetail("%.0f index row versions were removed.\n" - "%u index pages have been deleted, %u are currently reusable.\n" + "%u index pages were deleted.\n" + "%u index pages are currently deleted, of which %u are currently reusable.\n" "%s.", (*stats)->tuples_removed, + (*stats)->pages_newly_deleted, (*stats)->pages_deleted, (*stats)->pages_free, pg_rusage_show(&ru0)))); } diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 408230cb67..f5aa061254 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -2677,11 +2677,15 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, _bt_relbuf(rel, buf); /* + * Maintain pages_newly_deleted, which is simply the number of pages + * deleted by the ongoing VACUUM operation. + * * Maintain pages_deleted in a way that takes into account how * btvacuumpage() will count deleted pages that have yet to become * scanblkno -- only count page when it's not going to get that treatment * later on. */ + stats->pages_newly_deleted++; if (target <= scanblkno) stats->pages_deleted++; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index c3b32bb71c..b9ba521acd 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -922,6 +922,9 @@ _bt_newly_deleted_pages_recycle(Relation rel, BTVacState *vstate) { IndexBulkDeleteResult *stats = vstate->stats; + Assert(vstate->ndeleted > 0); + Assert(stats->pages_newly_deleted >= vstate->ndeleted); + /* Recompute VACUUM XID boundaries */ (void) GetOldestNonRemovableTransactionId(NULL); @@ -1057,6 +1060,7 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, stats->estimated_count = false; stats->num_index_tuples = 0; stats->tuples_removed = 0; + stats->pages_newly_deleted = 0; stats->pages_deleted = 0; stats->pages_free = 0; @@ -1307,8 +1311,8 @@ backtrack: else if (P_ISHALFDEAD(opaque)) { /* - * Half-dead leaf page. Try to delete now. Might update - * pages_deleted below. + * Half-dead leaf page. Try to delete now. Might end up incrementing + * pages_newly_deleted/pages_deleted inside _bt_pagedel. */ attempt_pagedel = true; } @@ -1520,7 +1524,9 @@ backtrack: oldcontext = MemoryContextSwitchTo(vstate->pagedelcontext); /* - * _bt_pagedel maintains the bulk delete stats on our behalf + * _bt_pagedel maintains the bulk delete stats on our behalf; + * pages_newly_deleted and pages_deleted are likely to be incremented + * during call */ Assert(blkno == scanblkno); _bt_pagedel(rel, buf, vstate); diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c index 0d02a02222..a9ffca5183 100644 --- a/src/backend/access/spgist/spgvacuum.c +++ b/src/backend/access/spgist/spgvacuum.c @@ -891,6 +891,7 @@ spgvacuumscan(spgBulkDeleteState *bds) /* Report final stats */ bds->stats->num_pages = num_pages; + bds->stats->pages_newly_deleted = bds->stats->pages_deleted; bds->stats->pages_free = bds->stats->pages_deleted; } -- 2.27.0