Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0efa510

Browse files
committed
Add documentation for new in-core advisory lock functions. Merlin Moncure
1 parent e56ccad commit 0efa510

File tree

2 files changed

+290
-18
lines changed

2 files changed

+290
-18
lines changed

doc/src/sgml/func.sgml

Lines changed: 195 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.338 2006/09/16 00:30:13 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.339 2006/09/20 23:43:21 tgl Exp $ -->
22

33
<chapter id="functions">
44
<title>Functions and Operators</title>
@@ -10577,15 +10577,205 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
1057710577
</indexterm>
1057810578
<para>
1057910579
<function>pg_stat_file</> returns a record containing the file
10580-
size, last accessed time stamp, last modified time stamp,
10581-
last file status change time stamp (Unix platforms only),
10582-
file creation timestamp (Windows only), and a <type>boolean</type> indicating
10583-
if it is a directory. Typical usages include:
10580+
size, last accessed time stamp, last modified time stamp,
10581+
last file status change time stamp (Unix platforms only),
10582+
file creation timestamp (Windows only), and a <type>boolean</type>
10583+
indicating if it is a directory. Typical usages include:
1058410584
<programlisting>
1058510585
SELECT * FROM pg_stat_file('filename');
1058610586
SELECT (pg_stat_file('filename')).modification;
1058710587
</programlisting>
1058810588
</para>
1058910589

10590+
<para>
10591+
The functions shown in <xref linkend="functions-advisory-locks"> manage
10592+
advisory locks. For details about proper usage of these functions, see
10593+
<xref linkend="advisory-locks">.
10594+
</para>
10595+
10596+
<table id="functions-advisory-locks">
10597+
<title>Advisory Lock Functions</title>
10598+
<tgroup cols="3">
10599+
<thead>
10600+
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
10601+
</row>
10602+
</thead>
10603+
10604+
<tbody>
10605+
<row>
10606+
<entry>
10607+
<literal><function>pg_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
10608+
</entry>
10609+
<entry><type>void</type></entry>
10610+
<entry>Obtain exclusive advisory lock</entry>
10611+
</row>
10612+
<row>
10613+
<entry>
10614+
<literal><function>pg_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10615+
</entry>
10616+
<entry><type>void</type></entry>
10617+
<entry>Obtain exclusive advisory lock</entry>
10618+
</row>
10619+
10620+
<row>
10621+
<entry>
10622+
<literal><function>pg_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
10623+
</entry>
10624+
<entry><type>void</type></entry>
10625+
<entry>Obtain shared advisory lock</entry>
10626+
</row>
10627+
<row>
10628+
<entry>
10629+
<literal><function>pg_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10630+
</entry>
10631+
<entry><type>void</type></entry>
10632+
<entry>Obtain shared advisory lock</entry>
10633+
</row>
10634+
10635+
<row>
10636+
<entry>
10637+
<literal><function>pg_try_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
10638+
</entry>
10639+
<entry><type>boolean</type></entry>
10640+
<entry>Obtain exclusive advisory lock if available</entry>
10641+
</row>
10642+
<row>
10643+
<entry>
10644+
<literal><function>pg_try_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10645+
</entry>
10646+
<entry><type>boolean</type></entry>
10647+
<entry>Obtain exclusive advisory lock if available</entry>
10648+
</row>
10649+
10650+
<row>
10651+
<entry>
10652+
<literal><function>pg_try_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
10653+
</entry>
10654+
<entry><type>boolean</type></entry>
10655+
<entry>Obtain shared advisory lock if available</entry>
10656+
</row>
10657+
<row>
10658+
<entry>
10659+
<literal><function>pg_try_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10660+
</entry>
10661+
<entry><type>boolean</type></entry>
10662+
<entry>Obtain shared advisory lock if available</entry>
10663+
</row>
10664+
10665+
<row>
10666+
<entry>
10667+
<literal><function>pg_advisory_unlock</function>(<parameter>key</> <type>bigint</>)</literal>
10668+
</entry>
10669+
<entry><type>boolean</type></entry>
10670+
<entry>Release an exclusive advisory lock</entry>
10671+
</row>
10672+
<row>
10673+
<entry>
10674+
<literal><function>pg_advisory_unlock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10675+
</entry>
10676+
<entry><type>boolean</type></entry>
10677+
<entry>Release an exclusive advisory lock</entry>
10678+
</row>
10679+
10680+
<row>
10681+
<entry>
10682+
<literal><function>pg_advisory_unlock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
10683+
</entry>
10684+
<entry><type>boolean</type></entry>
10685+
<entry>Release a shared advisory lock</entry>
10686+
</row>
10687+
<row>
10688+
<entry>
10689+
<literal><function>pg_advisory_unlock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
10690+
</entry>
10691+
<entry><type>boolean</type></entry>
10692+
<entry>Release a shared advisory lock</entry>
10693+
</row>
10694+
10695+
<row>
10696+
<entry>
10697+
<literal><function>pg_advisory_unlock_all</function>()</literal>
10698+
</entry>
10699+
<entry><type>void</type></entry>
10700+
<entry>Release all advisory locks held by the current session</entry>
10701+
</row>
10702+
10703+
</tbody>
10704+
</tgroup>
10705+
</table>
10706+
10707+
<indexterm zone="functions-admin">
10708+
<primary>pg_advisory_lock</primary>
10709+
</indexterm>
10710+
<para>
10711+
<function>pg_advisory_lock</> locks an application-defined resource,
10712+
which may be identified either by a single 64-bit key value or two
10713+
32-bit key values (note that these two key spaces do not overlap). If
10714+
another session already holds a lock on the same resource, the
10715+
function will wait until the resource becomes available. The lock
10716+
is exclusive. Multiple lock requests stack, so that if the same resource
10717+
is locked three times it must be also unlocked three times to be
10718+
released for other sessions' use.
10719+
</para>
10720+
10721+
<indexterm zone="functions-admin">
10722+
<primary>pg_advisory_lock_shared</primary>
10723+
</indexterm>
10724+
<para>
10725+
<function>pg_advisory_lock_shared</> works the same as
10726+
<function>pg_advisory_lock</>,
10727+
except the lock can be shared with other sessions requesting shared locks.
10728+
Only would-be exclusive lockers are locked out.
10729+
</para>
10730+
10731+
<indexterm zone="functions-admin">
10732+
<primary>pg_try_advisory_lock</primary>
10733+
</indexterm>
10734+
<para>
10735+
<function>pg_try_advisory_lock</> is similar to
10736+
<function>pg_advisory_lock</>, except the function will not wait for the
10737+
lock to become available. It will either obtain the lock immediately and
10738+
return <literal>true</>, or return <literal>false</> if the lock cannot be
10739+
acquired now.
10740+
</para>
10741+
10742+
<indexterm zone="functions-admin">
10743+
<primary>pg_try_advisory_lock_shared</primary>
10744+
</indexterm>
10745+
<para>
10746+
<function>pg_try_advisory_lock_shared</> works the same as
10747+
<function>pg_try_advisory_lock</>, except it attempts to acquire
10748+
shared rather than exclusive lock.
10749+
</para>
10750+
10751+
<indexterm zone="functions-admin">
10752+
<primary>pg_advisory_unlock</primary>
10753+
</indexterm>
10754+
<para>
10755+
<function>pg_advisory_unlock</> will release a previously-acquired
10756+
exclusive advisory lock. It
10757+
will return <literal>true</> if the lock is successfully released.
10758+
If the lock was in fact not held, it will return <literal>false</>,
10759+
and in addition, an SQL warning will be raised by the server.
10760+
</para>
10761+
10762+
<indexterm zone="functions-admin">
10763+
<primary>pg_advisory_unlock_shared</primary>
10764+
</indexterm>
10765+
<para>
10766+
<function>pg_advisory_unlock_shared</> works the same as
10767+
<function>pg_advisory_unlock</>,
10768+
except to release a shared advisory lock.
10769+
</para>
10770+
10771+
<indexterm zone="functions-admin">
10772+
<primary>pg_advisory_unlock_all</primary>
10773+
</indexterm>
10774+
<para>
10775+
<function>pg_advisory_unlock_all</> will release all advisory locks
10776+
held by the current session. (This function is implicitly invoked
10777+
at session end, even if the client disconnects ungracefully.)
10778+
</para>
10779+
1059010780
</sect1>
1059110781
</chapter>

doc/src/sgml/mvcc.sgml

Lines changed: 95 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.62 2006/09/18 12:11:36 teodor Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.63 2006/09/20 23:43:22 tgl Exp $ -->
22

33
<chapter id="mvcc">
44
<title>Concurrency Control</title>
@@ -25,18 +25,21 @@
2525
</indexterm>
2626

2727
<para>
28-
Unlike traditional database systems which use locks for concurrency control,
29-
<productname>PostgreSQL</productname>
30-
maintains data consistency by using a multiversion model
31-
(Multiversion Concurrency Control, <acronym>MVCC</acronym>).
28+
<productname>PostgreSQL</productname> provides a rich set of tools
29+
for developers to manage concurrent access to data. Internally,
30+
data consistency is maintained by using a multiversion
31+
model (Multiversion Concurrency Control, <acronym>MVCC</acronym>).
3232
This means that while querying a database each transaction sees
3333
a snapshot of data (a <firstterm>database version</firstterm>)
3434
as it was some
3535
time ago, regardless of the current state of the underlying data.
3636
This protects the transaction from viewing inconsistent data that
3737
could be caused by (other) concurrent transaction updates on the same
3838
data rows, providing <firstterm>transaction isolation</firstterm>
39-
for each database session.
39+
for each database session. <acronym>MVCC</acronym>, by eschewing
40+
explicit locking methodologies of traditional database systems,
41+
minimizes lock contention in order to allow for reasonable
42+
performance in multiuser environments.
4043
</para>
4144

4245
<para>
@@ -52,7 +55,9 @@
5255
<productname>PostgreSQL</productname> for applications that cannot
5356
adapt easily to <acronym>MVCC</acronym> behavior. However, proper
5457
use of <acronym>MVCC</acronym> will generally provide better
55-
performance than locks.
58+
performance than locks. In addition, application-defined advisory
59+
locks provide a mechanism for acquiring locks that are not tied
60+
to a single transaction.
5661
</para>
5762
</sect1>
5863

@@ -859,6 +864,83 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
859864
(e.g., while waiting for user input).
860865
</para>
861866
</sect2>
867+
868+
<sect2 id="advisory-locks">
869+
<title>Advisory Locks</title>
870+
871+
<indexterm zone="advisory-locks">
872+
<primary>lock</primary>
873+
<secondary>advisory</secondary>
874+
</indexterm>
875+
876+
<para>
877+
<productname>PostgreSQL</productname> provides a means for
878+
creating locks that have application-defined meanings. These are
879+
called <firstterm>advisory locks</>, because the system does not
880+
enforce their use &mdash; it is up to the application to use them
881+
correctly. Advisory locks can be useful for locking strategies
882+
that are an awkward fit for the MVCC model. Once acquired, an
883+
advisory lock is held until explicitly released or the session ends.
884+
Unlike standard locks, advisory locks do not
885+
honor transaction semantics. For example, a lock acquired during a
886+
transaction that is later rolled back will still be held following the
887+
rollback. The same lock can be acquired multiple times by its
888+
owning process: for each lock request there must be a corresponding
889+
unlock request before the lock is actually released. (If a session
890+
already holds a given lock, additional requests will always succeed, even
891+
if other sessions are awaiting the lock.) Like all locks in
892+
<productname>PostgreSQL</productname>, a complete list of advisory
893+
locks currently held by any session can be found in the system view
894+
<structname>pg_locks</structname>.
895+
</para>
896+
897+
<para>
898+
Advisory locks are allocated out of a shared memory pool whose size
899+
is defined by the configuration variables
900+
<xref linkend="guc-max-locks-per-transaction"> and
901+
<xref linkend="guc-max-connections">.
902+
Care must be taken not to exhaust this
903+
memory or the server will not be able to grant any locks at all.
904+
This imposes an upper limit on the number of advisory locks
905+
grantable by the server, typically in the tens to hundreds of thousands
906+
depending on how the server is configured.
907+
</para>
908+
909+
<para>
910+
A common use of advisory locks is to emulate pessimistic locking
911+
strategies typical of so called <quote>flat file</> data management
912+
systems.
913+
While a flag stored in a table could be used for the same purpose,
914+
advisory locks are faster, avoid MVCC bloat, and are automatically
915+
cleaned up by the server at the end of the session.
916+
In certain cases using this method, especially in queries
917+
involving explicit ordering and <literal>LIMIT</> clauses, care must be
918+
taken to control the locks acquired because of the order in which SQL
919+
expressions are evaluated. For example:
920+
<screen>
921+
SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
922+
SELECT pg_advisory_lock(id) FROM foo WHERE id &gt; 12345 LIMIT 100; -- danger!
923+
SELECT pg_advisory_lock(q.id) FROM
924+
(
925+
SELECT id FROM foo WHERE id &gt; 12345 LIMIT 100;
926+
) q; -- ok
927+
</screen>
928+
In the above queries, the second form is dangerous because the
929+
<literal>LIMIT</> is not guaranteed to be applied before the locking
930+
function is executed. This might cause some locks to be acquired
931+
that the application was not expecting, and hence would fail to release
932+
(until it ends the session).
933+
From the point of view of the application, such locks
934+
would be dangling, although still viewable in
935+
<structname>pg_locks</structname>.
936+
</para>
937+
938+
<para>
939+
The functions provided to manipulate advisory locks are described in
940+
<xref linkend="functions-advisory-locks">.
941+
</para>
942+
</sect2>
943+
862944
</sect1>
863945

864946
<sect1 id="applevel-consistency">
@@ -993,12 +1075,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
9931075
</term>
9941076
<listitem>
9951077
<para>
996-
Short-term share/exclusive page-level locks are used for
997-
read/write access. Locks are released immediately after each
998-
index row is fetched or inserted. But note that a GIN-indexed
999-
value insertion usually produces several index key insertions
1000-
per row, so GIN may do substantial work for a single value's
1001-
insertion.
1078+
Short-term share/exclusive page-level locks are used for
1079+
read/write access. Locks are released immediately after each
1080+
index row is fetched or inserted. But note that a GIN-indexed
1081+
value insertion usually produces several index key insertions
1082+
per row, so GIN may do substantial work for a single value's
1083+
insertion.
10021084
</para>
10031085
</listitem>
10041086
</varlistentry>

0 commit comments

Comments
 (0)