commit 26b97b68db2727de3c946d7fcb7d47aa699cf277 Author: Georgy Rylov Date: Thu Jan 9 13:36:02 2020 +0500 amcheck verify true root on replicas Here I add checking true root by getting info about it from meta page under lock instead of taking lock for the whole table like in parent_check. diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index 6a058ccdac..67d07f2ba5 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -167,6 +167,7 @@ static ItemId PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, Page page, OffsetNumber offset); static inline ItemPointer BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, IndexTuple itup, bool nonpivot); +static void bt_check_trueroot(BtreeCheckState *state); /* * bt_index_check(index regclass, heapallindexed boolean) @@ -738,6 +739,10 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) errmsg("block %u is not true root in index \"%s\"", current, RelationGetRelationName(state->rel)))); } + else + { + bt_check_trueroot(state); + } /* * Before beginning any non-trivial examination of level, prepare @@ -2571,3 +2576,34 @@ BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, IndexTuple itup, return result; } + +static void bt_check_trueroot(BtreeCheckState *state) +{ + Buffer meta_buffer; + Page meta_page, root_page; + BTMetaPageData *metad; + BTPageOpaque root_opaque; + bool is_root; + meta_page = palloc(BLCKSZ); + meta_buffer = ReadBufferExtended(state->rel, MAIN_FORKNUM, BTREE_METAPAGE, RBM_NORMAL, + state->checkstrategy); + LockBuffer(meta_buffer, BT_READ); + /* + * Perform the same basic sanity checking that nbtree itself performs for + * every page: + */ + _bt_checkpage(state->rel, meta_buffer); + /* Only use copy of page in palloc()'d memory */ + memcpy(meta_page, BufferGetPage(meta_buffer), BLCKSZ); + /* Get true root block from meta-page */ + metad = BTPageGetMeta(meta_page); + root_page = palloc_btree_page(state, metad->btm_root); + root_opaque = (BTPageOpaque) PageGetSpecialPointer(root_page); + is_root = P_ISROOT(root_opaque); + UnlockReleaseBuffer(meta_buffer); + if (!is_root) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("block %u is not true root in index \"%s\"", + metad->btm_root, RelationGetRelationName(state->rel)))); +}