83 lines
3.8 KiB
Plaintext
83 lines
3.8 KiB
Plaintext
src/backend/utils/resowner/README
|
|
|
|
Notes About Resource Owners
|
|
===========================
|
|
|
|
ResourceOwner objects are a concept invented to simplify management of
|
|
query-related resources, such as buffer pins and table locks. These
|
|
resources need to be tracked in a reliable way to ensure that they will
|
|
be released at query end, even if the query fails due to an error.
|
|
Rather than expecting the entire executor to have bulletproof data
|
|
structures, we localize the tracking of such resources into a single
|
|
module.
|
|
|
|
The design of the ResourceOwner API is modeled on our MemoryContext API,
|
|
which has proven very flexible and successful in preventing memory leaks.
|
|
In particular we allow ResourceOwners to have child ResourceOwner objects
|
|
so that there can be forests of the things; releasing a parent
|
|
ResourceOwner acts on all its direct and indirect children as well.
|
|
|
|
(It is tempting to consider unifying ResourceOwners and MemoryContexts
|
|
into a single object type, but their usage patterns are sufficiently
|
|
different that this is probably not really a helpful thing to do.)
|
|
|
|
We create a ResourceOwner for each transaction or subtransaction as
|
|
well as one for each Portal. During execution of a Portal, the global
|
|
variable CurrentResourceOwner points to the Portal's ResourceOwner.
|
|
This causes operations such as ReadBuffer and LockAcquire to record
|
|
ownership of the acquired resources in that ResourceOwner object.
|
|
|
|
When a Portal is closed, any remaining resources (typically only locks)
|
|
become the responsibility of the current transaction. This is represented
|
|
by making the Portal's ResourceOwner a child of the current transaction's
|
|
ResourceOwner. resowner.c automatically transfers the resources to the
|
|
parent object when releasing the child. Similarly, subtransaction
|
|
ResourceOwners are children of their immediate parent.
|
|
|
|
We need transaction-related ResourceOwners as well as Portal-related ones
|
|
because transactions may initiate operations that require resources (such
|
|
as query parsing) when no associated Portal exists yet.
|
|
|
|
|
|
API Overview
|
|
------------
|
|
|
|
The basic operations on a ResourceOwner are:
|
|
|
|
* create a ResourceOwner
|
|
|
|
* associate or deassociate some resource with a ResourceOwner
|
|
|
|
* release a ResourceOwner's assets (free all owned resources, but not the
|
|
owner object itself)
|
|
|
|
* delete a ResourceOwner (including child owner objects); all resources
|
|
must have been released beforehand
|
|
|
|
Locks are handled specially because in non-error situations a lock should
|
|
be held until end of transaction, even if it was originally taken by a
|
|
subtransaction or portal. Therefore, the "release" operation on a child
|
|
ResourceOwner transfers lock ownership to the parent instead of actually
|
|
releasing the lock, if isCommit is true.
|
|
|
|
Currently, ResourceOwners contain direct support for recording ownership of
|
|
buffer pins, lmgr locks, and catcache, relcache, plancache, tupdesc, and
|
|
snapshot references. Other objects can be associated with a ResourceOwner by
|
|
recording the address of the owning ResourceOwner in such an object. There is
|
|
an API for other modules to get control during ResourceOwner release, so that
|
|
they can scan their own data structures to find the objects that need to be
|
|
deleted.
|
|
|
|
Whenever we are inside a transaction, the global variable
|
|
CurrentResourceOwner shows which resource owner should be assigned
|
|
ownership of acquired resources. Note however that CurrentResourceOwner
|
|
is NULL when not inside any transaction (or when inside a failed
|
|
transaction). In this case it is not valid to acquire query-lifespan
|
|
resources.
|
|
|
|
When unpinning a buffer or releasing a lock or cache reference,
|
|
CurrentResourceOwner must point to the same resource owner that was current
|
|
when the buffer, lock, or cache reference was acquired. It would be possible
|
|
to relax this restriction given additional bookkeeping effort, but at present
|
|
there seems no need.
|