Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+69-66
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

-1
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)