@@ -130,7 +130,6 @@ static void SetReindexProcessing(Oid heapOid, Oid indexOid);
130
130
static void ResetReindexProcessing (void );
131
131
static void SetReindexPending (List * indexes );
132
132
static void RemoveReindexPending (Oid indexOid );
133
- static void ResetReindexPending (void );
134
133
135
134
136
135
/*
@@ -1532,8 +1531,8 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
1532
1531
newIndexForm -> indisclustered = oldIndexForm -> indisclustered ;
1533
1532
1534
1533
/*
1535
- * Mark the new index as valid, and the old index as invalid similarly
1536
- * to what index_set_state_flags() does.
1534
+ * Mark the new index as valid, and the old index as invalid similarly to
1535
+ * what index_set_state_flags() does.
1537
1536
*/
1538
1537
newIndexForm -> indisvalid = true;
1539
1538
oldIndexForm -> indisvalid = false;
@@ -3534,26 +3533,17 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3534
3533
indexInfo -> ii_ExclusionStrats = NULL ;
3535
3534
}
3536
3535
3537
- /* ensure SetReindexProcessing state isn't leaked */
3538
- PG_TRY ();
3539
- {
3540
- /* Suppress use of the target index while rebuilding it */
3541
- SetReindexProcessing (heapId , indexId );
3536
+ /* Suppress use of the target index while rebuilding it */
3537
+ SetReindexProcessing (heapId , indexId );
3542
3538
3543
- /* Create a new physical relation for the index */
3544
- RelationSetNewRelfilenode (iRel , persistence );
3539
+ /* Create a new physical relation for the index */
3540
+ RelationSetNewRelfilenode (iRel , persistence );
3545
3541
3546
- /* Initialize the index and rebuild */
3547
- /* Note: we do not need to re-establish pkey setting */
3548
- index_build (heapRelation , iRel , indexInfo , true, true);
3549
- }
3550
- PG_CATCH ();
3551
- {
3552
- /* Make sure flag gets cleared on error exit */
3553
- ResetReindexProcessing ();
3554
- PG_RE_THROW ();
3555
- }
3556
- PG_END_TRY ();
3542
+ /* Initialize the index and rebuild */
3543
+ /* Note: we do not need to re-establish pkey setting */
3544
+ index_build (heapRelation , iRel , indexInfo , true, true);
3545
+
3546
+ /* Re-allow use of target index */
3557
3547
ResetReindexProcessing ();
3558
3548
3559
3549
/*
@@ -3691,7 +3681,9 @@ reindex_relation(Oid relid, int flags, int options)
3691
3681
Relation rel ;
3692
3682
Oid toast_relid ;
3693
3683
List * indexIds ;
3684
+ char persistence ;
3694
3685
bool result ;
3686
+ ListCell * indexId ;
3695
3687
int i ;
3696
3688
3697
3689
/*
@@ -3726,79 +3718,65 @@ reindex_relation(Oid relid, int flags, int options)
3726
3718
*/
3727
3719
indexIds = RelationGetIndexList (rel );
3728
3720
3729
- PG_TRY ();
3721
+ if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
3730
3722
{
3731
- ListCell * indexId ;
3732
- char persistence ;
3723
+ /* Suppress use of all the indexes until they are rebuilt */
3724
+ SetReindexPending ( indexIds ) ;
3733
3725
3734
- if (flags & REINDEX_REL_SUPPRESS_INDEX_USE )
3735
- {
3736
- /* Suppress use of all the indexes until they are rebuilt */
3737
- SetReindexPending (indexIds );
3726
+ /*
3727
+ * Make the new heap contents visible --- now things might be
3728
+ * inconsistent!
3729
+ */
3730
+ CommandCounterIncrement ();
3731
+ }
3738
3732
3739
- /*
3740
- * Make the new heap contents visible --- now things might be
3741
- * inconsistent!
3742
- */
3743
- CommandCounterIncrement ();
3744
- }
3733
+ /*
3734
+ * Compute persistence of indexes: same as that of owning rel, unless
3735
+ * caller specified otherwise.
3736
+ */
3737
+ if (flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
3738
+ persistence = RELPERSISTENCE_UNLOGGED ;
3739
+ else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
3740
+ persistence = RELPERSISTENCE_PERMANENT ;
3741
+ else
3742
+ persistence = rel -> rd_rel -> relpersistence ;
3743
+
3744
+ /* Reindex all the indexes. */
3745
+ i = 1 ;
3746
+ foreach (indexId , indexIds )
3747
+ {
3748
+ Oid indexOid = lfirst_oid (indexId );
3749
+ Oid indexNamespaceId = get_rel_namespace (indexOid );
3745
3750
3746
3751
/*
3747
- * Compute persistence of indexes: same as that of owning rel, unless
3748
- * caller specified otherwise.
3752
+ * Skip any invalid indexes on a TOAST table. These can only be
3753
+ * duplicate leftovers from a failed REINDEX CONCURRENTLY, and if
3754
+ * rebuilt it would not be possible to drop them anymore.
3749
3755
*/
3750
- if (flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED )
3751
- persistence = RELPERSISTENCE_UNLOGGED ;
3752
- else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT )
3753
- persistence = RELPERSISTENCE_PERMANENT ;
3754
- else
3755
- persistence = rel -> rd_rel -> relpersistence ;
3756
-
3757
- /* Reindex all the indexes. */
3758
- i = 1 ;
3759
- foreach (indexId , indexIds )
3756
+ if (IsToastNamespace (indexNamespaceId ) &&
3757
+ !get_index_isvalid (indexOid ))
3760
3758
{
3761
- Oid indexOid = lfirst_oid (indexId );
3762
- Oid indexNamespaceId = get_rel_namespace (indexOid );
3763
-
3764
- /*
3765
- * Skip any invalid indexes on a TOAST table. These can only be
3766
- * duplicate leftovers from a failed REINDEX CONCURRENTLY, and if
3767
- * rebuilt it would not be possible to drop them anymore.
3768
- */
3769
- if (IsToastNamespace (indexNamespaceId ) &&
3770
- !get_index_isvalid (indexOid ))
3771
- {
3772
- ereport (WARNING ,
3773
- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
3774
- errmsg ("cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" ,
3775
- get_namespace_name (indexNamespaceId ),
3776
- get_rel_name (indexOid ))));
3777
- continue ;
3778
- }
3759
+ ereport (WARNING ,
3760
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
3761
+ errmsg ("cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" ,
3762
+ get_namespace_name (indexNamespaceId ),
3763
+ get_rel_name (indexOid ))));
3764
+ continue ;
3765
+ }
3779
3766
3780
- reindex_index (indexOid , !(flags & REINDEX_REL_CHECK_CONSTRAINTS ),
3781
- persistence , options );
3767
+ reindex_index (indexOid , !(flags & REINDEX_REL_CHECK_CONSTRAINTS ),
3768
+ persistence , options );
3782
3769
3783
- CommandCounterIncrement ();
3770
+ CommandCounterIncrement ();
3784
3771
3785
- /* Index should no longer be in the pending list */
3786
- Assert (!ReindexIsProcessingIndex (indexOid ));
3772
+ /* Index should no longer be in the pending list */
3773
+ Assert (!ReindexIsProcessingIndex (indexOid ));
3787
3774
3788
- /* Set index rebuild count */
3789
- pgstat_progress_update_param (PROGRESS_CLUSTER_INDEX_REBUILD_COUNT ,
3790
- i );
3791
- i ++ ;
3792
- }
3775
+ /* Set index rebuild count */
3776
+ pgstat_progress_update_param (PROGRESS_CLUSTER_INDEX_REBUILD_COUNT ,
3777
+ i );
3778
+ i ++ ;
3793
3779
}
3794
- PG_CATCH ();
3795
- {
3796
- /* Make sure list gets cleared on error exit */
3797
- ResetReindexPending ();
3798
- PG_RE_THROW ();
3799
- }
3800
- PG_END_TRY ();
3801
- ResetReindexPending ();
3802
3780
3803
3781
/*
3804
3782
* Close rel, but continue to hold the lock.
@@ -3832,6 +3810,7 @@ reindex_relation(Oid relid, int flags, int options)
3832
3810
static Oid currentlyReindexedHeap = InvalidOid ;
3833
3811
static Oid currentlyReindexedIndex = InvalidOid ;
3834
3812
static List * pendingReindexedIndexes = NIL ;
3813
+ static int reindexingNestLevel = 0 ;
3835
3814
3836
3815
/*
3837
3816
* ReindexIsProcessingHeap
@@ -3868,8 +3847,6 @@ ReindexIsProcessingIndex(Oid indexOid)
3868
3847
/*
3869
3848
* SetReindexProcessing
3870
3849
* Set flag that specified heap/index are being reindexed.
3871
- *
3872
- * NB: caller must use a PG_TRY block to ensure ResetReindexProcessing is done.
3873
3850
*/
3874
3851
static void
3875
3852
SetReindexProcessing (Oid heapOid , Oid indexOid )
@@ -3882,6 +3859,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
3882
3859
currentlyReindexedIndex = indexOid ;
3883
3860
/* Index is no longer "pending" reindex. */
3884
3861
RemoveReindexPending (indexOid );
3862
+ /* This may have been set already, but in case it isn't, do so now. */
3863
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
3885
3864
}
3886
3865
3887
3866
/*
@@ -3891,17 +3870,16 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
3891
3870
static void
3892
3871
ResetReindexProcessing (void )
3893
3872
{
3894
- /* This may be called in leader error path */
3895
3873
currentlyReindexedHeap = InvalidOid ;
3896
3874
currentlyReindexedIndex = InvalidOid ;
3875
+ /* reindexingNestLevel remains set till end of (sub)transaction */
3897
3876
}
3898
3877
3899
3878
/*
3900
3879
* SetReindexPending
3901
3880
* Mark the given indexes as pending reindex.
3902
3881
*
3903
- * NB: caller must use a PG_TRY block to ensure ResetReindexPending is done.
3904
- * Also, we assume that the current memory context stays valid throughout.
3882
+ * NB: we assume that the current memory context stays valid throughout.
3905
3883
*/
3906
3884
static void
3907
3885
SetReindexPending (List * indexes )
@@ -3912,6 +3890,7 @@ SetReindexPending(List *indexes)
3912
3890
if (IsInParallelMode ())
3913
3891
elog (ERROR , "cannot modify reindex state during a parallel operation" );
3914
3892
pendingReindexedIndexes = list_copy (indexes );
3893
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
3915
3894
}
3916
3895
3917
3896
/*
@@ -3928,14 +3907,32 @@ RemoveReindexPending(Oid indexOid)
3928
3907
}
3929
3908
3930
3909
/*
3931
- * ResetReindexPending
3932
- * Unset reindex-pending status .
3910
+ * ResetReindexState
3911
+ * Clear all reindexing state during (sub)transaction abort .
3933
3912
*/
3934
- static void
3935
- ResetReindexPending ( void )
3913
+ void
3914
+ ResetReindexState ( int nestLevel )
3936
3915
{
3937
- /* This may be called in leader error path */
3938
- pendingReindexedIndexes = NIL ;
3916
+ /*
3917
+ * Because reindexing is not re-entrant, we don't need to cope with nested
3918
+ * reindexing states. We just need to avoid messing up the outer-level
3919
+ * state in case a subtransaction fails within a REINDEX. So checking the
3920
+ * current nest level against that of the reindex operation is sufficient.
3921
+ */
3922
+ if (reindexingNestLevel >= nestLevel )
3923
+ {
3924
+ currentlyReindexedHeap = InvalidOid ;
3925
+ currentlyReindexedIndex = InvalidOid ;
3926
+
3927
+ /*
3928
+ * We needn't try to release the contents of pendingReindexedIndexes;
3929
+ * that list should be in a transaction-lifespan context, so it will
3930
+ * go away automatically.
3931
+ */
3932
+ pendingReindexedIndexes = NIL ;
3933
+
3934
+ reindexingNestLevel = 0 ;
3935
+ }
3939
3936
}
3940
3937
3941
3938
/*
@@ -3988,4 +3985,7 @@ RestoreReindexState(void *reindexstate)
3988
3985
lappend_oid (pendingReindexedIndexes ,
3989
3986
sistate -> pendingReindexedIndexes [c ]);
3990
3987
MemoryContextSwitchTo (oldcontext );
3988
+
3989
+ /* Note the worker has its own transaction nesting level */
3990
+ reindexingNestLevel = GetCurrentTransactionNestLevel ();
3991
3991
}
0 commit comments