aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xact.c7
-rw-r--r--src/backend/catalog/index.c144
-rw-r--r--src/include/catalog/index.h4
3 files changed, 82 insertions, 73 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 7c1771eae76..3c823f56821 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -30,6 +30,7 @@
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
+#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/storage.h"
#include "commands/async.h"
@@ -2576,6 +2577,9 @@ AbortTransaction(void)
*/
SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
+ /* Forget about any active REINDEX. */
+ ResetReindexState(s->nestingLevel);
+
/* If in parallel mode, clean up workers and exit parallel mode. */
if (IsInParallelMode())
{
@@ -4785,6 +4789,9 @@ AbortSubTransaction(void)
*/
SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
+ /* Forget about any active REINDEX. */
+ ResetReindexState(s->nestingLevel);
+
/* Exit from parallel mode, if necessary. */
if (IsInParallelMode())
{
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index bb7d9813273..061efd36a6a 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -144,7 +144,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);
/*
@@ -3799,27 +3798,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, InvalidTransactionId,
- InvalidMultiXactId);
+ /* Create a new physical relation for the index */
+ RelationSetNewRelfilenode(iRel, persistence, InvalidTransactionId,
+ InvalidMultiXactId);
- /* Initialize the index and rebuild */
- /* Note: we do not need to re-establish pkey setting */
- index_build(heapRelation, iRel, indexInfo, false, true, true);
- }
- PG_CATCH();
- {
- /* Make sure flag gets cleared on error exit */
- ResetReindexProcessing();
- PG_RE_THROW();
- }
- PG_END_TRY();
+ /* Initialize the index and rebuild */
+ /* Note: we do not need to re-establish pkey setting */
+ index_build(heapRelation, iRel, indexInfo, false, true, true);
+
+ /* Re-allow use of target index */
ResetReindexProcessing();
/*
@@ -3954,7 +3944,9 @@ reindex_relation(Oid relid, int flags, int options)
Relation rel;
Oid toast_relid;
List *indexIds;
+ char persistence;
bool result;
+ ListCell *indexId;
/*
* Open and lock the relation. ShareLock is sufficient since we only need
@@ -3988,56 +3980,42 @@ reindex_relation(Oid relid, int flags, int options)
*/
indexIds = RelationGetIndexList(rel);
- PG_TRY();
+ if (flags & REINDEX_REL_SUPPRESS_INDEX_USE)
{
- ListCell *indexId;
- char persistence;
-
- 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();
- }
+ /* Suppress use of all the indexes until they are rebuilt */
+ SetReindexPending(indexIds);
/*
- * Compute persistence of indexes: same as that of owning rel, unless
- * caller specified otherwise.
+ * Make the new heap contents visible --- now things might be
+ * inconsistent!
*/
- 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;
+ CommandCounterIncrement();
+ }
- /* Reindex all the indexes. */
- foreach(indexId, indexIds)
- {
- Oid indexOid = lfirst_oid(indexId);
+ /*
+ * 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_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
- persistence, options);
+ /* Reindex all the indexes. */
+ foreach(indexId, indexIds)
+ {
+ Oid indexOid = lfirst_oid(indexId);
- CommandCounterIncrement();
+ reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
+ persistence, options);
- /* Index should no longer be in the pending list */
- Assert(!ReindexIsProcessingIndex(indexOid));
- }
- }
- PG_CATCH();
- {
- /* Make sure list gets cleared on error exit */
- ResetReindexPending();
- PG_RE_THROW();
+ CommandCounterIncrement();
+
+ /* Index should no longer be in the pending list */
+ Assert(!ReindexIsProcessingIndex(indexOid));
}
- PG_END_TRY();
- ResetReindexPending();
/*
* Close rel, but continue to hold the lock.
@@ -4071,6 +4049,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
@@ -4107,8 +4086,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)
@@ -4121,6 +4098,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();
}
/*
@@ -4130,17 +4109,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)
@@ -4151,6 +4129,7 @@ SetReindexPending(List *indexes)
if (IsInParallelMode())
elog(ERROR, "cannot modify reindex state during a parallel operation");
pendingReindexedIndexes = list_copy(indexes);
+ reindexingNestLevel = GetCurrentTransactionNestLevel();
}
/*
@@ -4167,14 +4146,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;
+ }
}
/*
@@ -4227,4 +4224,7 @@ RestoreReindexState(void *reindexstate)
lappend_oid(pendingReindexedIndexes,
sistate->pendingReindexedIndexes[c]);
MemoryContextSwitchTo(oldcontext);
+
+ /* Note the worker has its own transaction nesting level */
+ reindexingNestLevel = GetCurrentTransactionNestLevel();
}
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index feaf760f51a..639f721ad7e 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -135,6 +135,8 @@ extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
+extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
+
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
char relpersistence, int options);
@@ -149,8 +151,8 @@ extern bool reindex_relation(Oid relid, int flags, int options);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern bool ReindexIsProcessingIndex(Oid indexOid);
-extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
+extern void ResetReindexState(int nestLevel);
extern Size EstimateReindexStateSpace(void);
extern void SerializeReindexState(Size maxsize, char *start_address);
extern void RestoreReindexState(void *reindexstate);