@@ -144,7 +144,6 @@ static void SetReindexProcessing(Oid heapOid, Oid indexOid);
144144static void ResetReindexProcessing (void );
145145static void SetReindexPending (List * indexes );
146146static void RemoveReindexPending (Oid indexOid );
147- static void ResetReindexPending (void );
148147
149148
150149/*
@@ -3799,27 +3798,18 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
37993798indexInfo -> ii_ExclusionStrats = NULL ;
38003799}
38013800
3802- /* ensure SetReindexProcessing state isn't leaked */
3803- PG_TRY ();
3804- {
3805- /* Suppress use of the target index while rebuilding it */
3806- SetReindexProcessing (heapId ,indexId );
3801+ /* Suppress use of the target index while rebuilding it */
3802+ SetReindexProcessing (heapId ,indexId );
38073803
3808- /* Create a new physical relation for the index */
3809- RelationSetNewRelfilenode (iRel ,persistence ,InvalidTransactionId ,
3810- InvalidMultiXactId );
3804+ /* Create a new physical relation for the index */
3805+ RelationSetNewRelfilenode (iRel ,persistence ,InvalidTransactionId ,
3806+ InvalidMultiXactId );
38113807
3812- /* Initialize the index and rebuild */
3813- /* Note: we do not need to re-establish pkey setting */
3814- index_build (heapRelation ,iRel ,indexInfo , false, true, true);
3815- }
3816- PG_CATCH ();
3817- {
3818- /* Make sure flag gets cleared on error exit */
3819- ResetReindexProcessing ();
3820- PG_RE_THROW ();
3821- }
3822- PG_END_TRY ();
3808+ /* Initialize the index and rebuild */
3809+ /* Note: we do not need to re-establish pkey setting */
3810+ index_build (heapRelation ,iRel ,indexInfo , false, true, true);
3811+
3812+ /* Re-allow use of target index */
38233813ResetReindexProcessing ();
38243814
38253815/*
@@ -3954,7 +3944,9 @@ reindex_relation(Oid relid, int flags, int options)
39543944Relation rel ;
39553945Oid toast_relid ;
39563946List * indexIds ;
3947+ char persistence ;
39573948bool result ;
3949+ ListCell * indexId ;
39583950
39593951/*
39603952 * Open and lock the relation. ShareLock is sufficient since we only need
@@ -3988,56 +3980,42 @@ reindex_relation(Oid relid, int flags, int options)
39883980 */
39893981indexIds = RelationGetIndexList (rel );
39903982
3991- PG_TRY ();
3983+ if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
39923984{
3993- ListCell * indexId ;
3994- char persistence ;
3995-
3996- if (flags & REINDEX_REL_SUPPRESS_INDEX_USE )
3997- {
3998- /* Suppress use of all the indexes until they are rebuilt */
3999- SetReindexPending (indexIds );
4000-
4001- /*
4002- * Make the new heap contents visible --- now things might be
4003- * inconsistent!
4004- */
4005- CommandCounterIncrement ();
4006- }
3985+ /* Suppress use of all the indexes until they are rebuilt */
3986+ SetReindexPending (indexIds );
40073987
40083988/*
4009- *Compute persistence of indexes: same as that of owning rel, unless
4010- *caller specified otherwise.
3989+ *Make the new heap contents visible --- now things might be
3990+ *inconsistent!
40113991 */
4012- if (flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
4013- persistence = RELPERSISTENCE_UNLOGGED ;
4014- else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
4015- persistence = RELPERSISTENCE_PERMANENT ;
4016- else
4017- persistence = rel -> rd_rel -> relpersistence ;
3992+ CommandCounterIncrement ();
3993+ }
40183994
4019- /* Reindex all the indexes. */
4020- foreach (indexId ,indexIds )
4021- {
4022- Oid indexOid = lfirst_oid (indexId );
3995+ /*
3996+ * Compute persistence of indexes: same as that of owning rel, unless
3997+ * caller specified otherwise.
3998+ */
3999+ if (flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
4000+ persistence = RELPERSISTENCE_UNLOGGED ;
4001+ else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
4002+ persistence = RELPERSISTENCE_PERMANENT ;
4003+ else
4004+ persistence = rel -> rd_rel -> relpersistence ;
40234005
4024- reindex_index (indexOid , !(flags & REINDEX_REL_CHECK_CONSTRAINTS ),
4025- persistence ,options );
4006+ /* Reindex all the indexes. */
4007+ foreach (indexId ,indexIds )
4008+ {
4009+ Oid indexOid = lfirst_oid (indexId );
40264010
4027- CommandCounterIncrement ();
4011+ reindex_index (indexOid , !(flags & REINDEX_REL_CHECK_CONSTRAINTS ),
4012+ persistence ,options );
40284013
4029- /* Index should no longer be in the pending list */
4030- Assert (!ReindexIsProcessingIndex (indexOid ));
4031- }
4032- }
4033- PG_CATCH ();
4034- {
4035- /* Make sure list gets cleared on error exit */
4036- ResetReindexPending ();
4037- PG_RE_THROW ();
4014+ CommandCounterIncrement ();
4015+
4016+ /* Index should no longer be in the pending list */
4017+ Assert (!ReindexIsProcessingIndex (indexOid ));
40384018}
4039- PG_END_TRY ();
4040- ResetReindexPending ();
40414019
40424020/*
40434021 * Close rel, but continue to hold the lock.
@@ -4071,6 +4049,7 @@ reindex_relation(Oid relid, int flags, int options)
40714049static Oid currentlyReindexedHeap = InvalidOid ;
40724050static Oid currentlyReindexedIndex = InvalidOid ;
40734051static List * pendingReindexedIndexes = NIL ;
4052+ static int reindexingNestLevel = 0 ;
40744053
40754054/*
40764055 * ReindexIsProcessingHeap
@@ -4107,8 +4086,6 @@ ReindexIsProcessingIndex(Oid indexOid)
41074086/*
41084087 * SetReindexProcessing
41094088 *Set flag that specified heap/index are being reindexed.
4110- *
4111- * NB: caller must use a PG_TRY block to ensure ResetReindexProcessing is done.
41124089 */
41134090static void
41144091SetReindexProcessing (Oid heapOid ,Oid indexOid )
@@ -4121,6 +4098,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
41214098currentlyReindexedIndex = indexOid ;
41224099/* Index is no longer "pending" reindex. */
41234100RemoveReindexPending (indexOid );
4101+ /* This may have been set already, but in case it isn't, do so now. */
4102+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
41244103}
41254104
41264105/*
@@ -4130,17 +4109,16 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
41304109static void
41314110ResetReindexProcessing (void )
41324111{
4133- /* This may be called in leader error path */
41344112currentlyReindexedHeap = InvalidOid ;
41354113currentlyReindexedIndex = InvalidOid ;
4114+ /* reindexingNestLevel remains set till end of (sub)transaction */
41364115}
41374116
41384117/*
41394118 * SetReindexPending
41404119 *Mark the given indexes as pending reindex.
41414120 *
4142- * NB: caller must use a PG_TRY block to ensure ResetReindexPending is done.
4143- * Also, we assume that the current memory context stays valid throughout.
4121+ * NB: we assume that the current memory context stays valid throughout.
41444122 */
41454123static void
41464124SetReindexPending (List * indexes )
@@ -4151,6 +4129,7 @@ SetReindexPending(List *indexes)
41514129if (IsInParallelMode ())
41524130elog (ERROR ,"cannot modify reindex state during a parallel operation" );
41534131pendingReindexedIndexes = list_copy (indexes );
4132+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
41544133}
41554134
41564135/*
@@ -4167,14 +4146,32 @@ RemoveReindexPending(Oid indexOid)
41674146}
41684147
41694148/*
4170- *ResetReindexPending
4171- *Unset reindex-pending status .
4149+ *ResetReindexState
4150+ *Clear all reindexing state during (sub)transaction abort .
41724151 */
4173- static void
4174- ResetReindexPending ( void )
4152+ void
4153+ ResetReindexState ( int nestLevel )
41754154{
4176- /* This may be called in leader error path */
4177- pendingReindexedIndexes = NIL ;
4155+ /*
4156+ * Because reindexing is not re-entrant, we don't need to cope with nested
4157+ * reindexing states. We just need to avoid messing up the outer-level
4158+ * state in case a subtransaction fails within a REINDEX. So checking the
4159+ * current nest level against that of the reindex operation is sufficient.
4160+ */
4161+ if (reindexingNestLevel >=nestLevel )
4162+ {
4163+ currentlyReindexedHeap = InvalidOid ;
4164+ currentlyReindexedIndex = InvalidOid ;
4165+
4166+ /*
4167+ * We needn't try to release the contents of pendingReindexedIndexes;
4168+ * that list should be in a transaction-lifespan context, so it will
4169+ * go away automatically.
4170+ */
4171+ pendingReindexedIndexes = NIL ;
4172+
4173+ reindexingNestLevel = 0 ;
4174+ }
41784175}
41794176
41804177/*
@@ -4227,4 +4224,7 @@ RestoreReindexState(void *reindexstate)
42274224lappend_oid (pendingReindexedIndexes ,
42284225sistate -> pendingReindexedIndexes [c ]);
42294226MemoryContextSwitchTo (oldcontext );
4227+
4228+ /* Note the worker has its own transaction nesting level */
4229+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
42304230}