commit 26b97b68db2727de3c946d7fcb7d47aa699cf277
Author: Georgy Rylov <g0dj4n@gmail.com>
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))));
+}
