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">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<title>Functions and Operators</title>
|
||||||
@ -10577,15 +10577,205 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
<para>
|
<para>
|
||||||
<function>pg_stat_file</> returns a record containing the file
|
<function>pg_stat_file</> returns a record containing the file
|
||||||
size, last accessed time stamp, last modified time stamp,
|
size, last accessed time stamp, last modified time stamp,
|
||||||
last file status change time stamp (Unix platforms only),
|
last file status change time stamp (Unix platforms only),
|
||||||
file creation timestamp (Windows only), and a <type>boolean</type> indicating
|
file creation timestamp (Windows only), and a <type>boolean</type>
|
||||||
if it is a directory. Typical usages include:
|
indicating if it is a directory. Typical usages include:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT * FROM pg_stat_file('filename');
|
SELECT * FROM pg_stat_file('filename');
|
||||||
SELECT (pg_stat_file('filename')).modification;
|
SELECT (pg_stat_file('filename')).modification;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</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>
|
</sect1>
|
||||||
</chapter>
|
</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">
|
<chapter id="mvcc">
|
||||||
<title>Concurrency Control</title>
|
<title>Concurrency Control</title>
|
||||||
@ -25,10 +25,10 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Unlike traditional database systems which use locks for concurrency control,
|
<productname>PostgreSQL</productname> provides a rich set of tools
|
||||||
<productname>PostgreSQL</productname>
|
for developers to manage concurrent access to data. Internally,
|
||||||
maintains data consistency by using a multiversion model
|
data consistency is maintained by using a multiversion
|
||||||
(Multiversion Concurrency Control, <acronym>MVCC</acronym>).
|
model (Multiversion Concurrency Control, <acronym>MVCC</acronym>).
|
||||||
This means that while querying a database each transaction sees
|
This means that while querying a database each transaction sees
|
||||||
a snapshot of data (a <firstterm>database version</firstterm>)
|
a snapshot of data (a <firstterm>database version</firstterm>)
|
||||||
as it was some
|
as it was some
|
||||||
@ -36,7 +36,10 @@
|
|||||||
This protects the transaction from viewing inconsistent data that
|
This protects the transaction from viewing inconsistent data that
|
||||||
could be caused by (other) concurrent transaction updates on the same
|
could be caused by (other) concurrent transaction updates on the same
|
||||||
data rows, providing <firstterm>transaction isolation</firstterm>
|
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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -52,7 +55,9 @@
|
|||||||
<productname>PostgreSQL</productname> for applications that cannot
|
<productname>PostgreSQL</productname> for applications that cannot
|
||||||
adapt easily to <acronym>MVCC</acronym> behavior. However, proper
|
adapt easily to <acronym>MVCC</acronym> behavior. However, proper
|
||||||
use of <acronym>MVCC</acronym> will generally provide better
|
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>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
@ -859,6 +864,83 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
|
|||||||
(e.g., while waiting for user input).
|
(e.g., while waiting for user input).
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</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>
|
||||||
|
|
||||||
<sect1 id="applevel-consistency">
|
<sect1 id="applevel-consistency">
|
||||||
@ -993,12 +1075,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
|
|||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Short-term share/exclusive page-level locks are used for
|
Short-term share/exclusive page-level locks are used for
|
||||||
read/write access. Locks are released immediately after each
|
read/write access. Locks are released immediately after each
|
||||||
index row is fetched or inserted. But note that a GIN-indexed
|
index row is fetched or inserted. But note that a GIN-indexed
|
||||||
value insertion usually produces several index key insertions
|
value insertion usually produces several index key insertions
|
||||||
per row, so GIN may do substantial work for a single value's
|
per row, so GIN may do substantial work for a single value's
|
||||||
insertion.
|
insertion.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user