1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Implement SKIP LOCKED for row-level locks

This clause changes the behavior of SELECT locking clauses in the
presence of locked rows: instead of causing a process to block waiting
for the locks held by other processes (or raise an error, with NOWAIT),
SKIP LOCKED makes the new reader skip over such rows.  While this is not
appropriate behavior for general purposes, there are some cases in which
it is useful, such as queue-like tables.

Catalog version bumped because this patch changes the representation of
stored rules.

Reviewed by Craig Ringer (based on a previous attempt at an
implementation by Simon Riggs, who also provided input on the syntax
used in the current patch), David Rowley, and Álvaro Herrera.

Author: Thomas Munro
This commit is contained in:
Alvaro Herrera
2014-10-07 17:23:34 -03:00
parent c421efd213
commit df630b0dd5
38 changed files with 907 additions and 121 deletions

View File

@ -45,7 +45,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replac
[ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
[ OFFSET <replaceable class="parameter">start</replaceable> [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
<phrase>where <replaceable class="parameter">from_item</replaceable> can be one of:</phrase>
@ -1284,7 +1284,7 @@ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] {
The locking clause has the general form
<synopsis>
FOR <replaceable>lock_strength</> [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ]
FOR <replaceable>lock_strength</> [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ]
</synopsis>
where <replaceable>lock_strength</> can be one of
@ -1360,9 +1360,15 @@ KEY SHARE
<para>
To prevent the operation from waiting for other transactions to commit,
use the <literal>NOWAIT</> option. With <literal>NOWAIT</>, the statement
reports an error, rather than waiting, if a selected row
cannot be locked immediately. Note that <literal>NOWAIT</> applies only
use either the <literal>NOWAIT</> or <literal>SKIP LOCKED</literal>
option. With <literal>NOWAIT</>, the statement reports an error, rather
than waiting, if a selected row cannot be locked immediately.
With <literal>SKIP LOCKED</literal>, any selected rows that cannot be
immediately locked are skipped. Skipping locked rows provides an
inconsistent view of the data, so this is not suitable for general purpose
work, but can be used to avoid lock contention with multiple consumers
accessing a queue-like table.
Note that <literal>NOWAIT</> and <literal>SKIP LOCKED</literal> apply only
to the row-level lock(s) &mdash; the required <literal>ROW SHARE</literal>
table-level lock is still taken in the ordinary way (see
<xref linkend="mvcc">). You can use
@ -1394,7 +1400,9 @@ KEY SHARE
then it is processed as if it was only specified by the strongest one.
Similarly, a table is processed
as <literal>NOWAIT</> if that is specified in any of the clauses
affecting it.
affecting it. Otherwise, it is processed
as <literal>SKIP LOCKED</literal> if that is specified in any of the
clauses affecting it.
</para>
<para>
@ -1931,9 +1939,9 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
<productname>PostgreSQL</productname> allows it in any <command>SELECT</>
query as well as in sub-<command>SELECT</>s, but this is an extension.
The <literal>FOR NO KEY UPDATE</>, <literal>FOR SHARE</> and
<literal>FOR KEY SHARE</> variants,
as well as the <literal>NOWAIT</> option,
do not appear in the standard.
<literal>FOR KEY SHARE</> variants, as well as the <literal>NOWAIT</>
and <literal>SKIP LOCKED</literal> options, do not appear in the
standard.
</para>
</refsect2>

View File

@ -863,7 +863,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
[ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
[ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
[ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
</synopsis>
</para>