2004-07-17 05:32:14 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* resowner.h
|
|
|
|
* POSTGRES resource owner definitions.
|
|
|
|
*
|
|
|
|
* Query-lifespan resources are tracked by associating them with
|
|
|
|
* ResourceOwner objects. This provides a simple mechanism for ensuring
|
|
|
|
* that such resources are freed at the right time.
|
|
|
|
* See utils/resowner/README for more info.
|
|
|
|
*
|
|
|
|
*
|
2021-01-02 19:06:25 +01:00
|
|
|
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
|
2004-07-17 05:32:14 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/utils/resowner.h
|
2004-07-17 05:32:14 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef RESOWNER_H
|
|
|
|
#define RESOWNER_H
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ResourceOwner objects are an opaque data structure known only within
|
|
|
|
* resowner.c.
|
|
|
|
*/
|
|
|
|
typedef struct ResourceOwnerData *ResourceOwner;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Globally known ResourceOwners
|
|
|
|
*/
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT ResourceOwner CurrentResourceOwner;
|
|
|
|
extern PGDLLIMPORT ResourceOwner CurTransactionResourceOwner;
|
|
|
|
extern PGDLLIMPORT ResourceOwner TopTransactionResourceOwner;
|
Use a ResourceOwner to track buffer pins in all cases.
Historically, we've allowed auxiliary processes to take buffer pins without
tracking them in a ResourceOwner. However, that creates problems for error
recovery. In particular, we've seen multiple reports of assertion crashes
in the startup process when it gets an error while holding a buffer pin,
as for example if it gets ENOSPC during a write. In a non-assert build,
the process would simply exit without releasing the pin at all. We've
gotten away with that so far just because a failure exit of the startup
process translates to a database crash anyhow; but any similar behavior
in other aux processes could result in stuck pins and subsequent problems
in vacuum.
To improve this, institute a policy that we must *always* have a resowner
backing any attempt to pin a buffer, which we can enforce just by removing
the previous special-case code in resowner.c. Add infrastructure to make
it easy to create a process-lifespan AuxProcessResourceOwner and clear
out its contents at appropriate times. Replace existing ad-hoc resowner
management in bgwriter.c and other aux processes with that. (Thus, while
the startup process gains a resowner where it had none at all before, some
other aux process types are replacing an ad-hoc resowner with this code.)
Also use the AuxProcessResourceOwner to manage buffer pins taken during
StartupXLOG and ShutdownXLOG, even when those are being run in a bootstrap
process or a standalone backend rather than a true auxiliary process.
In passing, remove some other ad-hoc resource owner creations that had
gotten cargo-culted into various other places. As far as I can tell
that was all unnecessary, and if it had been necessary it was incomplete,
due to lacking any provision for clearing those resowners later.
(Also worth noting in this connection is that a process that hasn't called
InitBufferPoolBackend has no business accessing buffers; so there's more
to do than just add the resowner if we want to touch buffers in processes
not covered by this patch.)
Although this fixes a very old bug, no back-patch, because there's no
evidence of any significant problem in non-assert builds.
Patch by me, pursuant to a report from Justin Pryzby. Thanks to
Robert Haas and Kyotaro Horiguchi for reviews.
Discussion: https://postgr.es/m/20180627233939.GA10276@telsasoft.com
2018-07-18 18:15:16 +02:00
|
|
|
extern PGDLLIMPORT ResourceOwner AuxProcessResourceOwner;
|
2004-07-17 05:32:14 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
RESOURCE_RELEASE_BEFORE_LOCKS,
|
|
|
|
RESOURCE_RELEASE_LOCKS,
|
|
|
|
RESOURCE_RELEASE_AFTER_LOCKS
|
|
|
|
} ResourceReleasePhase;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dynamically loaded modules can get control during ResourceOwnerRelease
|
|
|
|
* by providing a callback of this form.
|
|
|
|
*/
|
|
|
|
typedef void (*ResourceReleaseCallback) (ResourceReleasePhase phase,
|
|
|
|
bool isCommit,
|
|
|
|
bool isTopLevel,
|
|
|
|
void *arg);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Functions in resowner.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* generic routines */
|
|
|
|
extern ResourceOwner ResourceOwnerCreate(ResourceOwner parent,
|
|
|
|
const char *name);
|
|
|
|
extern void ResourceOwnerRelease(ResourceOwner owner,
|
|
|
|
ResourceReleasePhase phase,
|
|
|
|
bool isCommit,
|
|
|
|
bool isTopLevel);
|
Improve performance of "simple expressions" in PL/pgSQL.
For relatively simple expressions (say, "x + 1" or "x > 0"), plpgsql's
management overhead exceeds the cost of evaluating the expression.
This patch substantially improves that situation, providing roughly
2X speedup for such trivial expressions.
First, add infrastructure in the plancache to allow fast re-validation
of cached plans that contain no table access, and hence need no locks.
Teach plpgsql to use this infrastructure for expressions that it's
already deemed "simple" (which in particular will never contain table
references).
The fast path still requires checking that search_path hasn't changed,
so provide a fast path for OverrideSearchPathMatchesCurrent by
counting changes that have occurred to the active search path in the
current session. This is simplistic but seems enough for now, seeing
that PushOverrideSearchPath is not used in any performance-critical
cases.
Second, manage the refcounts on simple expressions' cached plans using
a transaction-lifespan resource owner, so that we only need to take
and release an expression's refcount once per transaction not once per
expression evaluation. The management of this resource owner exactly
parallels the existing management of plpgsql's simple-expression EState.
Add some regression tests covering this area, in particular verifying
that expression caching doesn't break semantics for search_path changes.
Patch by me, but it owes something to previous work by Amit Langote,
who recognized that getting rid of plancache-related overhead would
be a useful thing to do here. Also thanks to Andres Freund for review.
Discussion: https://postgr.es/m/CAFj8pRDRVfLdAxsWeVLzCAbkLFZhW549K+67tpOc-faC8uH8zw@mail.gmail.com
2020-03-26 23:58:57 +01:00
|
|
|
extern void ResourceOwnerReleaseAllPlanCacheRefs(ResourceOwner owner);
|
2004-07-17 05:32:14 +02:00
|
|
|
extern void ResourceOwnerDelete(ResourceOwner owner);
|
2004-08-27 19:07:42 +02:00
|
|
|
extern ResourceOwner ResourceOwnerGetParent(ResourceOwner owner);
|
2004-07-17 05:32:14 +02:00
|
|
|
extern void ResourceOwnerNewParent(ResourceOwner owner,
|
|
|
|
ResourceOwner newparent);
|
|
|
|
extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback,
|
|
|
|
void *arg);
|
|
|
|
extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback,
|
|
|
|
void *arg);
|
Use a ResourceOwner to track buffer pins in all cases.
Historically, we've allowed auxiliary processes to take buffer pins without
tracking them in a ResourceOwner. However, that creates problems for error
recovery. In particular, we've seen multiple reports of assertion crashes
in the startup process when it gets an error while holding a buffer pin,
as for example if it gets ENOSPC during a write. In a non-assert build,
the process would simply exit without releasing the pin at all. We've
gotten away with that so far just because a failure exit of the startup
process translates to a database crash anyhow; but any similar behavior
in other aux processes could result in stuck pins and subsequent problems
in vacuum.
To improve this, institute a policy that we must *always* have a resowner
backing any attempt to pin a buffer, which we can enforce just by removing
the previous special-case code in resowner.c. Add infrastructure to make
it easy to create a process-lifespan AuxProcessResourceOwner and clear
out its contents at appropriate times. Replace existing ad-hoc resowner
management in bgwriter.c and other aux processes with that. (Thus, while
the startup process gains a resowner where it had none at all before, some
other aux process types are replacing an ad-hoc resowner with this code.)
Also use the AuxProcessResourceOwner to manage buffer pins taken during
StartupXLOG and ShutdownXLOG, even when those are being run in a bootstrap
process or a standalone backend rather than a true auxiliary process.
In passing, remove some other ad-hoc resource owner creations that had
gotten cargo-culted into various other places. As far as I can tell
that was all unnecessary, and if it had been necessary it was incomplete,
due to lacking any provision for clearing those resowners later.
(Also worth noting in this connection is that a process that hasn't called
InitBufferPoolBackend has no business accessing buffers; so there's more
to do than just add the resowner if we want to touch buffers in processes
not covered by this patch.)
Although this fixes a very old bug, no back-patch, because there's no
evidence of any significant problem in non-assert builds.
Patch by me, pursuant to a report from Justin Pryzby. Thanks to
Robert Haas and Kyotaro Horiguchi for reviews.
Discussion: https://postgr.es/m/20180627233939.GA10276@telsasoft.com
2018-07-18 18:15:16 +02:00
|
|
|
extern void CreateAuxProcessResourceOwner(void);
|
|
|
|
extern void ReleaseAuxProcessResources(bool isCommit);
|
2004-07-17 05:32:14 +02:00
|
|
|
|
|
|
|
#endif /* RESOWNER_H */
|