@@ -144,7 +144,6 @@ static void SetReindexProcessing(Oid heapOid, Oid indexOid);
144
144
static void ResetReindexProcessing (void );
145
145
static void SetReindexPending (List * indexes );
146
146
static void RemoveReindexPending (Oid indexOid );
147
- static void ResetReindexPending (void );
148
147
149
148
150
149
/*
@@ -3799,27 +3798,18 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3799
3798
indexInfo -> ii_ExclusionStrats = NULL ;
3800
3799
}
3801
3800
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 );
3807
3803
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 );
3811
3807
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 */
3823
3813
ResetReindexProcessing ();
3824
3814
3825
3815
/*
@@ -3954,7 +3944,9 @@ reindex_relation(Oid relid, int flags, int options)
3954
3944
Relation rel ;
3955
3945
Oid toast_relid ;
3956
3946
List * indexIds ;
3947
+ char persistence ;
3957
3948
bool result ;
3949
+ ListCell * indexId ;
3958
3950
3959
3951
/*
3960
3952
* Open and lock the relation. ShareLock is sufficient since we only need
@@ -3988,56 +3980,42 @@ reindex_relation(Oid relid, int flags, int options)
3988
3980
*/
3989
3981
indexIds = RelationGetIndexList (rel );
3990
3982
3991
- PG_TRY ();
3983
+ if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
3992
3984
{
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 );
4007
3987
4008
3988
/*
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!
4011
3991
*/
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
+ }
4018
3994
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 ;
4023
4005
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 );
4026
4010
4027
- CommandCounterIncrement ();
4011
+ reindex_index (indexOid , !(flags & REINDEX_REL_CHECK_CONSTRAINTS ),
4012
+ persistence , options );
4028
4013
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 ));
4038
4018
}
4039
- PG_END_TRY ();
4040
- ResetReindexPending ();
4041
4019
4042
4020
/*
4043
4021
* Close rel, but continue to hold the lock.
@@ -4071,6 +4049,7 @@ reindex_relation(Oid relid, int flags, int options)
4071
4049
static Oid currentlyReindexedHeap = InvalidOid ;
4072
4050
static Oid currentlyReindexedIndex = InvalidOid ;
4073
4051
static List * pendingReindexedIndexes = NIL ;
4052
+ static int reindexingNestLevel = 0 ;
4074
4053
4075
4054
/*
4076
4055
* ReindexIsProcessingHeap
@@ -4107,8 +4086,6 @@ ReindexIsProcessingIndex(Oid indexOid)
4107
4086
/*
4108
4087
* SetReindexProcessing
4109
4088
* Set flag that specified heap/index are being reindexed.
4110
- *
4111
- * NB: caller must use a PG_TRY block to ensure ResetReindexProcessing is done.
4112
4089
*/
4113
4090
static void
4114
4091
SetReindexProcessing (Oid heapOid , Oid indexOid )
@@ -4121,6 +4098,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
4121
4098
currentlyReindexedIndex = indexOid ;
4122
4099
/* Index is no longer "pending" reindex. */
4123
4100
RemoveReindexPending (indexOid );
4101
+ /* This may have been set already, but in case it isn't, do so now. */
4102
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
4124
4103
}
4125
4104
4126
4105
/*
@@ -4130,17 +4109,16 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
4130
4109
static void
4131
4110
ResetReindexProcessing (void )
4132
4111
{
4133
- /* This may be called in leader error path */
4134
4112
currentlyReindexedHeap = InvalidOid ;
4135
4113
currentlyReindexedIndex = InvalidOid ;
4114
+ /* reindexingNestLevel remains set till end of (sub)transaction */
4136
4115
}
4137
4116
4138
4117
/*
4139
4118
* SetReindexPending
4140
4119
* Mark the given indexes as pending reindex.
4141
4120
*
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.
4144
4122
*/
4145
4123
static void
4146
4124
SetReindexPending (List * indexes )
@@ -4151,6 +4129,7 @@ SetReindexPending(List *indexes)
4151
4129
if (IsInParallelMode ())
4152
4130
elog (ERROR , "cannot modify reindex state during a parallel operation" );
4153
4131
pendingReindexedIndexes = list_copy (indexes );
4132
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
4154
4133
}
4155
4134
4156
4135
/*
@@ -4167,14 +4146,32 @@ RemoveReindexPending(Oid indexOid)
4167
4146
}
4168
4147
4169
4148
/*
4170
- * ResetReindexPending
4171
- * Unset reindex-pending status .
4149
+ * ResetReindexState
4150
+ * Clear all reindexing state during (sub)transaction abort .
4172
4151
*/
4173
- static void
4174
- ResetReindexPending ( void )
4152
+ void
4153
+ ResetReindexState ( int nestLevel )
4175
4154
{
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
+ }
4178
4175
}
4179
4176
4180
4177
/*
@@ -4227,4 +4224,7 @@ RestoreReindexState(void *reindexstate)
4227
4224
lappend_oid (pendingReindexedIndexes ,
4228
4225
sistate -> pendingReindexedIndexes [c ]);
4229
4226
MemoryContextSwitchTo (oldcontext );
4227
+
4228
+ /* Note the worker has its own transaction nesting level */
4229
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
4230
4230
}
0 commit comments