mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Add documentation for new in-core advisory lock functions. Merlin Moncure
This commit is contained in:
parent
e56ccad7b0
commit
0efa510bf7
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.338 2006/09/16 00:30:13 momjian Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.339 2006/09/20 23:43:21 tgl Exp $ -->
|
||||
|
||||
<chapter id="functions">
|
||||
<title>Functions and Operators</title>
|
||||
@ -10579,13 +10579,203 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
|
||||
<function>pg_stat_file</> returns a record containing the file
|
||||
size, last accessed time stamp, last modified time stamp,
|
||||
last file status change time stamp (Unix platforms only),
|
||||
file creation timestamp (Windows only), and a <type>boolean</type> indicating
|
||||
if it is a directory. Typical usages include:
|
||||
file creation timestamp (Windows only), and a <type>boolean</type>
|
||||
indicating if it is a directory. Typical usages include:
|
||||
<programlisting>
|
||||
SELECT * FROM pg_stat_file('filename');
|
||||
SELECT (pg_stat_file('filename')).modification;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The functions shown in <xref linkend="functions-advisory-locks"> manage
|
||||
advisory locks. For details about proper usage of these functions, see
|
||||
<xref linkend="advisory-locks">.
|
||||
</para>
|
||||
|
||||
<table id="functions-advisory-locks">
|
||||
<title>Advisory Lock Functions</title>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>void</type></entry>
|
||||
<entry>Obtain exclusive advisory lock</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>void</type></entry>
|
||||
<entry>Obtain exclusive advisory lock</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>void</type></entry>
|
||||
<entry>Obtain shared advisory lock</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>void</type></entry>
|
||||
<entry>Obtain shared advisory lock</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_try_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Obtain exclusive advisory lock if available</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_try_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Obtain exclusive advisory lock if available</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_try_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Obtain shared advisory lock if available</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_try_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Obtain shared advisory lock if available</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_unlock</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Release an exclusive advisory lock</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_unlock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Release an exclusive advisory lock</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_unlock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Release a shared advisory lock</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_unlock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>Release a shared advisory lock</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<literal><function>pg_advisory_unlock_all</function>()</literal>
|
||||
</entry>
|
||||
<entry><type>void</type></entry>
|
||||
<entry>Release all advisory locks held by the current session</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_advisory_lock</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_advisory_lock</> locks an application-defined resource,
|
||||
which may be identified either by a single 64-bit key value or two
|
||||
32-bit key values (note that these two key spaces do not overlap). If
|
||||
another session already holds a lock on the same resource, the
|
||||
function will wait until the resource becomes available. The lock
|
||||
is exclusive. Multiple lock requests stack, so that if the same resource
|
||||
is locked three times it must be also unlocked three times to be
|
||||
released for other sessions' use.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_advisory_lock_shared</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_advisory_lock_shared</> works the same as
|
||||
<function>pg_advisory_lock</>,
|
||||
except the lock can be shared with other sessions requesting shared locks.
|
||||
Only would-be exclusive lockers are locked out.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_try_advisory_lock</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_try_advisory_lock</> is similar to
|
||||
<function>pg_advisory_lock</>, except the function will not wait for the
|
||||
lock to become available. It will either obtain the lock immediately and
|
||||
return <literal>true</>, or return <literal>false</> if the lock cannot be
|
||||
acquired now.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_try_advisory_lock_shared</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_try_advisory_lock_shared</> works the same as
|
||||
<function>pg_try_advisory_lock</>, except it attempts to acquire
|
||||
shared rather than exclusive lock.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_advisory_unlock</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_advisory_unlock</> will release a previously-acquired
|
||||
exclusive advisory lock. It
|
||||
will return <literal>true</> if the lock is successfully released.
|
||||
If the lock was in fact not held, it will return <literal>false</>,
|
||||
and in addition, an SQL warning will be raised by the server.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_advisory_unlock_shared</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_advisory_unlock_shared</> works the same as
|
||||
<function>pg_advisory_unlock</>,
|
||||
except to release a shared advisory lock.
|
||||
</para>
|
||||
|
||||
<indexterm zone="functions-admin">
|
||||
<primary>pg_advisory_unlock_all</primary>
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>pg_advisory_unlock_all</> will release all advisory locks
|
||||
held by the current session. (This function is implicitly invoked
|
||||
at session end, even if the client disconnects ungracefully.)
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.62 2006/09/18 12:11:36 teodor Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.63 2006/09/20 23:43:22 tgl Exp $ -->
|
||||
|
||||
<chapter id="mvcc">
|
||||
<title>Concurrency Control</title>
|
||||
@ -25,10 +25,10 @@
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
Unlike traditional database systems which use locks for concurrency control,
|
||||
<productname>PostgreSQL</productname>
|
||||
maintains data consistency by using a multiversion model
|
||||
(Multiversion Concurrency Control, <acronym>MVCC</acronym>).
|
||||
<productname>PostgreSQL</productname> provides a rich set of tools
|
||||
for developers to manage concurrent access to data. Internally,
|
||||
data consistency is maintained by using a multiversion
|
||||
model (Multiversion Concurrency Control, <acronym>MVCC</acronym>).
|
||||
This means that while querying a database each transaction sees
|
||||
a snapshot of data (a <firstterm>database version</firstterm>)
|
||||
as it was some
|
||||
@ -36,7 +36,10 @@
|
||||
This protects the transaction from viewing inconsistent data that
|
||||
could be caused by (other) concurrent transaction updates on the same
|
||||
data rows, providing <firstterm>transaction isolation</firstterm>
|
||||
for each database session.
|
||||
for each database session. <acronym>MVCC</acronym>, by eschewing
|
||||
explicit locking methodologies of traditional database systems,
|
||||
minimizes lock contention in order to allow for reasonable
|
||||
performance in multiuser environments.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -52,7 +55,9 @@
|
||||
<productname>PostgreSQL</productname> for applications that cannot
|
||||
adapt easily to <acronym>MVCC</acronym> behavior. However, proper
|
||||
use of <acronym>MVCC</acronym> will generally provide better
|
||||
performance than locks.
|
||||
performance than locks. In addition, application-defined advisory
|
||||
locks provide a mechanism for acquiring locks that are not tied
|
||||
to a single transaction.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -859,6 +864,83 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
|
||||
(e.g., while waiting for user input).
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="advisory-locks">
|
||||
<title>Advisory Locks</title>
|
||||
|
||||
<indexterm zone="advisory-locks">
|
||||
<primary>lock</primary>
|
||||
<secondary>advisory</secondary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> provides a means for
|
||||
creating locks that have application-defined meanings. These are
|
||||
called <firstterm>advisory locks</>, because the system does not
|
||||
enforce their use — it is up to the application to use them
|
||||
correctly. Advisory locks can be useful for locking strategies
|
||||
that are an awkward fit for the MVCC model. Once acquired, an
|
||||
advisory lock is held until explicitly released or the session ends.
|
||||
Unlike standard locks, advisory locks do not
|
||||
honor transaction semantics. For example, a lock acquired during a
|
||||
transaction that is later rolled back will still be held following the
|
||||
rollback. The same lock can be acquired multiple times by its
|
||||
owning process: for each lock request there must be a corresponding
|
||||
unlock request before the lock is actually released. (If a session
|
||||
already holds a given lock, additional requests will always succeed, even
|
||||
if other sessions are awaiting the lock.) Like all locks in
|
||||
<productname>PostgreSQL</productname>, a complete list of advisory
|
||||
locks currently held by any session can be found in the system view
|
||||
<structname>pg_locks</structname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Advisory locks are allocated out of a shared memory pool whose size
|
||||
is defined by the configuration variables
|
||||
<xref linkend="guc-max-locks-per-transaction"> and
|
||||
<xref linkend="guc-max-connections">.
|
||||
Care must be taken not to exhaust this
|
||||
memory or the server will not be able to grant any locks at all.
|
||||
This imposes an upper limit on the number of advisory locks
|
||||
grantable by the server, typically in the tens to hundreds of thousands
|
||||
depending on how the server is configured.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A common use of advisory locks is to emulate pessimistic locking
|
||||
strategies typical of so called <quote>flat file</> data management
|
||||
systems.
|
||||
While a flag stored in a table could be used for the same purpose,
|
||||
advisory locks are faster, avoid MVCC bloat, and are automatically
|
||||
cleaned up by the server at the end of the session.
|
||||
In certain cases using this method, especially in queries
|
||||
involving explicit ordering and <literal>LIMIT</> clauses, care must be
|
||||
taken to control the locks acquired because of the order in which SQL
|
||||
expressions are evaluated. For example:
|
||||
<screen>
|
||||
SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
|
||||
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- danger!
|
||||
SELECT pg_advisory_lock(q.id) FROM
|
||||
(
|
||||
SELECT id FROM foo WHERE id > 12345 LIMIT 100;
|
||||
) q; -- ok
|
||||
</screen>
|
||||
In the above queries, the second form is dangerous because the
|
||||
<literal>LIMIT</> is not guaranteed to be applied before the locking
|
||||
function is executed. This might cause some locks to be acquired
|
||||
that the application was not expecting, and hence would fail to release
|
||||
(until it ends the session).
|
||||
From the point of view of the application, such locks
|
||||
would be dangling, although still viewable in
|
||||
<structname>pg_locks</structname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The functions provided to manipulate advisory locks are described in
|
||||
<xref linkend="functions-advisory-locks">.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="applevel-consistency">
|
||||
|
Loading…
x
Reference in New Issue
Block a user