From 0efa510bf7c762e1e3ff585d91f9ca51817e65b2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 20 Sep 2006 23:43:22 +0000 Subject: [PATCH] Add documentation for new in-core advisory lock functions. Merlin Moncure --- doc/src/sgml/func.sgml | 200 +++++++++++++++++++++++++++++++++++++++-- doc/src/sgml/mvcc.sgml | 108 +++++++++++++++++++--- 2 files changed, 290 insertions(+), 18 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 224b9005de..3c956ad8eb 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,4 +1,4 @@ - + Functions and Operators @@ -10577,15 +10577,205 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); 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 boolean indicating - if it is a directory. Typical usages include: + 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 boolean + indicating if it is a directory. Typical usages include: SELECT * FROM pg_stat_file('filename'); SELECT (pg_stat_file('filename')).modification; + + The functions shown in manage + advisory locks. For details about proper usage of these functions, see + . + + + + Advisory Lock Functions + + + Name Return Type Description + + + + + + + pg_advisory_lock(key bigint) + + void + Obtain exclusive advisory lock + + + + pg_advisory_lock(key1 int, key2 int) + + void + Obtain exclusive advisory lock + + + + + pg_advisory_lock_shared(key bigint) + + void + Obtain shared advisory lock + + + + pg_advisory_lock_shared(key1 int, key2 int) + + void + Obtain shared advisory lock + + + + + pg_try_advisory_lock(key bigint) + + boolean + Obtain exclusive advisory lock if available + + + + pg_try_advisory_lock(key1 int, key2 int) + + boolean + Obtain exclusive advisory lock if available + + + + + pg_try_advisory_lock_shared(key bigint) + + boolean + Obtain shared advisory lock if available + + + + pg_try_advisory_lock_shared(key1 int, key2 int) + + boolean + Obtain shared advisory lock if available + + + + + pg_advisory_unlock(key bigint) + + boolean + Release an exclusive advisory lock + + + + pg_advisory_unlock(key1 int, key2 int) + + boolean + Release an exclusive advisory lock + + + + + pg_advisory_unlock_shared(key bigint) + + boolean + Release a shared advisory lock + + + + pg_advisory_unlock_shared(key1 int, key2 int) + + boolean + Release a shared advisory lock + + + + + pg_advisory_unlock_all() + + void + Release all advisory locks held by the current session + + + + +
+ + + pg_advisory_lock + + + 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. + + + + pg_advisory_lock_shared + + + pg_advisory_lock_shared works the same as + pg_advisory_lock, + except the lock can be shared with other sessions requesting shared locks. + Only would-be exclusive lockers are locked out. + + + + pg_try_advisory_lock + + + pg_try_advisory_lock is similar to + pg_advisory_lock, except the function will not wait for the + lock to become available. It will either obtain the lock immediately and + return true, or return false if the lock cannot be + acquired now. + + + + pg_try_advisory_lock_shared + + + pg_try_advisory_lock_shared works the same as + pg_try_advisory_lock, except it attempts to acquire + shared rather than exclusive lock. + + + + pg_advisory_unlock + + + pg_advisory_unlock will release a previously-acquired + exclusive advisory lock. It + will return true if the lock is successfully released. + If the lock was in fact not held, it will return false, + and in addition, an SQL warning will be raised by the server. + + + + pg_advisory_unlock_shared + + + pg_advisory_unlock_shared works the same as + pg_advisory_unlock, + except to release a shared advisory lock. + + + + pg_advisory_unlock_all + + + 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.) + +
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 2dd3f99372..ef8675b3a4 100644 --- a/doc/src/sgml/mvcc.sgml +++ b/doc/src/sgml/mvcc.sgml @@ -1,4 +1,4 @@ - + Concurrency Control @@ -25,10 +25,10 @@ - Unlike traditional database systems which use locks for concurrency control, - PostgreSQL - maintains data consistency by using a multiversion model - (Multiversion Concurrency Control, MVCC). + PostgreSQL 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, MVCC). This means that while querying a database each transaction sees a snapshot of data (a database version) 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 transaction isolation - for each database session. + for each database session. MVCC, by eschewing + explicit locking methodologies of traditional database systems, + minimizes lock contention in order to allow for reasonable + performance in multiuser environments. @@ -52,7 +55,9 @@ PostgreSQL for applications that cannot adapt easily to MVCC behavior. However, proper use of MVCC 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. @@ -859,6 +864,83 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; (e.g., while waiting for user input). + + + Advisory Locks + + + lock + advisory + + + + PostgreSQL provides a means for + creating locks that have application-defined meanings. These are + called 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 + PostgreSQL, a complete list of advisory + locks currently held by any session can be found in the system view + pg_locks. + + + + Advisory locks are allocated out of a shared memory pool whose size + is defined by the configuration variables + and + . + 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. + + + + A common use of advisory locks is to emulate pessimistic locking + strategies typical of so called 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 LIMIT clauses, care must be + taken to control the locks acquired because of the order in which SQL + expressions are evaluated. For example: + +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 + + In the above queries, the second form is dangerous because the + 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 + pg_locks. + + + + The functions provided to manipulate advisory locks are described in + . + + + @@ -993,12 +1075,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; - Short-term share/exclusive page-level locks are used for - read/write access. Locks are released immediately after each - index row is fetched or inserted. But note that a GIN-indexed - value insertion usually produces several index key insertions - per row, so GIN may do substantial work for a single value's - insertion. + Short-term share/exclusive page-level locks are used for + read/write access. Locks are released immediately after each + index row is fetched or inserted. But note that a GIN-indexed + value insertion usually produces several index key insertions + per row, so GIN may do substantial work for a single value's + insertion.