From 280c8eecc1c291a2a32518737d1d08d5a434130a Mon Sep 17 00:00:00 2001
From: TatsuyaKawata <kawatatatsuya0913@gmail.com>
Date: Sat, 20 Jun 2026 16:04:45 +0900
Subject: [PATCH v2] doc: add Fast-Path Locking section and link from related
 views

Fast-path locking is referenced by pg_stat_lock.fastpath_exceeded,
pg_locks.fastpath, and max_locks_per_transaction, but the docs lack a
central description of what it is and which lock acquisitions are
eligible.  Without that, users inspecting pg_stat_lock can be confused
by non-relation rows that show fastpath_exceeded = 0 next to non-zero
waits, and wonder whether the counter is broken.

Add a new "Fast-Path Locking" subsection under Explicit Locking, and
reference it from the three places above.
---
 doc/src/sgml/config.sgml       |  6 ++++++
 doc/src/sgml/monitoring.sgml   |  3 +++
 doc/src/sgml/mvcc.sgml         | 29 +++++++++++++++++++++++++++++
 doc/src/sgml/system-views.sgml |  3 ++-
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index fa566c9e553..a5152389bc9 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -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
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 08d5b824552..a33ee854b08 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -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>
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml
index 241caeb3593..102dbbd5854 100644
--- a/doc/src/sgml/mvcc.sgml
+++ b/doc/src/sgml/mvcc.sgml
@@ -1248,6 +1248,35 @@ 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>).  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>
+    </sect3>
    </sect2>
 
    <sect2 id="locking-rows">
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 2ebec6928d5..967efea9fe8 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -1977,7 +1977,8 @@ 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"/> for
+       details.
       </para></entry>
      </row>
 
-- 
2.34.1

