Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1c0e678

Browse files
committed
Overdue code review for transaction-level advisory locks patch.
Commit62c7bd3 had assorted problems, mostvisibly that it broke PREPARE TRANSACTION in the presence of session-leveladvisory locks (which should be ignored by PREPARE), as per a recentcomplaint from Stephen Rees. More abstractly, the patch made theLockMethodData.transactional flag not merely useless but outrightdangerous, because in point of fact that flag no longer tells you anythingat all about whether a lock is held transactionally. This fix thereforeremoves that flag altogether. We now rely entirely on the conventionalready in use in lock.c that transactional lock holds must be owned bysome ResourceOwner, while session holds are never so owned. Setting thelocallock struct's owner link to NULL thus denotes a session hold, andthere is no redundant marker for that.PREPARE TRANSACTION now works again when there are session-level advisorylocks, and it is also able to transfer transactional advisory locks to theprepared transaction, but for implementation reasons it throws an error ifwe hold both types of lock on a single lockable object. Perhaps it will beworth improving that someday.Assorted other minor cleanup and documentation editing, as well.Back-patch to 9.1, except that in the 9.1 branch I did not remove theLockMethodData.transactional flag for fear of causing an ABI break forany external code that might be examining those structs.
1 parent6d362ec commit1c0e678

File tree

6 files changed

+217
-154
lines changed

6 files changed

+217
-154
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14767,7 +14767,7 @@ SELECT (pg_stat_file('filename')).modification;
1476714767
<literal><function>pg_advisory_xact_lock_shared(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</function></literal>
1476814768
</entry>
1476914769
<entry><type>void</type></entry>
14770-
<entry>Obtain sharedadvisory lock for the current transaction</entry>
14770+
<entry>Obtain sharedtransaction level advisory lock</entry>
1477114771
</row>
1477214772
<row>
1477314773
<entry>
@@ -14836,11 +14836,10 @@ SELECT (pg_stat_file('filename')).modification;
1483614836
<function>pg_advisory_lock</> locks an application-defined resource,
1483714837
which can be identified either by a single 64-bit key value or two
1483814838
32-bit key values (note that these two key spaces do not overlap).
14839-
The key type is specified in <literal>pg_locks.objid</>. If
14840-
another session already holds a lock on the same resource, the
14841-
function will wait until the resource becomes available. The lock
14839+
If another session already holds a lock on the same resource identifier,
14840+
this function will wait until the resource becomes available. The lock
1484214841
is exclusive. Multiple lock requests stack, so that if the same resource
14843-
is locked three times it mustbe also unlocked three times to be
14842+
is locked three times it mustthen be unlocked three times to be
1484414843
released for other sessions' use.
1484514844
</para>
1484614845

@@ -14874,6 +14873,35 @@ SELECT (pg_stat_file('filename')).modification;
1487414873
a shared rather than an exclusive lock.
1487514874
</para>
1487614875

14876+
<indexterm>
14877+
<primary>pg_advisory_unlock</primary>
14878+
</indexterm>
14879+
<para>
14880+
<function>pg_advisory_unlock</> will release a previously-acquired
14881+
exclusive session level advisory lock. It
14882+
returns <literal>true</> if the lock is successfully released.
14883+
If the lock was not held, it will return <literal>false</>,
14884+
and in addition, an SQL warning will be reported by the server.
14885+
</para>
14886+
14887+
<indexterm>
14888+
<primary>pg_advisory_unlock_shared</primary>
14889+
</indexterm>
14890+
<para>
14891+
<function>pg_advisory_unlock_shared</> works the same as
14892+
<function>pg_advisory_unlock</>,
14893+
except it releases a shared session level advisory lock.
14894+
</para>
14895+
14896+
<indexterm>
14897+
<primary>pg_advisory_unlock_all</primary>
14898+
</indexterm>
14899+
<para>
14900+
<function>pg_advisory_unlock_all</> will release all session level advisory
14901+
locks held by the current session. (This function is implicitly invoked
14902+
at session end, even if the client disconnects ungracefully.)
14903+
</para>
14904+
1487714905
<indexterm>
1487814906
<primary>pg_advisory_xact_lock</primary>
1487914907
</indexterm>
@@ -14912,35 +14940,6 @@ SELECT (pg_stat_file('filename')).modification;
1491214940
cannot be released explicitly.
1491314941
</para>
1491414942

14915-
<indexterm>
14916-
<primary>pg_advisory_unlock</primary>
14917-
</indexterm>
14918-
<para>
14919-
<function>pg_advisory_unlock</> will release a previously-acquired
14920-
exclusive session level advisory lock. It
14921-
returns <literal>true</> if the lock is successfully released.
14922-
If the lock was not held, it will return <literal>false</>,
14923-
and in addition, an SQL warning will be raised by the server.
14924-
</para>
14925-
14926-
<indexterm>
14927-
<primary>pg_advisory_unlock_shared</primary>
14928-
</indexterm>
14929-
<para>
14930-
<function>pg_advisory_unlock_shared</> works the same as
14931-
<function>pg_advisory_unlock</>,
14932-
except it releases a shared session level advisory lock.
14933-
</para>
14934-
14935-
<indexterm>
14936-
<primary>pg_advisory_unlock_all</primary>
14937-
</indexterm>
14938-
<para>
14939-
<function>pg_advisory_unlock_all</> will release all session level advisory
14940-
locks held by the current session. (This function is implicitly invoked
14941-
at session end, even if the client disconnects ungracefully.)
14942-
</para>
14943-
1494414943
</sect1>
1494514944

1494614945
<sect1 id="functions-trigger">

‎doc/src/sgml/mvcc.sgml

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,10 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
12071207
<sect2 id="advisory-locks">
12081208
<title>Advisory Locks</title>
12091209

1210+
<indexterm zone="advisory-locks">
1211+
<primary>advisory lock</primary>
1212+
</indexterm>
1213+
12101214
<indexterm zone="advisory-locks">
12111215
<primary>lock</primary>
12121216
<secondary>advisory</secondary>
@@ -1218,35 +1222,51 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
12181222
called <firstterm>advisory locks</>, because the system does not
12191223
enforce their use &mdash; it is up to the application to use them
12201224
correctly. Advisory locks can be useful for locking strategies
1221-
that are an awkward fit for the MVCC model.</para>
1225+
that are an awkward fit for the MVCC model.
1226+
For example, a common use of advisory locks is to emulate pessimistic
1227+
locking strategies typical of so called <quote>flat file</> data
1228+
management systems.
1229+
While a flag stored in a table could be used for the same purpose,
1230+
advisory locks are faster, avoid table bloat, and are automatically
1231+
cleaned up by the server at the end of the session.
1232+
</para>
12221233

12231234
<para>
1224-
There are two different types of advisory locks in
1225-
<productname>PostgreSQL</productname>: session level and transaction level.
1226-
Once acquired, a session level advisory lock is held until explicitly
1227-
released or the session ends. Unlike standard locks, session level
1228-
advisory locks do not honor transaction semantics: a lock acquired during
1229-
a transaction that is later rolled back will still be held following the
1230-
rollback, and likewise an unlock is effective even if the calling
1231-
transaction fails later. The same session level lock can be acquired
1232-
multiple times by its owning process: for each lock request there must be
1233-
a corresponding unlock request before the lock is actually released. (If a
1234-
session already holds a given lock, additional requests will always succeed,
1235-
even if other sessions are awaiting the lock.) Transaction level locks on
1236-
the other hand behave more like regular locks; they are automatically
1237-
released at the end of the transaction, and can not be explicitly unlocked.
1238-
Session and transaction level locks share the same lock space, which means
1239-
that a transaction level lock will prevent another session from obtaining
1240-
a session level lock on that same resource and vice versa.
1241-
Like all locks in <productname>PostgreSQL</productname>, a complete list of
1242-
advisory locks currently held by any session can be found in the
1243-
<link linkend="view-pg-locks"><structname>pg_locks</structname></link>
1244-
system view.
1235+
There are two ways to acquire an advisory lock in
1236+
<productname>PostgreSQL</productname>: at session level or at
1237+
transaction level.
1238+
Once acquired at session level, an advisory lock is held until
1239+
explicitly released or the session ends. Unlike standard lock requests,
1240+
session-level advisory lock requests do not honor transaction semantics:
1241+
a lock acquired during a transaction that is later rolled back will still
1242+
be held following the rollback, and likewise an unlock is effective even
1243+
if the calling transaction fails later. A lock can be acquired multiple
1244+
times by its owning process; for each completed lock request there must
1245+
be a corresponding unlock request before the lock is actually released.
1246+
Transaction-level lock requests, on the other hand, behave more like
1247+
regular lock requests: they are automatically released at the end of the
1248+
transaction, and there is no explicit unlock operation. This behavior
1249+
is often more convenient than the session-level behavior for short-term
1250+
usage of an advisory lock.
1251+
Session-level and transaction-level lock requests for the same advisory
1252+
lock identifier will block each other in the expected way.
1253+
If a session already holds a given advisory lock, additional requests by
1254+
it will always succeed, even if other sessions are awaiting the lock; this
1255+
statement is true regardless of whether the existing lock hold and new
1256+
request are at session level or transaction level.
12451257
</para>
12461258

12471259
<para>
1248-
Advisory locks are allocated out of a shared memory pool whose size
1249-
is defined by the configuration variables
1260+
Like all locks in
1261+
<productname>PostgreSQL</productname>, a complete list of advisory locks
1262+
currently held by any session can be found in the <link
1263+
linkend="view-pg-locks"><structname>pg_locks</structname></link> system
1264+
view.
1265+
</para>
1266+
1267+
<para>
1268+
Both advisory locks and regular locks are stored in a shared memory
1269+
pool whose size is defined by the configuration variables
12501270
<xref linkend="guc-max-locks-per-transaction"> and
12511271
<xref linkend="guc-max-connections">.
12521272
Care must be taken not to exhaust this
@@ -1257,13 +1277,7 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
12571277
</para>
12581278

12591279
<para>
1260-
A common use of advisory locks is to emulate pessimistic locking
1261-
strategies typical of so called <quote>flat file</> data management
1262-
systems.
1263-
While a flag stored in a table could be used for the same purpose,
1264-
advisory locks are faster, avoid MVCC bloat, and can be automatically
1265-
cleaned up by the server at the end of the session.
1266-
In certain cases using this advisory locking method, especially in queries
1280+
In certain cases using advisory locking methods, especially in queries
12671281
involving explicit ordering and <literal>LIMIT</> clauses, care must be
12681282
taken to control the locks acquired because of the order in which SQL
12691283
expressions are evaluated. For example:

‎src/backend/storage/lmgr/README

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,8 @@ The caller can then send a cancellation signal. This implements the
501501
principle that autovacuum has a low locking priority (eg it must not block
502502
DDL on the table).
503503

504-
User Locks
505-
----------
504+
User Locks (Advisory Locks)
505+
---------------------------
506506

507507
User locks are handled totally on the application side as long term
508508
cooperative locks which may extend beyond the normal transaction boundaries.
@@ -516,12 +516,12 @@ level by someone.
516516
User locks and normal locks are completely orthogonal and they don't
517517
interfere with each other.
518518

519-
There are two types of user locks: session leveland transaction level.
520-
Sessionleveluser locks are not released at transaction end. They must
521-
be releasedexplicitly by the application --- but they are released
522-
automatically when a backend terminates. On the other hand, transaction
523-
leveluserlocks are released automatically at the end of the transaction
524-
as like as other normal locks.
519+
User locks can be acquired either at session levelor transaction level.
520+
A session-levellock request is notautomaticallyreleased at transaction
521+
end, but must beexplicitlyreleasedby the application. (However, any
522+
remaining locks are always released at session end.) Transaction-level
523+
userlock requests behave the same as normal lock requests, in that they
524+
are released at transaction end and do not need explicit unlocking.
525525

526526
Locking during Hot Standby
527527
--------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp