@ -33,7 +33,6 @@
# include "storage/predicate.h"
# include "storage/predicate.h"
# include "utils/snapmgr.h"
# include "utils/snapmgr.h"
static void _bt_cachemetadata ( Relation rel , BTMetaPageData * input ) ;
static BTMetaPageData * _bt_getmeta ( Relation rel , Buffer metabuf ) ;
static BTMetaPageData * _bt_getmeta ( Relation rel , Buffer metabuf ) ;
static bool _bt_mark_page_halfdead ( Relation rel , Buffer buf , BTStack stack ) ;
static bool _bt_mark_page_halfdead ( Relation rel , Buffer buf , BTStack stack ) ;
static bool _bt_unlink_halfdead_page ( Relation rel , Buffer leafbuf ,
static bool _bt_unlink_halfdead_page ( Relation rel , Buffer leafbuf ,
@ -109,48 +108,13 @@ _bt_upgrademetapage(Page page)
( ( char * ) metad + sizeof ( BTMetaPageData ) ) - ( char * ) page ;
( ( char * ) metad + sizeof ( BTMetaPageData ) ) - ( char * ) page ;
}
}
/*
* Cache metadata from input meta page to rel - > rd_amcache .
*/
static void
_bt_cachemetadata ( Relation rel , BTMetaPageData * input )
{
BTMetaPageData * cached_metad ;
/* We assume rel->rd_amcache was already freed by caller */
Assert ( rel - > rd_amcache = = NULL ) ;
rel - > rd_amcache = MemoryContextAlloc ( rel - > rd_indexcxt ,
sizeof ( BTMetaPageData ) ) ;
/* Meta page should be of supported version */
Assert ( input - > btm_version > = BTREE_MIN_VERSION & &
input - > btm_version < = BTREE_VERSION ) ;
cached_metad = ( BTMetaPageData * ) rel - > rd_amcache ;
if ( input - > btm_version > = BTREE_NOVAC_VERSION )
{
/* Version with compatible meta-data, no need to upgrade */
memcpy ( cached_metad , input , sizeof ( BTMetaPageData ) ) ;
}
else
{
/*
* Upgrade meta - data : copy available information from meta - page and
* fill new fields with default values .
*
* Note that we cannot upgrade to version 4 + without a REINDEX , since
* extensive on - disk changes are required .
*/
memcpy ( cached_metad , input , offsetof ( BTMetaPageData , btm_oldest_btpo_xact ) ) ;
cached_metad - > btm_version = BTREE_NOVAC_VERSION ;
cached_metad - > btm_oldest_btpo_xact = InvalidTransactionId ;
cached_metad - > btm_last_cleanup_num_heap_tuples = - 1.0 ;
}
}
/*
/*
* Get metadata from share - locked buffer containing metapage , while performing
* Get metadata from share - locked buffer containing metapage , while performing
* standard sanity checks . Sanity checks here must match _bt_getroot ( ) .
* standard sanity checks .
*
* Callers that cache data returned here in local cache should note that an
* on - the - fly upgrade using _bt_upgrademetapage ( ) can change the version field
* and BTREE_NOVAC_VERSION specific fields without invalidating local cache .
*/
*/
static BTMetaPageData *
static BTMetaPageData *
_bt_getmeta ( Relation rel , Buffer metabuf )
_bt_getmeta ( Relation rel , Buffer metabuf )
@ -291,8 +255,6 @@ Buffer
_bt_getroot ( Relation rel , int access )
_bt_getroot ( Relation rel , int access )
{
{
Buffer metabuf ;
Buffer metabuf ;
Page metapg ;
BTPageOpaque metaopaque ;
Buffer rootbuf ;
Buffer rootbuf ;
Page rootpage ;
Page rootpage ;
BTPageOpaque rootopaque ;
BTPageOpaque rootopaque ;
@ -345,30 +307,13 @@ _bt_getroot(Relation rel, int access)
}
}
metabuf = _bt_getbuf ( rel , BTREE_METAPAGE , BT_READ ) ;
metabuf = _bt_getbuf ( rel , BTREE_METAPAGE , BT_READ ) ;
metapg = BufferGetPage ( metabuf ) ;
metad = _bt_getmeta ( rel , metabuf ) ;
metaopaque = ( BTPageOpaque ) PageGetSpecialPointer ( metapg ) ;
metad = BTPageGetMeta ( metapg ) ;
/* sanity-check the metapage */
if ( ! P_ISMETA ( metaopaque ) | |
metad - > btm_magic ! = BTREE_MAGIC )
ereport ( ERROR ,
( errcode ( ERRCODE_INDEX_CORRUPTED ) ,
errmsg ( " index \" %s \" is not a btree " ,
RelationGetRelationName ( rel ) ) ) ) ;
if ( metad - > btm_version < BTREE_MIN_VERSION | |
metad - > btm_version > BTREE_VERSION )
ereport ( ERROR ,
( errcode ( ERRCODE_INDEX_CORRUPTED ) ,
errmsg ( " version mismatch in index \" %s \" : file version %d, "
" current version %d, minimal supported version %d " ,
RelationGetRelationName ( rel ) ,
metad - > btm_version , BTREE_VERSION , BTREE_MIN_VERSION ) ) ) ;
/* if no root page initialized yet, do it */
/* if no root page initialized yet, do it */
if ( metad - > btm_root = = P_NONE )
if ( metad - > btm_root = = P_NONE )
{
{
Page metapg ;
/* If access = BT_READ, caller doesn't want us to create root yet */
/* If access = BT_READ, caller doesn't want us to create root yet */
if ( access = = BT_READ )
if ( access = = BT_READ )
{
{
@ -410,6 +355,8 @@ _bt_getroot(Relation rel, int access)
rootopaque - > btpo_flags = ( BTP_LEAF | BTP_ROOT ) ;
rootopaque - > btpo_flags = ( BTP_LEAF | BTP_ROOT ) ;
rootopaque - > btpo . level = 0 ;
rootopaque - > btpo . level = 0 ;
rootopaque - > btpo_cycleid = 0 ;
rootopaque - > btpo_cycleid = 0 ;
/* Get raw page pointer for metapage */
metapg = BufferGetPage ( metabuf ) ;
/* NO ELOG(ERROR) till meta is updated */
/* NO ELOG(ERROR) till meta is updated */
START_CRIT_SECTION ( ) ;
START_CRIT_SECTION ( ) ;
@ -471,7 +418,7 @@ _bt_getroot(Relation rel, int access)
LockBuffer ( rootbuf , BUFFER_LOCK_UNLOCK ) ;
LockBuffer ( rootbuf , BUFFER_LOCK_UNLOCK ) ;
LockBuffer ( rootbuf , BT_READ ) ;
LockBuffer ( rootbuf , BT_READ ) ;
/* okay, metadata is correct, release lock on it */
/* okay, metadata is correct, release lock on it without caching */
_bt_relbuf ( rel , metabuf ) ;
_bt_relbuf ( rel , metabuf ) ;
}
}
else
else
@ -483,7 +430,9 @@ _bt_getroot(Relation rel, int access)
/*
/*
* Cache the metapage data for next time
* Cache the metapage data for next time
*/
*/
_bt_cachemetadata ( rel , metad ) ;
rel - > rd_amcache = MemoryContextAlloc ( rel - > rd_indexcxt ,
sizeof ( BTMetaPageData ) ) ;
memcpy ( rel - > rd_amcache , metad , sizeof ( BTMetaPageData ) ) ;
/*
/*
* We are done with the metapage ; arrange to release it via first
* We are done with the metapage ; arrange to release it via first
@ -657,16 +606,19 @@ _bt_getrootheight(Relation rel)
/*
/*
* Cache the metapage data for next time
* Cache the metapage data for next time
*/
*/
_bt_cachemetadata ( rel , metad ) ;
rel - > rd_amcache = MemoryContextAlloc ( rel - > rd_indexcxt ,
/* We shouldn't have cached it if any of these fail */
sizeof ( BTMetaPageData ) ) ;
Assert ( metad - > btm_magic = = BTREE_MAGIC ) ;
memcpy ( rel - > rd_amcache , metad , sizeof ( BTMetaPageData ) ) ;
Assert ( metad - > btm_version > = BTREE_NOVAC_VERSION ) ;
Assert ( metad - > btm_fastroot ! = P_NONE ) ;
_bt_relbuf ( rel , metabuf ) ;
_bt_relbuf ( rel , metabuf ) ;
}
}
/* Get cached page */
/* Get cached page */
metad = ( BTMetaPageData * ) rel - > rd_amcache ;
metad = ( BTMetaPageData * ) rel - > rd_amcache ;
/* We shouldn't have cached it if any of these fail */
Assert ( metad - > btm_magic = = BTREE_MAGIC ) ;
Assert ( metad - > btm_version > = BTREE_MIN_VERSION ) ;
Assert ( metad - > btm_version < = BTREE_VERSION ) ;
Assert ( metad - > btm_fastroot ! = P_NONE ) ;
return metad - > btm_fastlevel ;
return metad - > btm_fastlevel ;
}
}
@ -707,17 +659,26 @@ _bt_heapkeyspace(Relation rel)
/*
/*
* Cache the metapage data for next time
* Cache the metapage data for next time
*
* An on - the - fly version upgrade performed by _bt_upgrademetapage ( )
* can change the nbtree version for an index without invalidating any
* local cache . This is okay because it can only happen when moving
* from version 2 to version 3 , both of which are ! heapkeyspace
* versions .
*/
*/
_bt_cachemetadata ( rel , metad ) ;
rel - > rd_amcache = MemoryContextAlloc ( rel - > rd_indexcxt ,
/* We shouldn't have cached it if any of these fail */
sizeof ( BTMetaPageData ) ) ;
Assert ( metad - > btm_magic = = BTREE_MAGIC ) ;
memcpy ( rel - > rd_amcache , metad , sizeof ( BTMetaPageData ) ) ;
Assert ( metad - > btm_version > = BTREE_NOVAC_VERSION ) ;
Assert ( metad - > btm_fastroot ! = P_NONE ) ;
_bt_relbuf ( rel , metabuf ) ;
_bt_relbuf ( rel , metabuf ) ;
}
}
/* Get cached page */
/* Get cached page */
metad = ( BTMetaPageData * ) rel - > rd_amcache ;
metad = ( BTMetaPageData * ) rel - > rd_amcache ;
/* We shouldn't have cached it if any of these fail */
Assert ( metad - > btm_magic = = BTREE_MAGIC ) ;
Assert ( metad - > btm_version > = BTREE_MIN_VERSION ) ;
Assert ( metad - > btm_version < = BTREE_VERSION ) ;
Assert ( metad - > btm_fastroot ! = P_NONE ) ;
return metad - > btm_version > BTREE_NOVAC_VERSION ;
return metad - > btm_version > BTREE_NOVAC_VERSION ;
}
}