Skip to content

Commit 792238c

Browse files
Fix missing FSM vacuum opportunities on tables without indexes.
Commit c120550 optimized the vacuuming of relations without indexes (a.k.a. one-pass strategy) by directly marking dead item IDs as LP_UNUSED. However, the periodic FSM vacuum was still checking if dead item IDs had been marked as LP_DEAD when attempting to vacuum the FSM every VACUUM_FSM_EVERY_PAGES blocks. This condition was never met due to the optimization, resulting in missed FSM vacuum opportunities. This commit modifies the periodic FSM vacuum condition to use the number of tuples deleted during HOT pruning. This count includes items marked as either LP_UNUSED or LP_REDIRECT, both of which are expected to result in new free space to report. Back-patch to v17 where the vacuum optimization for tables with no indexes was introduced. Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Discussion: https://postgr.es/m/CAD21AoBL8m6B9GSzQfYxVaEgvD7-Kr3AJaS-hJPHC+avm-29zw@mail.gmail.com Backpatch-through: 17
1 parent 0740034 commit 792238c

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static void find_next_unskippable_block(LVRelState *vacrel, bool *skipsallvis);
235235
static bool lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf,
236236
BlockNumber blkno, Page page,
237237
bool sharelock, Buffer vmbuffer);
238-
static void lazy_scan_prune(LVRelState *vacrel, Buffer buf,
238+
static int lazy_scan_prune(LVRelState *vacrel, Buffer buf,
239239
BlockNumber blkno, Page page,
240240
Buffer vmbuffer, bool all_visible_according_to_vm,
241241
bool *has_lpdead_items);
@@ -844,6 +844,7 @@ lazy_scan_heap(LVRelState *vacrel)
844844
{
845845
Buffer buf;
846846
Page page;
847+
int ndeleted = 0;
847848
bool has_lpdead_items;
848849
bool got_cleanup_lock = false;
849850

@@ -973,9 +974,9 @@ lazy_scan_heap(LVRelState *vacrel)
973974
* line pointers previously marked LP_DEAD.
974975
*/
975976
if (got_cleanup_lock)
976-
lazy_scan_prune(vacrel, buf, blkno, page,
977-
vmbuffer, all_visible_according_to_vm,
978-
&has_lpdead_items);
977+
ndeleted = lazy_scan_prune(vacrel, buf, blkno, page,
978+
vmbuffer, all_visible_according_to_vm,
979+
&has_lpdead_items);
979980

980981
/*
981982
* Now drop the buffer lock and, potentially, update the FSM.
@@ -1011,7 +1012,7 @@ lazy_scan_heap(LVRelState *vacrel)
10111012
* table has indexes. There will only be newly-freed space if we
10121013
* held the cleanup lock and lazy_scan_prune() was called.
10131014
*/
1014-
if (got_cleanup_lock && vacrel->nindexes == 0 && has_lpdead_items &&
1015+
if (got_cleanup_lock && vacrel->nindexes == 0 && ndeleted > 0 &&
10151016
blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
10161017
{
10171018
FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
@@ -1402,8 +1403,10 @@ cmpOffsetNumbers(const void *a, const void *b)
14021403
*
14031404
* *has_lpdead_items is set to true or false depending on whether, upon return
14041405
* from this function, any LP_DEAD items are still present on the page.
1406+
*
1407+
* Returns the number of tuples deleted from the page during HOT pruning.
14051408
*/
1406-
static void
1409+
static int
14071410
lazy_scan_prune(LVRelState *vacrel,
14081411
Buffer buf,
14091412
BlockNumber blkno,
@@ -1623,6 +1626,8 @@ lazy_scan_prune(LVRelState *vacrel,
16231626
VISIBILITYMAP_ALL_VISIBLE |
16241627
VISIBILITYMAP_ALL_FROZEN);
16251628
}
1629+
1630+
return presult.ndeleted;
16261631
}
16271632

16281633
/*

0 commit comments

Comments
 (0)