diff options
-rw-r--r-- | src/backend/access/transam/xact.c | 7 | ||||
-rw-r--r-- | src/backend/catalog/index.c | 144 | ||||
-rw-r--r-- | src/include/catalog/index.h | 4 |
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); |