@ -131,7 +131,6 @@ static void SetReindexProcessing(Oid heapOid, Oid indexOid);
static void ResetReindexProcessing ( void ) ;
static void SetReindexPending ( List * indexes ) ;
static void RemoveReindexPending ( Oid indexOid ) ;
static void ResetReindexPending ( void ) ;
/*
@ -1543,8 +1542,8 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
newIndexForm - > indisclustered = oldIndexForm - > indisclustered ;
/*
* Mark the new index as valid , and the old index as invalid similarly
* to what index_set_state_flags ( ) does .
* Mark the new index as valid , and the old index as invalid similarly to
* what index_set_state_flags ( ) does .
*/
newIndexForm - > indisvalid = true ;
oldIndexForm - > indisvalid = false ;
@ -3525,25 +3524,18 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
indexInfo - > ii_ExclusionStrats = NULL ;
}
/* ensure SetReindexProcessing state isn't leaked */
PG_TRY ( ) ;
{
/* Suppress use of the target index while rebuilding it */
SetReindexProcessing ( heapId , indexId ) ;
/* Suppress use of the target index while rebuilding it */
SetReindexProcessing ( heapId , indexId ) ;
/* Create a new physical relation for the index */
RelationSetNewRelfilenode ( iRel , persistence ) ;
/* Create a new physical relation for the index */
RelationSetNewRelfilenode ( iRel , persistence ) ;
/* Initialize the index and rebuild */
/* Note: we do not need to re-establish pkey setting */
index_build ( heapRelation , iRel , indexInfo , true , true ) ;
}
PG_FINALLY ( ) ;
{
/* Make sure flag gets cleared on error exit */
ResetReindexProcessing ( ) ;
}
PG_END_TRY ( ) ;
/* Initialize the index and rebuild */
/* Note: we do not need to re-establish pkey setting */
index_build ( heapRelation , iRel , indexInfo , true , true ) ;
/* Re-allow use of target index */
ResetReindexProcessing ( ) ;
/*
* If the index is marked invalid / not - ready / dead ( ie , it ' s from a failed
@ -3680,7 +3672,9 @@ reindex_relation(Oid relid, int flags, int options)
Relation rel ;
Oid toast_relid ;
List * indexIds ;
char persistence ;
bool result ;
ListCell * indexId ;
int i ;
/*
@ -3715,77 +3709,65 @@ reindex_relation(Oid relid, int flags, int options)
*/
indexIds = RelationGetIndexList ( rel ) ;
PG_TRY ( ) ;
if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
{
ListCell * indexId ;
char persistence ;
/* Suppress use of all the indexes until they are rebuilt */
SetReindexPending ( indexIds ) ;
if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
{
/* Suppress use of all the indexes until they are rebuilt */
SetReindexPending ( indexIds ) ;
/*
* Make the new heap contents visible - - - now things might be
* inconsistent !
*/
CommandCounterIncrement ( ) ;
}
/*
* Make the new heap contents visible - - - now things might be
* inconsistent !
*/
CommandCounterIncrement ( ) ;
}
/*
* Compute persistence of indexes : same as that of owning rel , unless
* caller specified otherwise .
*/
if ( flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
persistence = RELPERSISTENCE_UNLOGGED ;
else if ( flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
persistence = RELPERSISTENCE_PERMANENT ;
else
persistence = rel - > rd_rel - > relpersistence ;
/* Reindex all the indexes. */
i = 1 ;
foreach ( indexId , indexIds )
{
Oid indexOid = lfirst_oid ( indexId ) ;
Oid indexNamespaceId = get_rel_namespace ( indexOid ) ;
/*
* Compute persistence of indexes : same as that of owning rel , unless
* caller specified otherwise .
* Skip any invalid indexes on a TOAST table . These can only be
* duplicate leftovers from a failed REINDEX CONCURRENTLY , and if
* rebuilt it would not be possible to drop them anymore .
*/
if ( flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
persistence = RELPERSISTENCE_UNLOGGED ;
else if ( flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
persistence = RELPERSISTENCE_PERMANENT ;
else
persistence = rel - > rd_rel - > relpersistence ;
/* Reindex all the indexes. */
i = 1 ;
foreach ( indexId , indexIds )
if ( IsToastNamespace ( indexNamespaceId ) & &
! get_index_isvalid ( indexOid ) )
{
Oid indexOid = lfirst_oid ( indexId ) ;
Oid indexNamespaceId = get_rel_namespace ( indexOid ) ;
/*
* Skip any invalid indexes on a TOAST table . These can only be
* duplicate leftovers from a failed REINDEX CONCURRENTLY , and if
* rebuilt it would not be possible to drop them anymore .
*/
if ( IsToastNamespace ( indexNamespaceId ) & &
! get_index_isvalid ( indexOid ) )
{
ereport ( WARNING ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
errmsg ( " cannot reindex invalid index \" %s.%s \" on TOAST table, skipping " ,
get_namespace_name ( indexNamespaceId ) ,
get_rel_name ( indexOid ) ) ) ) ;
continue ;
}
ereport ( WARNING ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
errmsg ( " cannot reindex invalid index \" %s.%s \" on TOAST table, skipping " ,
get_namespace_name ( indexNamespaceId ) ,
get_rel_name ( indexOid ) ) ) ) ;
continue ;
}
reindex_index ( indexOid , ! ( flags & REINDEX_REL_CHECK_CONSTRAINTS ) ,
persistence , options ) ;
reindex_index ( indexOid , ! ( flags & REINDEX_REL_CHECK_CONSTRAINTS ) ,
persistence , options ) ;
CommandCounterIncrement ( ) ;
CommandCounterIncrement ( ) ;
/* Index should no longer be in the pending list */
Assert ( ! ReindexIsProcessingIndex ( indexOid ) ) ;
/* Index should no longer be in the pending list */
Assert ( ! ReindexIsProcessingIndex ( indexOid ) ) ;
/* Set index rebuild count */
pgstat_progress_update_param ( PROGRESS_CLUSTER_INDEX_REBUILD_COUNT ,
i ) ;
i + + ;
}
/* Set index rebuild count */
pgstat_progress_update_param ( PROGRESS_CLUSTER_INDEX_REBUILD_COUNT ,
i ) ;
i + + ;
}
PG_FINALLY ( ) ;
{
/* Make sure list gets cleared on error exit */
ResetReindexPending ( ) ;
}
PG_END_TRY ( ) ;
/*
* Close rel , but continue to hold the lock .
@ -3819,6 +3801,7 @@ reindex_relation(Oid relid, int flags, int options)
static Oid currentlyReindexedHeap = InvalidOid ;
static Oid currentlyReindexedIndex = InvalidOid ;
static List * pendingReindexedIndexes = NIL ;
static int reindexingNestLevel = 0 ;
/*
* ReindexIsProcessingHeap
@ -3855,8 +3838,6 @@ ReindexIsProcessingIndex(Oid indexOid)
/*
* SetReindexProcessing
* Set flag that specified heap / index are being reindexed .
*
* NB : caller must use a PG_TRY block to ensure ResetReindexProcessing is done .
*/
static void
SetReindexProcessing ( Oid heapOid , Oid indexOid )
@ -3869,6 +3850,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
currentlyReindexedIndex = indexOid ;
/* Index is no longer "pending" reindex. */
RemoveReindexPending ( indexOid ) ;
/* This may have been set already, but in case it isn't, do so now. */
reindexingNestLevel = GetCurrentTransactionNestLevel ( ) ;
}
/*
@ -3878,17 +3861,16 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
static void
ResetReindexProcessing ( void )
{
/* This may be called in leader error path */
currentlyReindexedHeap = InvalidOid ;
currentlyReindexedIndex = InvalidOid ;
/* reindexingNestLevel remains set till end of (sub)transaction */
}
/*
* SetReindexPending
* Mark the given indexes as pending reindex .
*
* NB : caller must use a PG_TRY block to ensure ResetReindexPending is done .
* Also , we assume that the current memory context stays valid throughout .
* NB : we assume that the current memory context stays valid throughout .
*/
static void
SetReindexPending ( List * indexes )
@ -3899,6 +3881,7 @@ SetReindexPending(List *indexes)
if ( IsInParallelMode ( ) )
elog ( ERROR , " cannot modify reindex state during a parallel operation " ) ;
pendingReindexedIndexes = list_copy ( indexes ) ;
reindexingNestLevel = GetCurrentTransactionNestLevel ( ) ;
}
/*
@ -3915,14 +3898,32 @@ RemoveReindexPending(Oid indexOid)
}
/*
* ResetReindexPending
* Unset reindex - pending status .
* ResetReindexState
* Clear all reindexing state during ( sub ) transaction abort .
*/
static void
ResetReindexPending ( void )
void
ResetReindexState ( int nestLevel )
{
/* This may be called in leader error path */
pendingReindexedIndexes = NIL ;
/*
* Because reindexing is not re - entrant , we don ' t need to cope with nested
* reindexing states . We just need to avoid messing up the outer - level
* state in case a subtransaction fails within a REINDEX . So checking the
* current nest level against that of the reindex operation is sufficient .
*/
if ( reindexingNestLevel > = nestLevel )
{
currentlyReindexedHeap = InvalidOid ;
currentlyReindexedIndex = InvalidOid ;
/*
* We needn ' t try to release the contents of pendingReindexedIndexes ;
* that list should be in a transaction - lifespan context , so it will
* go away automatically .
*/
pendingReindexedIndexes = NIL ;
reindexingNestLevel = 0 ;
}
}
/*
@ -3975,4 +3976,7 @@ RestoreReindexState(void *reindexstate)
lappend_oid ( pendingReindexedIndexes ,
sistate - > pendingReindexedIndexes [ c ] ) ;
MemoryContextSwitchTo ( oldcontext ) ;
/* Note the worker has its own transaction nesting level */
reindexingNestLevel = GetCurrentTransactionNestLevel ( ) ;
}