summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/storage/buf_internals.h28
-rw-r--r--src/include/storage/bufmgr.h4
-rw-r--r--src/include/utils/catcache.h3
-rw-r--r--src/include/utils/plancache.h2
-rw-r--r--src/include/utils/resowner.h94
5 files changed, 118 insertions, 13 deletions
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index bc79a329a1a..e15a86eff99 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -26,6 +26,7 @@
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/relcache.h"
+#include "utils/resowner.h"
/*
* Buffer state is a single 32-bit variable where following data is combined.
@@ -383,6 +384,32 @@ typedef struct CkptSortItem
extern PGDLLIMPORT CkptSortItem *CkptBufferIds;
+/* ResourceOwner callbacks to hold buffer I/Os and pins */
+extern const ResourceOwnerDesc buffer_io_resowner_desc;
+extern const ResourceOwnerDesc buffer_pin_resowner_desc;
+
+/* Convenience wrappers over ResourceOwnerRemember/Forget */
+static inline void
+ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
+{
+ ResourceOwnerRemember(owner, Int32GetDatum(buffer), &buffer_pin_resowner_desc);
+}
+static inline void
+ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
+{
+ ResourceOwnerForget(owner, Int32GetDatum(buffer), &buffer_pin_resowner_desc);
+}
+static inline void
+ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
+{
+ ResourceOwnerRemember(owner, Int32GetDatum(buffer), &buffer_io_resowner_desc);
+}
+static inline void
+ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
+{
+ ResourceOwnerForget(owner, Int32GetDatum(buffer), &buffer_io_resowner_desc);
+}
+
/*
* Internal buffer management routines
*/
@@ -418,6 +445,7 @@ extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
/* localbuf.c */
extern bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount);
extern void UnpinLocalBuffer(Buffer buffer);
+extern void UnpinLocalBufferNoOwner(Buffer buffer);
extern PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr,
ForkNumber forkNum,
BlockNumber blockNum);
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 2eda466d44e..41e26d3e205 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -207,7 +207,7 @@ extern Buffer ExtendBufferedRelTo(BufferManagerRelation bmr,
extern void InitBufferPoolAccess(void);
extern void AtEOXact_Buffers(bool isCommit);
-extern void PrintBufferLeakWarning(Buffer buffer);
+extern char *DebugPrintBufferRefcount(Buffer buffer);
extern void CheckPointBuffers(int flags);
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,
@@ -248,8 +248,6 @@ extern bool ConditionalLockBufferForCleanup(Buffer buffer);
extern bool IsBufferCleanupOK(Buffer buffer);
extern bool HoldingBufferPinThatDelaysRecovery(void);
-extern void AbortBufferIO(Buffer buffer);
-
extern bool BgBufferSync(struct WritebackContext *wb_context);
/* in buf_init.c */
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index af0b3418736..df405382182 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -225,7 +225,4 @@ extern void PrepareToInvalidateCacheTuple(Relation relation,
HeapTuple newtuple,
void (*function) (int, uint32, Oid));
-extern void PrintCatCacheLeakWarning(HeapTuple tuple);
-extern void PrintCatCacheListLeakWarning(CatCList *list);
-
#endif /* CATCACHE_H */
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 97e58157b7c..110e649fce8 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -188,6 +188,8 @@ typedef struct CachedExpression
extern void InitPlanCache(void);
extern void ResetPlanCache(void);
+extern void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner);
+
extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree,
const char *query_string,
CommandTag commandTag);
diff --git a/src/include/utils/resowner.h b/src/include/utils/resowner.h
index cb35e9e0904..0735480214e 100644
--- a/src/include/utils/resowner.h
+++ b/src/include/utils/resowner.h
@@ -37,19 +37,87 @@ extern PGDLLIMPORT ResourceOwner AuxProcessResourceOwner;
/*
* Resource releasing is done in three phases: pre-locks, locks, and
- * post-locks. The pre-lock phase must release any resources that are
- * visible to other backends (such as pinned buffers); this ensures that
- * when we release a lock that another backend may be waiting on, it will
- * see us as being fully out of our transaction. The post-lock phase
- * should be used for backend-internal cleanup.
+ * post-locks. The pre-lock phase must release any resources that are visible
+ * to other backends (such as pinned buffers); this ensures that when we
+ * release a lock that another backend may be waiting on, it will see us as
+ * being fully out of our transaction. The post-lock phase should be used for
+ * backend-internal cleanup.
+ *
+ * Within each phase, resources are released in priority order. Priority is
+ * just an integer specified in ResourceOwnerDesc. The priorities of built-in
+ * resource types are given below, extensions may use any priority relative to
+ * those or RELEASE_PRIO_FIRST/LAST. RELEASE_PRIO_FIRST is a fine choice if
+ * your resource doesn't depend on any other resources.
*/
typedef enum
{
- RESOURCE_RELEASE_BEFORE_LOCKS,
+ RESOURCE_RELEASE_BEFORE_LOCKS = 1,
RESOURCE_RELEASE_LOCKS,
RESOURCE_RELEASE_AFTER_LOCKS,
} ResourceReleasePhase;
+typedef uint32 ResourceReleasePriority;
+
+/* priorities of built-in BEFORE_LOCKS resources */
+#define RELEASE_PRIO_BUFFER_IOS 100
+#define RELEASE_PRIO_BUFFER_PINS 200
+#define RELEASE_PRIO_RELCACHE_REFS 300
+#define RELEASE_PRIO_DSMS 400
+#define RELEASE_PRIO_JIT_CONTEXTS 500
+#define RELEASE_PRIO_CRYPTOHASH_CONTEXTS 600
+#define RELEASE_PRIO_HMAC_CONTEXTS 700
+
+/* priorities of built-in AFTER_LOCKS resources */
+#define RELEASE_PRIO_CATCACHE_REFS 100
+#define RELEASE_PRIO_CATCACHE_LIST_REFS 200
+#define RELEASE_PRIO_PLANCACHE_REFS 300
+#define RELEASE_PRIO_TUPDESC_REFS 400
+#define RELEASE_PRIO_SNAPSHOT_REFS 500
+#define RELEASE_PRIO_FILES 600
+
+/* 0 is considered invalid */
+#define RELEASE_PRIO_FIRST 1
+#define RELEASE_PRIO_LAST UINT32_MAX
+
+/*
+ * In order to track an object, resowner.c needs a few callbacks for it.
+ * The callbacks for resources of a specific kind are encapsulated in
+ * ResourceOwnerDesc.
+ *
+ * Note that the callbacks occur post-commit or post-abort, so the callback
+ * functions can only do noncritical cleanup and must not fail.
+ */
+typedef struct ResourceOwnerDesc
+{
+ const char *name; /* name for the object kind, for debugging */
+
+ /* when are these objects released? */
+ ResourceReleasePhase release_phase;
+ ResourceReleasePriority release_priority;
+
+ /*
+ * Release resource.
+ *
+ * This is called for each resource in the resource owner, in the order
+ * specified by 'release_phase' and 'release_priority' when the whole
+ * resource owner is been released or when ResourceOwnerReleaseAllOfKind()
+ * is called. The resource is implicitly removed from the owner, the
+ * callback function doesn't need to call ResourceOwnerForget.
+ */
+ void (*ReleaseResource) (Datum res);
+
+ /*
+ * Format a string describing the resource, for debugging purposes. If a
+ * resource has not been properly released before commit, this is used to
+ * print a WARNING.
+ *
+ * This can be left to NULL, in which case a generic "[resource name]: %p"
+ * format is used.
+ */
+ char *(*DebugPrint) (Datum res);
+
+} ResourceOwnerDesc;
+
/*
* Dynamically loaded modules can get control during ResourceOwnerRelease
* by providing a callback of this form.
@@ -71,16 +139,28 @@ extern void ResourceOwnerRelease(ResourceOwner owner,
ResourceReleasePhase phase,
bool isCommit,
bool isTopLevel);
-extern void ResourceOwnerReleaseAllPlanCacheRefs(ResourceOwner owner);
extern void ResourceOwnerDelete(ResourceOwner owner);
extern ResourceOwner ResourceOwnerGetParent(ResourceOwner owner);
extern void ResourceOwnerNewParent(ResourceOwner owner,
ResourceOwner newparent);
+
+extern void ResourceOwnerEnlarge(ResourceOwner owner);
+extern void ResourceOwnerRemember(ResourceOwner owner, Datum res, const ResourceOwnerDesc *kind);
+extern void ResourceOwnerForget(ResourceOwner owner, Datum res, const ResourceOwnerDesc *kind);
+
+extern void ResourceOwnerReleaseAllOfKind(ResourceOwner owner, const ResourceOwnerDesc *kind);
+
extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback,
void *arg);
extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback,
void *arg);
+
extern void CreateAuxProcessResourceOwner(void);
extern void ReleaseAuxProcessResources(bool isCommit);
+/* special support for local lock management */
+struct LOCALLOCK;
+extern void ResourceOwnerRememberLock(ResourceOwner owner, struct LOCALLOCK *locallock);
+extern void ResourceOwnerForgetLock(ResourceOwner owner, struct LOCALLOCK *locallock);
+
#endif /* RESOWNER_H */