diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/transam/xact.c | 13 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 54 |
2 files changed, 47 insertions, 20 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 4f4ce757623..9bda1aa6bc6 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5279,20 +5279,7 @@ AbortSubTransaction(void) AtEOSubXact_RelationCache(false, s->subTransactionId, s->parent->subTransactionId); - - - /* - * AtEOSubXact_Inval sometimes needs to temporarily bump the refcount - * on the relcache entries that it processes. We cannot use the - * subtransaction's resource owner anymore, because we've already - * started releasing it. But we can use the parent resource owner. - */ - CurrentResourceOwner = s->parent->curTransactionOwner; - AtEOSubXact_Inval(false); - - CurrentResourceOwner = s->curTransactionOwner; - ResourceOwnerRelease(s->curTransactionOwner, RESOURCE_RELEASE_LOCKS, false, false); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index cc9b0c6524f..35dbb87ae3d 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -275,6 +275,7 @@ static HTAB *OpClassCache = NULL; static void RelationCloseCleanup(Relation relation); static void RelationDestroyRelation(Relation relation, bool remember_tupdesc); +static void RelationInvalidateRelation(Relation relation); static void RelationClearRelation(Relation relation, bool rebuild); static void RelationReloadIndexInfo(Relation relation); @@ -2513,6 +2514,31 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) } /* + * RelationInvalidateRelation - mark a relation cache entry as invalid + * + * An entry that's marked as invalid will be reloaded on next access. + */ +static void +RelationInvalidateRelation(Relation relation) +{ + /* + * Make sure smgr and lower levels close the relation's files, if they + * weren't closed already. If the relation is not getting deleted, the + * next smgr access should reopen the files automatically. This ensures + * that the low-level file access state is updated after, say, a vacuum + * truncation. + */ + RelationCloseSmgr(relation); + + /* Free AM cached data, if any */ + if (relation->rd_amcache) + pfree(relation->rd_amcache); + relation->rd_amcache = NULL; + + relation->rd_isvalid = false; +} + +/* * RelationClearRelation * * Physically blow away a relation cache entry, or reset it and rebuild @@ -2846,14 +2872,28 @@ RelationFlushRelation(Relation relation) * New relcache entries are always rebuilt, not flushed; else we'd * forget the "new" status of the relation. Ditto for the * new-relfilenumber status. - * - * The rel could have zero refcnt here, so temporarily increment the - * refcnt to ensure it's safe to rebuild it. We can assume that the - * current transaction has some lock on the rel already. */ - RelationIncrementReferenceCount(relation); - RelationClearRelation(relation, true); - RelationDecrementReferenceCount(relation); + if (IsTransactionState() && relation->rd_droppedSubid == InvalidSubTransactionId) + { + /* + * The rel could have zero refcnt here, so temporarily increment + * the refcnt to ensure it's safe to rebuild it. We can assume + * that the current transaction has some lock on the rel already. + */ + RelationIncrementReferenceCount(relation); + RelationClearRelation(relation, true); + RelationDecrementReferenceCount(relation); + } + else + { + /* + * During abort processing, the current resource owner is not + * valid and we cannot hold a refcnt. Without a valid + * transaction, RelationClearRelation() would just mark the rel as + * invalid anyway, so we can do the same directly. + */ + RelationInvalidateRelation(relation); + } } else { |