summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xact.c13
-rw-r--r--src/backend/utils/cache/relcache.c54
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
{