diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/storage/buf_internals.h | 28 | ||||
-rw-r--r-- | src/include/storage/bufmgr.h | 4 | ||||
-rw-r--r-- | src/include/utils/catcache.h | 3 | ||||
-rw-r--r-- | src/include/utils/plancache.h | 2 | ||||
-rw-r--r-- | src/include/utils/resowner.h | 94 |
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 */ |