Skip to content

Commit e313a61

Browse files
committed
Remove LVPagePruneState.
Commit cb97024 moved some code from lazy_scan_heap() to lazy_scan_prune(), and now some things that used to need to be passed back and forth are completely local to lazy_scan_prune(). Hence, this struct is mostly obsolete. The only thing that still needs to be passed back to the caller is has_lpdead_items, and that's also passed back by lazy_scan_noprune(), so do it the same way in both cases. Melanie Plageman, reviewed and slightly revised by me. Discussion: http://postgr.es/m/CAAKRu_aM=OL85AOr-80wBsCr=vLVzhnaavqkVPRkFBtD0zsuLQ@mail.gmail.com
1 parent cb97024 commit e313a61

File tree

2 files changed

+69
-67
lines changed

2 files changed

+69
-67
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 69 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,6 @@ typedef struct LVRelState
212212
int64 missed_dead_tuples; /* # removable, but not removed */
213213
} LVRelState;
214214

215-
/*
216-
* State returned by lazy_scan_prune()
217-
*/
218-
typedef struct LVPagePruneState
219-
{
220-
bool has_lpdead_items; /* includes existing LP_DEAD items */
221-
222-
/*
223-
* State describes the proper VM bit states to set for the page following
224-
* pruning and freezing. all_visible implies !has_lpdead_items, but don't
225-
* trust all_frozen result unless all_visible is also set to true.
226-
*/
227-
bool all_visible; /* Every item visible to all? */
228-
bool all_frozen; /* provided all_visible is also true */
229-
TransactionId visibility_cutoff_xid; /* For recovery conflicts */
230-
} LVPagePruneState;
231-
232215
/* Struct for saving and restoring vacuum error information. */
233216
typedef struct LVSavedErrInfo
234217
{
@@ -250,7 +233,7 @@ static bool lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf,
250233
static void lazy_scan_prune(LVRelState *vacrel, Buffer buf,
251234
BlockNumber blkno, Page page,
252235
Buffer vmbuffer, bool all_visible_according_to_vm,
253-
LVPagePruneState *prunestate);
236+
bool *has_lpdead_items);
254237
static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf,
255238
BlockNumber blkno, Page page,
256239
bool *has_lpdead_items);
@@ -854,7 +837,7 @@ lazy_scan_heap(LVRelState *vacrel)
854837
Buffer buf;
855838
Page page;
856839
bool all_visible_according_to_vm;
857-
LVPagePruneState prunestate;
840+
bool has_lpdead_items;
858841

859842
if (blkno == next_unskippable_block)
860843
{
@@ -959,8 +942,6 @@ lazy_scan_heap(LVRelState *vacrel)
959942
page = BufferGetPage(buf);
960943
if (!ConditionalLockBufferForCleanup(buf))
961944
{
962-
bool has_lpdead_items;
963-
964945
LockBuffer(buf, BUFFER_LOCK_SHARE);
965946

966947
/* Check for new or empty pages before lazy_scan_noprune call */
@@ -1035,7 +1016,7 @@ lazy_scan_heap(LVRelState *vacrel)
10351016
*/
10361017
lazy_scan_prune(vacrel, buf, blkno, page,
10371018
vmbuffer, all_visible_according_to_vm,
1038-
&prunestate);
1019+
&has_lpdead_items);
10391020

10401021
/*
10411022
* Final steps for block: drop cleanup lock, record free space in the
@@ -1056,7 +1037,7 @@ lazy_scan_heap(LVRelState *vacrel)
10561037
*/
10571038
if (vacrel->nindexes == 0
10581039
|| !vacrel->do_index_vacuuming
1059-
|| !prunestate.has_lpdead_items)
1040+
|| !has_lpdead_items)
10601041
{
10611042
Size freespace = PageGetHeapFreeSpace(page);
10621043

@@ -1068,7 +1049,7 @@ lazy_scan_heap(LVRelState *vacrel)
10681049
* visible on upper FSM pages. This is done after vacuuming if the
10691050
* table has indexes.
10701051
*/
1071-
if (vacrel->nindexes == 0 && prunestate.has_lpdead_items &&
1052+
if (vacrel->nindexes == 0 && has_lpdead_items &&
10721053
blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
10731054
{
10741055
FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
@@ -1383,6 +1364,14 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
13831364
* right after this operation completes instead of in the middle of it. Note that
13841365
* any tuple that becomes dead after the call to heap_page_prune() can't need to
13851366
* be frozen, because it was visible to another session when vacuum started.
1367+
*
1368+
* vmbuffer is the buffer containing the VM block with visibility information
1369+
* for the heap block, blkno. all_visible_according_to_vm is the saved
1370+
* visibility status of the heap block looked up earlier by the caller. We
1371+
* won't rely entirely on this status, as it may be out of date.
1372+
*
1373+
* *has_lpdead_items is set to true or false depending on whether, upon return
1374+
* from this function, any LP_DEAD items are still present on the page.
13861375
*/
13871376
static void
13881377
lazy_scan_prune(LVRelState *vacrel,
@@ -1391,7 +1380,7 @@ lazy_scan_prune(LVRelState *vacrel,
13911380
Page page,
13921381
Buffer vmbuffer,
13931382
bool all_visible_according_to_vm,
1394-
LVPagePruneState *prunestate)
1383+
bool *has_lpdead_items)
13951384
{
13961385
Relation rel = vacrel->rel;
13971386
OffsetNumber offnum,
@@ -1404,6 +1393,9 @@ lazy_scan_prune(LVRelState *vacrel,
14041393
recently_dead_tuples;
14051394
HeapPageFreeze pagefrz;
14061395
bool hastup = false;
1396+
bool all_visible,
1397+
all_frozen;
1398+
TransactionId visibility_cutoff_xid;
14071399
int64 fpi_before = pgWalUsage.wal_fpi;
14081400
OffsetNumber deadoffsets[MaxHeapTuplesPerPage];
14091401
HeapTupleFreeze frozen[MaxHeapTuplesPerPage];
@@ -1444,14 +1436,22 @@ lazy_scan_prune(LVRelState *vacrel,
14441436
&presult, &vacrel->offnum);
14451437

14461438
/*
1447-
* Now scan the page to collect LP_DEAD items and check for tuples
1448-
* requiring freezing among remaining tuples with storage
1439+
* We will update the VM after collecting LP_DEAD items and freezing
1440+
* tuples. Keep track of whether or not the page is all_visible and
1441+
* all_frozen and use this information to update the VM. all_visible
1442+
* implies 0 lpdead_items, but don't trust all_frozen result unless
1443+
* all_visible is also set to true.
1444+
*
1445+
* Also keep track of the visibility cutoff xid for recovery conflicts.
14491446
*/
1450-
prunestate->has_lpdead_items = false;
1451-
prunestate->all_visible = true;
1452-
prunestate->all_frozen = true;
1453-
prunestate->visibility_cutoff_xid = InvalidTransactionId;
1447+
all_visible = true;
1448+
all_frozen = true;
1449+
visibility_cutoff_xid = InvalidTransactionId;
14541450

1451+
/*
1452+
* Now scan the page to collect LP_DEAD items and update the variables set
1453+
* just above.
1454+
*/
14551455
for (offnum = FirstOffsetNumber;
14561456
offnum <= maxoff;
14571457
offnum = OffsetNumberNext(offnum))
@@ -1538,13 +1538,13 @@ lazy_scan_prune(LVRelState *vacrel,
15381538
* asynchronously. See SetHintBits for more info. Check that
15391539
* the tuple is hinted xmin-committed because of that.
15401540
*/
1541-
if (prunestate->all_visible)
1541+
if (all_visible)
15421542
{
15431543
TransactionId xmin;
15441544

15451545
if (!HeapTupleHeaderXminCommitted(htup))
15461546
{
1547-
prunestate->all_visible = false;
1547+
all_visible = false;
15481548
break;
15491549
}
15501550

@@ -1556,14 +1556,14 @@ lazy_scan_prune(LVRelState *vacrel,
15561556
if (!TransactionIdPrecedes(xmin,
15571557
vacrel->cutoffs.OldestXmin))
15581558
{
1559-
prunestate->all_visible = false;
1559+
all_visible = false;
15601560
break;
15611561
}
15621562

15631563
/* Track newest xmin on page. */
1564-
if (TransactionIdFollows(xmin, prunestate->visibility_cutoff_xid) &&
1564+
if (TransactionIdFollows(xmin, visibility_cutoff_xid) &&
15651565
TransactionIdIsNormal(xmin))
1566-
prunestate->visibility_cutoff_xid = xmin;
1566+
visibility_cutoff_xid = xmin;
15671567
}
15681568
break;
15691569
case HEAPTUPLE_RECENTLY_DEAD:
@@ -1574,7 +1574,7 @@ lazy_scan_prune(LVRelState *vacrel,
15741574
* pruning.)
15751575
*/
15761576
recently_dead_tuples++;
1577-
prunestate->all_visible = false;
1577+
all_visible = false;
15781578
break;
15791579
case HEAPTUPLE_INSERT_IN_PROGRESS:
15801580

@@ -1585,11 +1585,11 @@ lazy_scan_prune(LVRelState *vacrel,
15851585
* results. This assumption is a bit shaky, but it is what
15861586
* acquire_sample_rows() does, so be consistent.
15871587
*/
1588-
prunestate->all_visible = false;
1588+
all_visible = false;
15891589
break;
15901590
case HEAPTUPLE_DELETE_IN_PROGRESS:
15911591
/* This is an expected case during concurrent vacuum */
1592-
prunestate->all_visible = false;
1592+
all_visible = false;
15931593

15941594
/*
15951595
* Count such rows as live. As above, we assume the deleting
@@ -1619,7 +1619,7 @@ lazy_scan_prune(LVRelState *vacrel,
16191619
* definitely cannot be set all-frozen in the visibility map later on
16201620
*/
16211621
if (!totally_frozen)
1622-
prunestate->all_frozen = false;
1622+
all_frozen = false;
16231623
}
16241624

16251625
/*
@@ -1637,7 +1637,7 @@ lazy_scan_prune(LVRelState *vacrel,
16371637
* page all-frozen afterwards (might not happen until final heap pass).
16381638
*/
16391639
if (pagefrz.freeze_required || tuples_frozen == 0 ||
1640-
(prunestate->all_visible && prunestate->all_frozen &&
1640+
(all_visible && all_frozen &&
16411641
fpi_before != pgWalUsage.wal_fpi))
16421642
{
16431643
/*
@@ -1675,11 +1675,11 @@ lazy_scan_prune(LVRelState *vacrel,
16751675
* once we're done with it. Otherwise we generate a conservative
16761676
* cutoff by stepping back from OldestXmin.
16771677
*/
1678-
if (prunestate->all_visible && prunestate->all_frozen)
1678+
if (all_visible && all_frozen)
16791679
{
16801680
/* Using same cutoff when setting VM is now unnecessary */
1681-
snapshotConflictHorizon = prunestate->visibility_cutoff_xid;
1682-
prunestate->visibility_cutoff_xid = InvalidTransactionId;
1681+
snapshotConflictHorizon = visibility_cutoff_xid;
1682+
visibility_cutoff_xid = InvalidTransactionId;
16831683
}
16841684
else
16851685
{
@@ -1702,7 +1702,7 @@ lazy_scan_prune(LVRelState *vacrel,
17021702
*/
17031703
vacrel->NewRelfrozenXid = pagefrz.NoFreezePageRelfrozenXid;
17041704
vacrel->NewRelminMxid = pagefrz.NoFreezePageRelminMxid;
1705-
prunestate->all_frozen = false;
1705+
all_frozen = false;
17061706
tuples_frozen = 0; /* avoid miscounts in instrumentation */
17071707
}
17081708

@@ -1715,16 +1715,17 @@ lazy_scan_prune(LVRelState *vacrel,
17151715
*/
17161716
#ifdef USE_ASSERT_CHECKING
17171717
/* Note that all_frozen value does not matter when !all_visible */
1718-
if (prunestate->all_visible && lpdead_items == 0)
1718+
if (all_visible && lpdead_items == 0)
17191719
{
1720-
TransactionId cutoff;
1721-
bool all_frozen;
1720+
TransactionId debug_cutoff;
1721+
bool debug_all_frozen;
17221722

1723-
if (!heap_page_is_all_visible(vacrel, buf, &cutoff, &all_frozen))
1723+
if (!heap_page_is_all_visible(vacrel, buf,
1724+
&debug_cutoff, &debug_all_frozen))
17241725
Assert(false);
17251726

1726-
Assert(!TransactionIdIsValid(cutoff) ||
1727-
cutoff == prunestate->visibility_cutoff_xid);
1727+
Assert(!TransactionIdIsValid(debug_cutoff) ||
1728+
debug_cutoff == visibility_cutoff_xid);
17281729
}
17291730
#endif
17301731

@@ -1737,7 +1738,6 @@ lazy_scan_prune(LVRelState *vacrel,
17371738
ItemPointerData tmp;
17381739

17391740
vacrel->lpdead_item_pages++;
1740-
prunestate->has_lpdead_items = true;
17411741

17421742
ItemPointerSetBlockNumber(&tmp, blkno);
17431743

@@ -1762,7 +1762,7 @@ lazy_scan_prune(LVRelState *vacrel,
17621762
* Now that freezing has been finalized, unset all_visible. It needs
17631763
* to reflect the present state of things, as expected by our caller.
17641764
*/
1765-
prunestate->all_visible = false;
1765+
all_visible = false;
17661766
}
17671767

17681768
/* Finally, add page-local counts to whole-VACUUM counts */
@@ -1776,19 +1776,23 @@ lazy_scan_prune(LVRelState *vacrel,
17761776
if (hastup)
17771777
vacrel->nonempty_pages = blkno + 1;
17781778

1779-
Assert(!prunestate->all_visible || !prunestate->has_lpdead_items);
1779+
/* Did we find LP_DEAD items? */
1780+
*has_lpdead_items = (lpdead_items > 0);
1781+
1782+
Assert(!all_visible || !(*has_lpdead_items));
17801783

17811784
/*
17821785
* Handle setting visibility map bit based on information from the VM (as
1783-
* of last lazy_scan_skip() call), and from prunestate
1786+
* of last lazy_scan_skip() call), and from all_visible and all_frozen
1787+
* variables
17841788
*/
1785-
if (!all_visible_according_to_vm && prunestate->all_visible)
1789+
if (!all_visible_according_to_vm && all_visible)
17861790
{
17871791
uint8 flags = VISIBILITYMAP_ALL_VISIBLE;
17881792

1789-
if (prunestate->all_frozen)
1793+
if (all_frozen)
17901794
{
1791-
Assert(!TransactionIdIsValid(prunestate->visibility_cutoff_xid));
1795+
Assert(!TransactionIdIsValid(visibility_cutoff_xid));
17921796
flags |= VISIBILITYMAP_ALL_FROZEN;
17931797
}
17941798

@@ -1808,7 +1812,7 @@ lazy_scan_prune(LVRelState *vacrel,
18081812
PageSetAllVisible(page);
18091813
MarkBufferDirty(buf);
18101814
visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr,
1811-
vmbuffer, prunestate->visibility_cutoff_xid,
1815+
vmbuffer, visibility_cutoff_xid,
18121816
flags);
18131817
}
18141818

@@ -1841,7 +1845,7 @@ lazy_scan_prune(LVRelState *vacrel,
18411845
* There should never be LP_DEAD items on a page with PD_ALL_VISIBLE set,
18421846
* however.
18431847
*/
1844-
else if (prunestate->has_lpdead_items && PageIsAllVisible(page))
1848+
else if (lpdead_items > 0 && PageIsAllVisible(page))
18451849
{
18461850
elog(WARNING, "page containing LP_DEAD items is marked as all-visible in relation \"%s\" page %u",
18471851
vacrel->relname, blkno);
@@ -1854,16 +1858,15 @@ lazy_scan_prune(LVRelState *vacrel,
18541858
/*
18551859
* If the all-visible page is all-frozen but not marked as such yet, mark
18561860
* it as all-frozen. Note that all_frozen is only valid if all_visible is
1857-
* true, so we must check both prunestate fields.
1861+
* true, so we must check both all_visible and all_frozen.
18581862
*/
1859-
else if (all_visible_according_to_vm && prunestate->all_visible &&
1860-
prunestate->all_frozen &&
1861-
!VM_ALL_FROZEN(vacrel->rel, blkno, &vmbuffer))
1863+
else if (all_visible_according_to_vm && all_visible &&
1864+
all_frozen && !VM_ALL_FROZEN(vacrel->rel, blkno, &vmbuffer))
18621865
{
18631866
/*
18641867
* Avoid relying on all_visible_according_to_vm as a proxy for the
18651868
* page-level PD_ALL_VISIBLE bit being set, since it might have become
1866-
* stale -- even when all_visible is set in prunestate
1869+
* stale -- even when all_visible is set
18671870
*/
18681871
if (!PageIsAllVisible(page))
18691872
{
@@ -1878,7 +1881,7 @@ lazy_scan_prune(LVRelState *vacrel,
18781881
* since a snapshotConflictHorizon sufficient to make everything safe
18791882
* for REDO was logged when the page's tuples were frozen.
18801883
*/
1881-
Assert(!TransactionIdIsValid(prunestate->visibility_cutoff_xid));
1884+
Assert(!TransactionIdIsValid(visibility_cutoff_xid));
18821885
visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr,
18831886
vmbuffer, InvalidTransactionId,
18841887
VISIBILITYMAP_ALL_VISIBLE |

src/tools/pgindent/typedefs.list

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,6 @@ LPVOID
14051405
LPWSTR
14061406
LSEG
14071407
LUID
1408-
LVPagePruneState
14091408
LVRelState
14101409
LVSavedErrInfo
14111410
LWLock

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy