summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index a49ab465b36..b3faccbefe5 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -80,13 +80,14 @@
#include "storage/smgr.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/catcache.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/relmapper.h"
-#include "utils/resowner_private.h"
+#include "utils/resowner.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
@@ -273,6 +274,7 @@ static HTAB *OpClassCache = NULL;
/* non-export function prototypes */
+static void RelationCloseCleanup(Relation relation);
static void RelationDestroyRelation(Relation relation, bool remember_tupdesc);
static void RelationClearRelation(Relation relation, bool rebuild);
@@ -2115,6 +2117,31 @@ RelationIdGetRelation(Oid relationId)
* ----------------------------------------------------------------
*/
+/* ResourceOwner callbacks to track relcache references */
+static void ResOwnerReleaseRelation(Datum res);
+static char *ResOwnerPrintRelCache(Datum res);
+
+static const ResourceOwnerDesc relref_resowner_desc =
+{
+ .name = "relcache reference",
+ .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
+ .release_priority = RELEASE_PRIO_RELCACHE_REFS,
+ .ReleaseResource = ResOwnerReleaseRelation,
+ .DebugPrint = ResOwnerPrintRelCache
+};
+
+/* Convenience wrappers over ResourceOwnerRemember/Forget */
+static inline void
+ResourceOwnerRememberRelationRef(ResourceOwner owner, Relation rel)
+{
+ ResourceOwnerRemember(owner, PointerGetDatum(rel), &relref_resowner_desc);
+}
+static inline void
+ResourceOwnerForgetRelationRef(ResourceOwner owner, Relation rel)
+{
+ ResourceOwnerForget(owner, PointerGetDatum(rel), &relref_resowner_desc);
+}
+
/*
* RelationIncrementReferenceCount
* Increments relation reference count.
@@ -2126,7 +2153,7 @@ RelationIdGetRelation(Oid relationId)
void
RelationIncrementReferenceCount(Relation rel)
{
- ResourceOwnerEnlargeRelationRefs(CurrentResourceOwner);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
rel->rd_refcnt += 1;
if (!IsBootstrapProcessingMode())
ResourceOwnerRememberRelationRef(CurrentResourceOwner, rel);
@@ -2162,6 +2189,12 @@ RelationClose(Relation relation)
/* Note: no locking manipulations needed */
RelationDecrementReferenceCount(relation);
+ RelationCloseCleanup(relation);
+}
+
+static void
+RelationCloseCleanup(Relation relation)
+{
/*
* If the relation is no longer open in this session, we can clean up any
* stale partition descriptors it has. This is unlikely, so check to see
@@ -6813,3 +6846,30 @@ unlink_initfile(const char *initfilename, int elevel)
initfilename)));
}
}
+
+/*
+ * ResourceOwner callbacks
+ */
+static char *
+ResOwnerPrintRelCache(Datum res)
+{
+ Relation rel = (Relation) DatumGetPointer(res);
+
+ return psprintf("relation \"%s\"", RelationGetRelationName(rel));
+}
+
+static void
+ResOwnerReleaseRelation(Datum res)
+{
+ Relation rel = (Relation) DatumGetPointer(res);
+
+ /*
+ * This reference has already been removed from the resource owner, so
+ * just decrement reference count without calling
+ * ResourceOwnerForgetRelationRef.
+ */
+ Assert(rel->rd_refcnt > 0);
+ rel->rd_refcnt -= 1;
+
+ RelationCloseCleanup((Relation) res);
+}