@ -35,6 +35,7 @@
# include "lib/bloomfilter.h"
# include "lib/bloomfilter.h"
# include "miscadmin.h"
# include "miscadmin.h"
# include "storage/lmgr.h"
# include "storage/lmgr.h"
# include "storage/smgr.h"
# include "utils/memutils.h"
# include "utils/memutils.h"
# include "utils/snapmgr.h"
# include "utils/snapmgr.h"
@ -128,6 +129,7 @@ PG_FUNCTION_INFO_V1(bt_index_parent_check);
static void bt_index_check_internal ( Oid indrelid , bool parentcheck ,
static void bt_index_check_internal ( Oid indrelid , bool parentcheck ,
bool heapallindexed , bool rootdescend ) ;
bool heapallindexed , bool rootdescend ) ;
static inline void btree_index_checkable ( Relation rel ) ;
static inline void btree_index_checkable ( Relation rel ) ;
static inline bool btree_index_mainfork_expected ( Relation rel ) ;
static void bt_check_every_level ( Relation rel , Relation heaprel ,
static void bt_check_every_level ( Relation rel , Relation heaprel ,
bool heapkeyspace , bool readonly , bool heapallindexed ,
bool heapkeyspace , bool readonly , bool heapallindexed ,
bool rootdescend ) ;
bool rootdescend ) ;
@ -225,7 +227,6 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
Oid heapid ;
Oid heapid ;
Relation indrel ;
Relation indrel ;
Relation heaprel ;
Relation heaprel ;
bool heapkeyspace ;
LOCKMODE lockmode ;
LOCKMODE lockmode ;
if ( parentcheck )
if ( parentcheck )
@ -275,10 +276,22 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
/* Relation suitable for checking as B-Tree? */
/* Relation suitable for checking as B-Tree? */
btree_index_checkable ( indrel ) ;
btree_index_checkable ( indrel ) ;
/* Check index, possibly against table it is an index on */
if ( btree_index_mainfork_expected ( indrel ) )
heapkeyspace = _bt_heapkeyspace ( indrel ) ;
{
bt_check_every_level ( indrel , heaprel , heapkeyspace , parentcheck ,
bool heapkeyspace ;
heapallindexed , rootdescend ) ;
RelationOpenSmgr ( indrel ) ;
if ( ! smgrexists ( indrel - > rd_smgr , MAIN_FORKNUM ) )
ereport ( ERROR ,
( errcode ( ERRCODE_INDEX_CORRUPTED ) ,
errmsg ( " index \" %s \" lacks a main relation fork " ,
RelationGetRelationName ( indrel ) ) ) ) ;
/* Check index, possibly against table it is an index on */
heapkeyspace = _bt_heapkeyspace ( indrel ) ;
bt_check_every_level ( indrel , heaprel , heapkeyspace , parentcheck ,
heapallindexed , rootdescend ) ;
}
/*
/*
* Release locks early . That ' s ok here because nothing in the called
* Release locks early . That ' s ok here because nothing in the called
@ -324,6 +337,28 @@ btree_index_checkable(Relation rel)
errdetail ( " Index is not valid. " ) ) ) ;
errdetail ( " Index is not valid. " ) ) ) ;
}
}
/*
* Check if B - Tree index relation should have a file for its main relation
* fork . Verification uses this to skip unlogged indexes when in hot standby
* mode , where there is simply nothing to verify .
*
* NB : Caller should call btree_index_checkable ( ) before calling here .
*/
static inline bool
btree_index_mainfork_expected ( Relation rel )
{
if ( rel - > rd_rel - > relpersistence ! = RELPERSISTENCE_UNLOGGED | |
! RecoveryInProgress ( ) )
return true ;
ereport ( NOTICE ,
( errcode ( ERRCODE_READ_ONLY_SQL_TRANSACTION ) ,
errmsg ( " cannot verify unlogged index \" %s \" during recovery, skipping " ,
RelationGetRelationName ( rel ) ) ) ) ;
return false ;
}
/*
/*
* Main entry point for B - Tree SQL - callable functions . Walks the B - Tree in
* Main entry point for B - Tree SQL - callable functions . Walks the B - Tree in
* logical order , verifying invariants as it goes . Optionally , verification
* logical order , verifying invariants as it goes . Optionally , verification