diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/heap/vacuumlazy.c | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index b63cad1335f..e7a942e1835 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -252,7 +252,7 @@ static void lazy_scan_prune(LVRelState *vacrel, Buffer buf, LVPagePruneState *prunestate); static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, - bool *recordfreespace); + bool *has_lpdead_items); static void lazy_vacuum(LVRelState *vacrel); static bool lazy_vacuum_all_indexes(LVRelState *vacrel); static void lazy_vacuum_heap_rel(LVRelState *vacrel); @@ -958,7 +958,7 @@ lazy_scan_heap(LVRelState *vacrel) page = BufferGetPage(buf); if (!ConditionalLockBufferForCleanup(buf)) { - bool recordfreespace; + bool has_lpdead_items; LockBuffer(buf, BUFFER_LOCK_SHARE); @@ -974,17 +974,30 @@ lazy_scan_heap(LVRelState *vacrel) * Collect LP_DEAD items in dead_items array, count tuples, * determine if rel truncation is safe */ - if (lazy_scan_noprune(vacrel, buf, blkno, page, - &recordfreespace)) + if (lazy_scan_noprune(vacrel, buf, blkno, page, &has_lpdead_items)) { Size freespace = 0; + bool recordfreespace; /* - * Processed page successfully (without cleanup lock) -- just - * need to update the FSM, much like the lazy_scan_prune case. - * Don't bother trying to match its visibility map setting - * steps, though. + * We processed the page successfully (without a cleanup + * lock). + * + * Update the FSM, just as we would in the case where + * lazy_scan_prune() is called. Our goal is to update the + * freespace map the last time we touch the page. If the + * relation has no indexes, or if index vacuuming is disabled, + * there will be no second heap pass; if this particular page + * has no dead items, the second heap pass will not touch this + * page. So, in those cases, update the FSM now. + * + * After a call to lazy_scan_prune(), we would also try to + * adjust the page-level all-visible bit and the visibility + * map, but we skip that step in this path. */ + recordfreespace = vacrel->nindexes == 0 + || !vacrel->do_index_vacuuming + || !has_lpdead_items; if (recordfreespace) freespace = PageGetHeapFreeSpace(page); UnlockReleaseBuffer(buf); @@ -1935,15 +1948,17 @@ lazy_scan_prune(LVRelState *vacrel, * one or more tuples on the page. We always return true for non-aggressive * callers. * - * recordfreespace flag instructs caller on whether or not it should do - * generic FSM processing for page. + * If this function returns true, *has_lpdead_items gets set to true or false + * depending on whether, upon return from this function, any LP_DEAD items are + * present on the page. If this function returns false, *has_lpdead_items + * is not updated. */ static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, - bool *recordfreespace) + bool *has_lpdead_items) { OffsetNumber offnum, maxoff; @@ -1960,7 +1975,6 @@ lazy_scan_noprune(LVRelState *vacrel, Assert(BufferGetBlockNumber(buf) == blkno); hastup = false; /* for now */ - *recordfreespace = false; /* for now */ lpdead_items = 0; live_tuples = 0; @@ -2102,18 +2116,8 @@ lazy_scan_noprune(LVRelState *vacrel, hastup = true; missed_dead_tuples += lpdead_items; } - - *recordfreespace = true; - } - else if (lpdead_items == 0) - { - /* - * Won't be vacuuming this page later, so record page's freespace in - * the FSM now - */ - *recordfreespace = true; } - else + else if (lpdead_items > 0) { VacDeadItems *dead_items = vacrel->dead_items; ItemPointerData tmp; @@ -2138,12 +2142,6 @@ lazy_scan_noprune(LVRelState *vacrel, dead_items->num_items); vacrel->lpdead_items += lpdead_items; - - /* - * Assume that we'll go on to vacuum this heap page during final pass - * over the heap. Don't record free space until then. - */ - *recordfreespace = false; } /* @@ -2159,6 +2157,9 @@ lazy_scan_noprune(LVRelState *vacrel, if (hastup) vacrel->nonempty_pages = blkno + 1; + /* Did we find LP_DEAD items? */ + *has_lpdead_items = (lpdead_items > 0); + /* Caller won't need to call lazy_scan_prune with same page */ return true; } |