diff options
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 64 |
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); +} |