@@ -227,12 +227,12 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed)
227
227
* with heap relation locked first to prevent deadlocking). In hot
228
228
* standby mode this will raise an error when parentcheck is true.
229
229
*
230
- * There is no need for the usual indcheckxmin usability horizon test here,
231
- * even in the heapallindexed case, because index undergoing verification
232
- * only needs to have entries for a new transaction snapshot. (If this is
233
- * a parentcheck verification, there is no question about committed or
234
- * recently dead heap tuples lacking index entries due to concurrent
235
- * activity.)
230
+ * There is no need for the usual indcheckxmin usability horizon test
231
+ * here, even in the heapallindexed case, because index undergoing
232
+ * verification only needs to have entries for a new transaction snapshot.
233
+ * (If this is a parentcheck verification, there is no question about
234
+ * committed or recently dead heap tuples lacking index entries due to
235
+ * concurrent activity.)
236
236
*/
237
237
indrel = index_open (indrelid , lockmode );
238
238
@@ -366,8 +366,8 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly,
366
366
* index fingerprinting should have reached all tuples returned by
367
367
* IndexBuildHeapScan().
368
368
*
369
- * In readonly case, we also check for problems with missing downlinks.
370
- * A second Bloom filter is used for this.
369
+ * In readonly case, we also check for problems with missing
370
+ * downlinks. A second Bloom filter is used for this.
371
371
*/
372
372
if (!state -> readonly )
373
373
{
@@ -378,13 +378,13 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly,
378
378
* READ COMMITTED mode. A new snapshot is guaranteed to have all
379
379
* the entries it requires in the index.
380
380
*
381
- * We must defend against the possibility that an old xact snapshot
382
- * was returned at higher isolation levels when that snapshot is
383
- * not safe for index scans of the target index. This is possible
384
- * when the snapshot sees tuples that are before the index's
385
- * indcheckxmin horizon. Throwing an error here should be very
386
- * rare. It doesn't seem worth using a secondary snapshot to avoid
387
- * this.
381
+ * We must defend against the possibility that an old xact
382
+ * snapshot was returned at higher isolation levels when that
383
+ * snapshot is not safe for index scans of the target index. This
384
+ * is possible when the snapshot sees tuples that are before the
385
+ * index's indcheckxmin horizon. Throwing an error here should be
386
+ * very rare. It doesn't seem worth using a secondary snapshot to
387
+ * avoid this.
388
388
*/
389
389
if (IsolationUsesXactSnapshot () && rel -> rd_index -> indcheckxmin &&
390
390
!TransactionIdPrecedes (HeapTupleHeaderGetXmin (rel -> rd_indextuple -> t_data ),
@@ -396,13 +396,13 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly,
396
396
}
397
397
else
398
398
{
399
- int64 total_pages ;
399
+ int64 total_pages ;
400
400
401
401
/*
402
402
* Extra readonly downlink check.
403
403
*
404
- * In readonly case, we know that there cannot be a concurrent page
405
- * split or a concurrent page deletion, which gives us the
404
+ * In readonly case, we know that there cannot be a concurrent
405
+ * page split or a concurrent page deletion, which gives us the
406
406
* opportunity to verify that every non-ignorable page had a
407
407
* downlink one level up. We must be tolerant of interrupted page
408
408
* splits and page deletions, though. This is taken care of in
@@ -491,9 +491,9 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly,
491
491
}
492
492
493
493
/*
494
- * Create our own scan for IndexBuildHeapScan(), rather than getting it
495
- * to do so for us. This is required so that we can actually use the
496
- * MVCC snapshot registered earlier in !readonly case.
494
+ * Create our own scan for IndexBuildHeapScan(), rather than getting
495
+ * it to do so for us. This is required so that we can actually use
496
+ * the MVCC snapshot registered earlier in !readonly case.
497
497
*
498
498
* Note that IndexBuildHeapScan() calls heap_endscan() for us.
499
499
*/
@@ -607,10 +607,10 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
607
607
{
608
608
/*
609
609
* Since there cannot be a concurrent VACUUM operation in readonly
610
- * mode, and since a page has no links within other pages (siblings
611
- * and parent) once it is marked fully deleted, it should be
612
- * impossible to land on a fully deleted page in readonly mode.
613
- * See bt_downlink_check() for further details.
610
+ * mode, and since a page has no links within other pages
611
+ * (siblings and parent) once it is marked fully deleted, it
612
+ * should be impossible to land on a fully deleted page in
613
+ * readonly mode. See bt_downlink_check() for further details.
614
614
*
615
615
* The bt_downlink_check() P_ISDELETED() check is repeated here so
616
616
* that pages that are only reachable through sibling links get
@@ -799,8 +799,8 @@ bt_target_page_check(BtreeCheckState *state)
799
799
P_ISLEAF (topaque ) ? "leaf" : "internal" , state -> targetblock );
800
800
801
801
/*
802
- * Check the number of attributes in high key. Note, rightmost page doesn't
803
- * contain a high key, so nothing to check
802
+ * Check the number of attributes in high key. Note, rightmost page
803
+ * doesn't contain a high key, so nothing to check
804
804
*/
805
805
if (!P_RIGHTMOST (topaque ) &&
806
806
!_bt_check_natts (state -> rel , state -> target , P_HIKEY ))
@@ -845,8 +845,8 @@ bt_target_page_check(BtreeCheckState *state)
845
845
846
846
/*
847
847
* lp_len should match the IndexTuple reported length exactly, since
848
- * lp_len is completely redundant in indexes, and both sources of tuple
849
- * length are MAXALIGN()'d. nbtree does not use lp_len all that
848
+ * lp_len is completely redundant in indexes, and both sources of
849
+ * tuple length are MAXALIGN()'d. nbtree does not use lp_len all that
850
850
* frequently, and is surprisingly tolerant of corrupt lp_len fields.
851
851
*/
852
852
if (tupsize != ItemIdGetLength (itemid ))
@@ -1441,13 +1441,13 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock,
1441
1441
static void
1442
1442
bt_downlink_missing_check (BtreeCheckState * state )
1443
1443
{
1444
- BTPageOpaque topaque = (BTPageOpaque ) PageGetSpecialPointer (state -> target );
1445
- ItemId itemid ;
1446
- IndexTuple itup ;
1447
- Page child ;
1448
- BTPageOpaque copaque ;
1449
- uint32 level ;
1450
- BlockNumber childblk ;
1444
+ BTPageOpaque topaque = (BTPageOpaque ) PageGetSpecialPointer (state -> target );
1445
+ ItemId itemid ;
1446
+ IndexTuple itup ;
1447
+ Page child ;
1448
+ BTPageOpaque copaque ;
1449
+ uint32 level ;
1450
+ BlockNumber childblk ;
1451
1451
1452
1452
Assert (state -> heapallindexed && state -> readonly );
1453
1453
Assert (!P_IGNORE (topaque ));
@@ -1462,14 +1462,15 @@ bt_downlink_missing_check(BtreeCheckState *state)
1462
1462
* page split in passing, when it notices that the left sibling page is
1463
1463
* P_INCOMPLETE_SPLIT().
1464
1464
*
1465
- * In general, VACUUM is not prepared for there to be no downlink to a page
1466
- * that it deletes. This is the main reason why the lack of a downlink can
1467
- * be reported as corruption here. It's not obvious that an invalid
1468
- * missing downlink can result in wrong answers to queries, though, since
1469
- * index scans that land on the child may end up consistently moving right.
1470
- * The handling of concurrent page splits (and page deletions) within
1471
- * _bt_moveright() cannot distinguish inconsistencies that last for a
1472
- * moment from inconsistencies that are permanent and irrecoverable.
1465
+ * In general, VACUUM is not prepared for there to be no downlink to a
1466
+ * page that it deletes. This is the main reason why the lack of a
1467
+ * downlink can be reported as corruption here. It's not obvious that an
1468
+ * invalid missing downlink can result in wrong answers to queries,
1469
+ * though, since index scans that land on the child may end up
1470
+ * consistently moving right. The handling of concurrent page splits (and
1471
+ * page deletions) within _bt_moveright() cannot distinguish
1472
+ * inconsistencies that last for a moment from inconsistencies that are
1473
+ * permanent and irrecoverable.
1473
1474
*
1474
1475
* VACUUM isn't even prepared to delete pages that have no downlink due to
1475
1476
* an incomplete page split, but it can detect and reason about that case
@@ -1498,8 +1499,8 @@ bt_downlink_missing_check(BtreeCheckState *state)
1498
1499
1499
1500
/*
1500
1501
* Target is probably the "top parent" of a multi-level page deletion.
1501
- * We'll need to descend the subtree to make sure that descendant pages are
1502
- * consistent with that, though.
1502
+ * We'll need to descend the subtree to make sure that descendant pages
1503
+ * are consistent with that, though.
1503
1504
*
1504
1505
* If the target page (which must be non-ignorable) is a leaf page, then
1505
1506
* clearly it can't be the top parent. The lack of a downlink is probably
@@ -1562,14 +1563,14 @@ bt_downlink_missing_check(BtreeCheckState *state)
1562
1563
* bt_downlink_check() does not visit pages reachable through negative
1563
1564
* infinity items. Besides, bt_downlink_check() is unwilling to descend
1564
1565
* multiple levels. (The similar bt_downlink_check() P_ISDELETED() check
1565
- * within bt_check_level_from_leftmost() won't reach the page either, since
1566
- * the leaf's live siblings should have their sibling links updated to
1567
- * bypass the deletion target page when it is marked fully dead.)
1566
+ * within bt_check_level_from_leftmost() won't reach the page either,
1567
+ * since the leaf's live siblings should have their sibling links updated
1568
+ * to bypass the deletion target page when it is marked fully dead.)
1568
1569
*
1569
1570
* If this error is raised, it might be due to a previous multi-level page
1570
- * deletion that failed to realize that it wasn't yet safe to mark the leaf
1571
- * page as fully dead. A "dangling downlink" will still remain when this
1572
- * happens. The fact that the dangling downlink's page (the leaf's
1571
+ * deletion that failed to realize that it wasn't yet safe to mark the
1572
+ * leaf page as fully dead. A "dangling downlink" will still remain when
1573
+ * this happens. The fact that the dangling downlink's page (the leaf's
1573
1574
* parent/ancestor page) lacked a downlink is incidental.
1574
1575
*/
1575
1576
if (P_ISDELETED (copaque ))
@@ -1583,14 +1584,14 @@ bt_downlink_missing_check(BtreeCheckState *state)
1583
1584
(uint32 ) state -> targetlsn )));
1584
1585
1585
1586
/*
1586
- * Iff leaf page is half-dead, its high key top parent link should point to
1587
- * what VACUUM considered to be the top parent page at the instant it was
1588
- * interrupted. Provided the high key link actually points to the target
1589
- * page, the missing downlink we detected is consistent with there having
1590
- * been an interrupted multi-level page deletion. This means that the
1591
- * subtree with the target page at its root (a page deletion chain) is in a
1592
- * consistent state, enabling VACUUM to resume deleting the entire chain
1593
- * the next time it encounters the half-dead leaf page.
1587
+ * Iff leaf page is half-dead, its high key top parent link should point
1588
+ * to what VACUUM considered to be the top parent page at the instant it
1589
+ * was interrupted. Provided the high key link actually points to the
1590
+ * target page, the missing downlink we detected is consistent with there
1591
+ * having been an interrupted multi-level page deletion. This means that
1592
+ * the subtree with the target page at its root (a page deletion chain) is
1593
+ * in a consistent state, enabling VACUUM to resume deleting the entire
1594
+ * chain the next time it encounters the half-dead leaf page.
1594
1595
*/
1595
1596
if (P_ISHALFDEAD (copaque ) && !P_RIGHTMOST (copaque ))
1596
1597
{
@@ -1681,16 +1682,17 @@ bt_tuple_present_callback(Relation index, HeapTuple htup, Datum *values,
1681
1682
* are assumed immutable. While the LP_DEAD bit is mutable in leaf pages,
1682
1683
* that's ItemId metadata, which was not fingerprinted. (There will often
1683
1684
* be some dead-to-everyone IndexTuples fingerprinted by the Bloom filter,
1684
- * but we only try to detect the absence of needed tuples, so that's okay.)
1685
+ * but we only try to detect the absence of needed tuples, so that's
1686
+ * okay.)
1685
1687
*
1686
- * Note that we rely on deterministic index_form_tuple() TOAST compression.
1687
- * If index_form_tuple() was ever enhanced to compress datums out-of-line,
1688
- * or otherwise varied when or how compression was applied, our assumption
1689
- * would break, leading to false positive reports of corruption. It's also
1690
- * possible that non-pivot tuples could in the future have alternative
1691
- * equivalent representations (e.g. by using the INDEX_ALT_TID_MASK bit).
1692
- * For now, we don't decompress/normalize toasted values as part of
1693
- * fingerprinting.
1688
+ * Note that we rely on deterministic index_form_tuple() TOAST
1689
+ * compression. If index_form_tuple() was ever enhanced to compress datums
1690
+ * out-of-line, or otherwise varied when or how compression was applied,
1691
+ * our assumption would break, leading to false positive reports of
1692
+ * corruption. It's also possible that non-pivot tuples could in the
1693
+ * future have alternative equivalent representations (e.g. by using the
1694
+ * INDEX_ALT_TID_MASK bit). For now, we don't decompress/normalize toasted
1695
+ * values as part of fingerprinting.
1694
1696
*/
1695
1697
itup = index_form_tuple (RelationGetDescr (index ), values , isnull );
1696
1698
itup -> t_tid = htup -> t_self ;
@@ -1905,19 +1907,19 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
1905
1907
* Sanity checks for number of items on page.
1906
1908
*
1907
1909
* As noted at the beginning of _bt_binsrch(), an internal page must have
1908
- * children, since there must always be a negative infinity downlink (there
1909
- * may also be a highkey). In the case of non-rightmost leaf pages, there
1910
- * must be at least a highkey.
1910
+ * children, since there must always be a negative infinity downlink
1911
+ * (there may also be a highkey). In the case of non-rightmost leaf
1912
+ * pages, there must be at least a highkey.
1911
1913
*
1912
- * This is correct when pages are half-dead, since internal pages are never
1913
- * half-dead, and leaf pages must have a high key when half-dead (the
1914
- * rightmost page can never be deleted). It's also correct with fully
1915
- * deleted pages: _bt_unlink_halfdead_page() doesn't change anything about
1916
- * the target page other than setting the page as fully dead, and setting
1917
- * its xact field. In particular, it doesn't change the sibling links in
1918
- * the deletion target itself, since they're required when index scans land
1919
- * on the deletion target, and then need to move right (or need to move
1920
- * left, in the case of backward index scans).
1914
+ * This is correct when pages are half-dead, since internal pages are
1915
+ * never half-dead, and leaf pages must have a high key when half-dead
1916
+ * (the rightmost page can never be deleted). It's also correct with
1917
+ * fully deleted pages: _bt_unlink_halfdead_page() doesn't change anything
1918
+ * about the target page other than setting the page as fully dead, and
1919
+ * setting its xact field. In particular, it doesn't change the sibling
1920
+ * links in the deletion target itself, since they're required when index
1921
+ * scans land on the deletion target, and then need to move right (or need
1922
+ * to move left, in the case of backward index scans).
1921
1923
*/
1922
1924
maxoffset = PageGetMaxOffsetNumber (page );
1923
1925
if (maxoffset > MaxIndexTuplesPerPage )
0 commit comments