51 #define InvalidBtreeLevel ((uint32) InvalidBlockNumber)
52 #define BTreeTupleGetNKeyAtts(itup, rel) \
53 Min(IndexRelationGetNumberOfKeyAttributes(rel), BTreeTupleGetNAtts(itup, rel))
142 bool heapallindexed,
bool rootdescend);
146 bool heapkeyspace,
bool readonly,
bool heapallindexed,
165 bool tupleIsAlive,
void *checkstate);
206 bool heapallindexed =
false;
229 bool heapallindexed =
false;
230 bool rootdescend =
false;
254 int save_sec_context;
290 save_sec_context = -1;
316 errmsg(
"could not open parent table of index \"%s\"",
329 (
errcode(ERRCODE_INDEX_CORRUPTED),
330 errmsg(
"index \"%s\" lacks a main relation fork",
335 if (allequalimage && !heapkeyspace)
337 (
errcode(ERRCODE_INDEX_CORRUPTED),
338 errmsg(
"index \"%s\" metapage has equalimage field set on unsupported nbtree version",
342 (
errcode(ERRCODE_INDEX_CORRUPTED),
343 errmsg(
"index \"%s\" metapage incorrectly indicates that deduplication is safe",
348 heapallindexed, rootdescend);
378 if (rel->
rd_rel->relkind != RELKIND_INDEX ||
379 rel->
rd_rel->relam != BTREE_AM_OID)
381 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
382 errmsg(
"only B-Tree indexes are supported as targets for verification"),
383 errdetail(
"Relation \"%s\" is not a B-Tree index.",
388 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
389 errmsg(
"cannot access temporary tables of other sessions"),
390 errdetail(
"Index \"%s\" is associated with temporary relation.",
395 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
396 errmsg(
"cannot check index \"%s\"",
412 if (rel->
rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED ||
417 (
errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
418 errmsg(
"cannot verify unlogged index \"%s\" during recovery, skipping",
449 bool readonly,
bool heapallindexed,
bool rootdescend)
459 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\"",
462 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\" with cross-level checks",
476 state->heaprel = heaprel;
477 state->heapkeyspace = heapkeyspace;
478 state->readonly = readonly;
479 state->heapallindexed = heapallindexed;
480 state->rootdescend = rootdescend;
482 if (
state->heapallindexed)
497 (int64)
state->rel->rd_rel->reltuples);
502 state->heaptuplespresent = 0;
511 if (!
state->readonly)
533 errmsg(
"index \"%s\" cannot be verified using transaction snapshot",
539 if (
state->rootdescend && !
state->heapkeyspace)
541 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
542 errmsg(
"cannot verify that tuples from index \"%s\" can each be found by an independent index search",
544 errhint(
"Only B-Tree version 4 indexes support rootdescend verification.")));
569 errdetail_internal(
"Fast root block %u (level %u) differs from true root block %u (level %u).",
592 (
errcode(ERRCODE_INDEX_CORRUPTED),
593 errmsg(
"index \"%s\" has no valid pages on level below %u or first level",
596 previouslevel = current.
level;
602 if (
state->heapallindexed)
645 elog(
DEBUG1,
"verifying that tuples from index \"%s\" are present in \"%s\"",
707 " (true root level)" : level.
level == 0 ?
" (leaf level)" :
"");
710 state->previncompletesplit =
false;
718 state->targetblock = current;
739 (
errcode(ERRCODE_INDEX_CORRUPTED),
740 errmsg(
"downlink or sibling link points to deleted block in index \"%s\"",
743 current, leftcurrent, opaque->
btpo_prev)));
747 (
errcode(ERRCODE_INDEX_CORRUPTED),
748 errmsg(
"block %u fell off the end of index \"%s\"",
770 (
errcode(ERRCODE_INDEX_CORRUPTED),
771 errmsg(
"block %u is not leftmost in index \"%s\"",
776 (
errcode(ERRCODE_INDEX_CORRUPTED),
777 errmsg(
"block %u is not true root in index \"%s\"",
829 (
errcode(ERRCODE_INDEX_CORRUPTED),
830 errmsg(
"leftmost down link for level points to block in index \"%s\" whose level is not one level down",
832 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
841 if (current == leftcurrent || current == opaque->
btpo_prev)
843 (
errcode(ERRCODE_INDEX_CORRUPTED),
844 errmsg(
"circular link chain found in block %u of index \"%s\"",
847 leftcurrent = current;
854 state->lowkey = NULL;
889 while (current !=
P_NONE);
895 state->lowkey = NULL;
901 return nextleveldown;
944 if (!
state->readonly)
974 if (newtargetblock != leftcurrent)
978 state->checkstrategy);
984 btpo_prev_from_target = opaque->
btpo_prev;
1006 if (btpo_prev_from_target == leftcurrent)
1010 (
errcode(ERRCODE_INTERNAL_ERROR),
1011 errmsg_internal(
"harmless concurrent page split detected in index \"%s\"",
1014 leftcurrent, newtargetblock,
1015 state->targetblock)));
1026 state->targetblock = newtargetblock;
1030 (
errcode(ERRCODE_INDEX_CORRUPTED),
1031 errmsg(
"left link/right link pair in index \"%s\" not in agreement",
1034 state->targetblock, leftcurrent,
1035 btpo_prev_from_target)));
1083 elog(
DEBUG2,
"verifying %u items on %s block %u", max,
1084 P_ISLEAF(topaque) ?
"leaf" :
"internal",
state->targetblock);
1103 (
errcode(ERRCODE_INDEX_CORRUPTED),
1104 errmsg(
"wrong number of high key index tuple attributes in index \"%s\"",
1109 P_ISLEAF(topaque) ?
"heap" :
"index",
1127 bool lowersizelimit;
1133 state->target, offset);
1145 (
errcode(ERRCODE_INDEX_CORRUPTED),
1146 errmsg(
"index tuple size does not equal lp_len in index \"%s\"",
1149 state->targetblock, offset,
1152 errhint(
"This could be a torn page problem.")));
1169 (
errcode(ERRCODE_INDEX_CORRUPTED),
1170 errmsg(
"wrong number of index tuple attributes in index \"%s\"",
1175 P_ISLEAF(topaque) ?
"heap" :
"index",
1219 (
errcode(ERRCODE_INDEX_CORRUPTED),
1220 errmsg(
"could not find tuple using search from root page in index \"%s\"",
1245 char *itid =
psprintf(
"(%u,%u)",
state->targetblock, offset);
1248 (
errcode(ERRCODE_INDEX_CORRUPTED),
1249 errmsg_internal(
"posting list contains misplaced TID in index \"%s\"",
1302 (
errcode(ERRCODE_INDEX_CORRUPTED),
1303 errmsg(
"index row size %zu exceeds maximum for index \"%s\"",
1307 P_ISLEAF(topaque) ?
"heap" :
"index",
1329 if (norm != logtuple)
1409 (
errcode(ERRCODE_INDEX_CORRUPTED),
1410 errmsg(
"high key invariant violated for index \"%s\"",
1414 P_ISLEAF(topaque) ?
"heap" :
"index",
1455 (
errcode(ERRCODE_INDEX_CORRUPTED),
1456 errmsg(
"item order invariant violated for index \"%s\"",
1459 "higher index tid=%s (points to %s tid=%s) "
1462 P_ISLEAF(topaque) ?
"heap" :
"index",
1465 P_ISLEAF(topaque) ?
"heap" :
"index",
1487 else if (offset == max)
1504 if (!
state->readonly)
1519 (
errcode(ERRCODE_INDEX_CORRUPTED),
1520 errmsg(
"cross page item order invariant violated for index \"%s\"",
1523 state->targetblock, offset,
1630 errmsg_internal(
"level %u sibling page in block %u of index \"%s\" was found deleted or half dead",
1632 errdetail_internal(
"Deleted page found when building scankey from right sibling.")));
1761 P_ISLEAF(opaque) ?
"leaf" :
"internal", targetnext,
1860 bool rightsplit =
state->previncompletesplit;
1869 state->target, target_downlinkoffnum);
1906 state->previncompletesplit =
false;
1913 (
errcode(ERRCODE_INDEX_CORRUPTED),
1914 errmsg(
"can't traverse from downlink %u to downlink %u of index \"%s\"",
1915 state->prevrightlink, downlink,
1919 if (blkno == downlink && loaded_child)
1920 page = loaded_child;
1929 (
errcode(ERRCODE_INDEX_CORRUPTED),
1930 errmsg(
"the first child of leftmost target page is not leftmost of its level in index \"%s\"",
1933 state->targetblock, blkno,
1940 (
errcode(ERRCODE_INDEX_CORRUPTED),
1941 errmsg(
"block found while following rightlinks from child of index \"%s\" has invalid level",
1943 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
1944 blkno, target_level - 1, opaque->
btpo_level)));
1947 if ((!first && blkno ==
state->prevrightlink) || blkno == opaque->
btpo_prev)
1949 (
errcode(ERRCODE_INDEX_CORRUPTED),
1950 errmsg(
"circular link chain found in block %u of index \"%s\"",
1953 if (blkno != downlink && !
P_IGNORE(opaque))
1997 if (blkno == downlink)
2000 pivotkey_offset = target_downlinkoffnum;
2015 (
errcode(ERRCODE_INDEX_CORRUPTED),
2016 errmsg(
"child high key is greater than rightmost pivot key on target level in index \"%s\"",
2019 state->targetblock, blkno,
2024 state->target, pivotkey_offset);
2045 (
errcode(ERRCODE_INDEX_CORRUPTED),
2046 errmsg(
"can't find left sibling high key in index \"%s\"",
2049 state->targetblock, blkno,
2051 itup =
state->lowkey;
2057 (
errcode(ERRCODE_INDEX_CORRUPTED),
2058 errmsg(
"mismatch between parent key and child high key in index \"%s\"",
2061 state->targetblock, blkno,
2067 if (blkno == downlink)
2070 state->previncompletesplit = rightsplit;
2078 if (page != loaded_child)
2111 state->target, downlinkoffnum);
2197 (
errcode(ERRCODE_INDEX_CORRUPTED),
2198 errmsg(
"downlink to deleted page found in index \"%s\"",
2201 state->targetblock, childblock,
2205 offset <= maxoffset;
2238 (
errcode(ERRCODE_INDEX_CORRUPTED),
2239 errmsg(
"down-link lower bound invariant violated for index \"%s\"",
2242 state->targetblock, childblock, offset,
2309 errmsg_internal(
"harmless interrupted page split detected in index \"%s\"",
2330 (
errcode(ERRCODE_INDEX_CORRUPTED),
2331 errmsg(
"leaf index block lacks downlink in index \"%s\"",
2338 elog(
DEBUG1,
"checking for interrupted multi-level deletion due to missing downlink in index \"%s\"",
2358 (
errcode(ERRCODE_INDEX_CORRUPTED),
2359 errmsg_internal(
"downlink points to block in index \"%s\" whose level is not one level down",
2361 errdetail_internal(
"Top parent/under check block=%u block pointed to=%u expected level=%u level in pointed to block=%u.",
2396 (
errcode(ERRCODE_INDEX_CORRUPTED),
2397 errmsg_internal(
"downlink to deleted leaf page found in index \"%s\"",
2399 errdetail_internal(
"Top parent/target block=%u leaf block=%u top parent/under check lsn=%X/%X.",
2422 (
errcode(ERRCODE_INDEX_CORRUPTED),
2423 errmsg(
"internal index block lacks downlink in index \"%s\"",
2487 bool *isnull,
bool tupleIsAlive,
void *checkstate)
2505 errmsg(
"heap tuple (%u,%u) from table \"%s\" lacks matching index tuple within index \"%s\"",
2511 ?
errhint(
"Retrying verification using the function bt_index_parent_check() might provide a more specific error.")
2514 state->heaptuplespresent++;
2560 bool formnewtup =
false;
2571 for (
i = 0;
i < tupleDescriptor->
natts;
i++)
2578 toast_free[
i] =
false;
2582 if (att->attbyval || att->attlen != -1 || isnull[
i])
2592 (
errcode(ERRCODE_INDEX_CORRUPTED),
2593 errmsg(
"external varlena datum in tuple that references heap row (%u,%u) in index \"%s\"",
2601 toast_free[
i] =
true;
2622 for (
i = 0;
i < tupleDescriptor->
natts;
i++)
2705 insertstate.
itup = itup;
2710 insertstate.
buf = lbuf;
2788 if (!
key->heapkeyspace)
2819 if (
key->keysz == uppnkeyatts)
2820 return key->scantid == NULL && rheaptid != NULL;
2822 return key->keysz < uppnkeyatts;
2872 if (!
key->heapkeyspace)
2913 if (!
key->heapkeyspace)
2934 if (
key->keysz == uppnkeyatts)
2935 return key->scantid == NULL && childheaptid != NULL;
2937 return key->keysz < uppnkeyatts;
2972 state->checkstrategy);
2989 (
errcode(ERRCODE_INDEX_CORRUPTED),
2990 errmsg(
"invalid meta page found at block %u in index \"%s\"",
3001 (
errcode(ERRCODE_INDEX_CORRUPTED),
3002 errmsg(
"index \"%s\" meta page is corrupt",
3008 (
errcode(ERRCODE_INDEX_CORRUPTED),
3009 errmsg(
"version mismatch in index \"%s\": file version %d, "
3010 "current version %d, minimum supported version %d",
3030 (
errcode(ERRCODE_INDEX_CORRUPTED),
3031 errmsg_internal(
"invalid leaf page level %u for block %u in index \"%s\"",
3037 (
errcode(ERRCODE_INDEX_CORRUPTED),
3038 errmsg_internal(
"invalid internal page level 0 for block %u in index \"%s\"",
3065 (
errcode(ERRCODE_INDEX_CORRUPTED),
3066 errmsg(
"Number of items on block %u of index \"%s\" exceeds MaxIndexTuplesPerPage (%u)",
3072 (
errcode(ERRCODE_INDEX_CORRUPTED),
3073 errmsg(
"internal block %u in index \"%s\" lacks high key and/or at least one downlink",
3078 (
errcode(ERRCODE_INDEX_CORRUPTED),
3079 errmsg(
"non-rightmost leaf block %u in index \"%s\" lacks high key item",
3091 (
errcode(ERRCODE_INDEX_CORRUPTED),
3092 errmsg(
"internal page block %u in index \"%s\" is half-dead",
3094 errhint(
"This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it.")));
3102 (
errcode(ERRCODE_INDEX_CORRUPTED),
3103 errmsg_internal(
"internal page block %u in index \"%s\" has garbage items",
3108 (
errcode(ERRCODE_INDEX_CORRUPTED),
3109 errmsg_internal(
"full transaction id page flag appears in non-deleted block %u in index \"%s\"",
3114 (
errcode(ERRCODE_INDEX_CORRUPTED),
3168 (
errcode(ERRCODE_INDEX_CORRUPTED),
3169 errmsg(
"line pointer points past end of tuple space in index \"%s\"",
3184 (
errcode(ERRCODE_INDEX_CORRUPTED),
3185 errmsg(
"invalid line pointer storage in index \"%s\"",
3213 (
errcode(ERRCODE_INDEX_CORRUPTED),
3214 errmsg_internal(
"block %u or its right sibling block or child block in index \"%s\" has unexpected pivot tuple",
3220 (
errcode(ERRCODE_INDEX_CORRUPTED),
3221 errmsg_internal(
"block %u or its right sibling block or child block in index \"%s\" has unexpected non-pivot tuple",
3228 (
errcode(ERRCODE_INDEX_CORRUPTED),
3229 errmsg(
"block %u or its right sibling block or child block in index \"%s\" contains non-pivot tuple that lacks a heap TID",
3260 return &itup->
t_tid;
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void bloom_free(bloom_filter *filter)
bloom_filter * bloom_create(int64 total_elems, int bloom_work_mem, uint64 seed)
double bloom_prop_bits_set(bloom_filter *filter)
bool bloom_lacks_element(bloom_filter *filter, unsigned char *elem, size_t len)
void bloom_add_element(bloom_filter *filter, unsigned char *elem, size_t len)
static Datum values[MAXATTR]
void UnlockReleaseBuffer(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static XLogRecPtr PageGetLSN(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define OidIsValid(objectId)
elog(ERROR, "%s: %s", p2, msg)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_DETOAST_DATUM(datum)
#define PG_GETARG_BOOL(n)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
int NewGUCNestLevel(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
#define HeapTupleHeaderGetXmin(tup)
Oid IndexGetRelation(Oid indexId, bool missing_ok)
IndexInfo * BuildIndexInfo(Relation index)
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
#define ItemIdGetLength(itemId)
#define ItemIdGetOffset(itemId)
#define ItemIdIsDead(itemId)
#define ItemIdIsUsed(itemId)
#define ItemIdIsRedirected(itemId)
#define ItemIdGetFlags(itemId)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
#define IndexTupleHasVarwidths(itup)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define MaxIndexTuplesPerPage
Assert(fmt[strlen(fmt) - 1] !='\n')
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define SECURITY_RESTRICTED_OPERATION
#define CHECK_FOR_INTERRUPTS()
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
IndexTuple _bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids)
void _bt_relbuf(Relation rel, Buffer buf)
void _bt_checkpage(Relation rel, Buffer buf)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
#define P_HAS_FULLXID(opaque)
#define P_ISHALFDEAD(opaque)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
#define BTREE_MIN_VERSION
#define P_HAS_GARBAGE(opaque)
#define BTMaxItemSizeNoHeapTid(page)
#define P_LEFTMOST(opaque)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
static BlockNumber BTreeTupleGetTopParent(IndexTuple leafhikey)
#define MaxTIDsPerBTreePage
#define P_FIRSTDATAKEY(opaque)
#define P_RIGHTMOST(opaque)
#define BTMaxItemSize(page)
#define P_INCOMPLETE_SPLIT(opaque)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static BlockNumber BTreeTupleGetDownLink(IndexTuple pivot)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
#define BTreeTupleGetNAtts(itup, rel)
BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, int access)
OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate)
int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum)
void _bt_freestack(BTStack stack)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
bool _bt_allequalimage(Relation rel, bool debugmessage)
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
#define ERRCODE_DATA_CORRUPTED
uint64 pg_prng_uint64(pg_prng_state *state)
pg_prng_state pg_global_prng_state
#define ERRCODE_T_R_SERIALIZATION_FAILURE
#define ERRCODE_UNDEFINED_TABLE
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
char * psprintf(const char *fmt,...)
static int cmp(const chr *x, const chr *y, size_t len)
static SMgrRelation RelationGetSmgr(Relation rel)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RELATION_IS_OTHER_TEMP(relation)
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Snapshot GetTransactionSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
BufferAccessStrategy checkstrategy
BlockNumber prevrightlink
MemoryContext targetcontext
uint16 * ii_ExclusionStrats
struct HeapTupleData * rd_indextuple
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
static TableScanDesc table_beginscan_strat(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key, bool allow_strat, bool allow_sync)
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
#define TransactionIdIsValid(xid)
#define TupleDescAttr(tupdesc, i)
#define VARATT_IS_COMPRESSED(PTR)
#define VARATT_IS_EXTERNAL(PTR)
static bool offset_is_negative_infinity(BTPageOpaque opaque, OffsetNumber offset)
static bool invariant_l_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber upperbound)
static ItemPointer BTreeTupleGetPointsToTID(IndexTuple itup)
struct BtreeCheckState BtreeCheckState
static IndexTuple bt_posting_plain_tuple(IndexTuple itup, int n)
static void bt_target_page_check(BtreeCheckState *state)
static bool bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2)
static bool invariant_leq_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber upperbound)
Datum bt_index_parent_check(PG_FUNCTION_ARGS)
static void bt_child_highkey_check(BtreeCheckState *state, OffsetNumber target_downlinkoffnum, Page loaded_child, uint32 target_level)
static BTScanInsert bt_mkscankey_pivotsearch(Relation rel, IndexTuple itup)
Datum bt_index_check(PG_FUNCTION_ARGS)
static BtreeLevel bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
static void bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, BlockNumber blkno, Page page)
PG_FUNCTION_INFO_V1(bt_index_check)
static ItemId PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, Page page, OffsetNumber offset)
static void bt_tuple_present_callback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *checkstate)
static void bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, bool readonly, bool heapallindexed, bool rootdescend)
static void bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, bool rootdescend)
static bool btree_index_mainfork_expected(Relation rel)
static bool bt_rootdescend(BtreeCheckState *state, IndexTuple itup)
static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state)
static bool invariant_g_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber lowerbound)
#define InvalidBtreeLevel
static Page palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
static IndexTuple bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
static void bt_recheck_sibling_links(BtreeCheckState *state, BlockNumber btpo_prev_from_target, BlockNumber leftcurrent)
static ItemPointer BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, IndexTuple itup, bool nonpivot)
#define BTreeTupleGetNKeyAtts(itup, rel)
static void bt_child_check(BtreeCheckState *state, BTScanInsert targetkey, OffsetNumber downlinkoffnum)
static void btree_index_checkable(Relation rel)
static bool invariant_l_nontarget_offset(BtreeCheckState *state, BTScanInsert key, BlockNumber nontargetblock, Page nontarget, OffsetNumber upperbound)
struct BtreeLevel BtreeLevel
#define IsolationUsesXactSnapshot()
bool RecoveryInProgress(void)
#define LSN_FORMAT_ARGS(lsn)