doc: Add new section describing fast-path locking

Fast-path locking is referenced by pg_stat_lock.fastpath_exceeded, by
pg_locks.fastpath, and in the GUC max_locks_per_transaction.  However,
the documentation has never described in details how this works; one
would need to look at the internals of lock.c, mostly around
EligibleForRelationFastPath().

This commit adds a new subsection called "Fast-Path Locking" to the area
dedicated to locks, with the three places mentioned above linking to it.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAHza6qdKo9dcPy70QBi88vpqhS2gYWViS8=Uj=-+QQbR=ONgSQ@mail.gmail.com
This commit is contained in:
Michael Paquier 2026-07-01 10:08:26 +09:00
parent a78f7390bf
commit 2d31da5271
4 changed files with 50 additions and 2 deletions

View file

@ -11726,6 +11726,12 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir'
many children. This parameter can only be set at server start.
</para>
<para>
This parameter also determines the number of per-backend slots
available for <link linkend="locking-tables-fast-path">fast-path
locking</link>.
</para>
<para>
When running a standby server, you must set this parameter to have the
same or higher value as on the primary server. Otherwise, queries

View file

@ -3378,6 +3378,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage
Number of times a lock of this type could not be acquired via fast path
because the fast path slot limit was exceeded. Increasing
<xref linkend="guc-max-locks-per-transaction"/> can reduce this number.
See <xref linkend="locking-tables-fast-path"/> for which locks are
eligible for fast-path locking; for ineligible lock types this
counter is always zero.
</para>
</entry>
</row>

View file

@ -1248,6 +1248,44 @@ ERROR: could not serialize access due to read/write dependencies among transact
</tbody>
</tgroup>
</table>
<sect3 id="locking-tables-fast-path">
<title>Fast-Path Locking</title>
<indexterm zone="locking-tables-fast-path">
<primary>fast-path locking</primary>
</indexterm>
<para>
Internally, <productname>PostgreSQL</productname> can record some
table-level locks using a <firstterm>fast-path locking</firstterm>
mechanism instead of the main lock table. This reduces the overhead of
acquiring and releasing locks that rarely conflict. It is an
implementation optimization and does not change lock semantics.
</para>
<para>
Fast-path locking can be used only for eligible relation locks in the
weak table-level lock modes <literal>ACCESS SHARE</literal>
(<literal>AccessShareLock</literal>), <literal>ROW SHARE</literal>
(<literal>RowShareLock</literal>), and <literal>ROW EXCLUSIVE</literal>
(<literal>RowExclusiveLock</literal>). It does not apply to shared
relations (those visible across all databases, such as
<structname>pg_authid</structname>). Other lock types, and stronger
lock modes on relations, always go through the main lock table. Even
for eligible locks, fast-path is used only when a per-backend slot is
available; the number of slots is derived from <xref
linkend="guc-max-locks-per-transaction"/>. When no slot is available,
the lock is acquired via the main lock table instead.
</para>
<para>
Acquiring a lock via the main lock table is considerably more
expensive than the fast path, and under heavy concurrent lock
activity can become a point of contention (observable as the
<literal>LockManager</literal> wait event).
</para>
</sect3>
</sect2>
<sect2 id="locking-rows">

View file

@ -1977,7 +1977,7 @@ AND c1.path[c2.level] = c2.path[c2.level];
</para>
<para>
True if lock was taken via fast path, false if taken via main
lock table
lock table (see <xref linkend="locking-tables-fast-path"/>)
</para></entry>
</row>
@ -2113,7 +2113,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
The <structname>pg_locks</structname> view displays data from both the
regular lock manager and the predicate lock manager, which are
separate systems; in addition, the regular lock manager subdivides its
locks into regular and <firstterm>fast-path</firstterm> locks.
locks into regular and <firstterm>fast-path</firstterm> locks
(see <xref linkend="locking-tables-fast-path"/>).
This data is not guaranteed to be entirely consistent.
When the view is queried,
data on fast-path locks (with <structfield>fastpath</structfield> = <literal>true</literal>)