agora inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
[PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
144+ messages / 3 participants
[nested] [flat]

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--






^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids()
@ 2026-08-29 04:24 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-29 04:24 UTC (permalink / raw)

Commit 85f6b49c2c53 made relation extension locks conflict between members of
the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids(). So, pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Add the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The
commit also documents this behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/...
---
 doc/src/sgml/func/func-info.sgml  | 14 +++++++++++---
 src/backend/utils/adt/lockfuncs.c | 10 ++++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)
  68.7% doc/src/sgml/func/
  31.2% src/backend/utils/adt/

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 2f03766b67a..226a815916d 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -246,9 +246,17 @@
         request and is ahead of it in the wait queue (soft block).  When using
         parallel queries the result always lists client-visible process IDs
         (that is, <function>pg_backend_pid</function> results) even if the
-        actual lock is held or awaited by a child worker process.  As a result
-        of that, there may be duplicated PIDs in the result.  Also note that
-        when a prepared transaction holds a conflicting lock, it will be
+        actual lock is held or awaited by a child worker process. As a result
+        of that, there may be duplicated PIDs in the result. When members of
+        the same parallel lock group block each other on a relation extension
+        lock (shown as lock type <literal>extend</literal> in <link
+        linkend="view-pg-locks"><structname>pg_locks</structname></link>), the
+        specified process ID can also appear in the result. This does not mean
+        that a process blocks itself. Rather, a lock held by one member of its
+        parallel lock group blocks a lock request made by another member of that
+        group.
+        Also note that when a prepared transaction holds a conflicting lock,
+        it will be
         represented by a zero process ID.
        </para>
        <para>
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 3eb9a5b4215..1f0cc2b9bcb 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -518,8 +518,14 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
 			/* A proc never blocks itself, so ignore that entry */
 			if (instance == blocked_instance)
 				continue;
-			/* Members of same lock group never block each other, either */
-			if (instance->leaderPid == blocked_instance->leaderPid)
+
+			/*
+			 * Members of the same lock group do not block each other, except
+			 * when extending a relation.
+			 */
+			if (instance->leaderPid == blocked_instance->leaderPid &&
+				blocked_instance->locktag.locktag_type !=
+				LOCKTAG_RELATION_EXTEND)
 				continue;
 
 			if (conflictMask & instance->holdMask)
-- 
2.34.1


--DQnhTvUE7k3IbPB4--





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* Report relation extension blockers within parallel lock groups
@ 2026-08-31 02:39 Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  2026-08-31 09:22 ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
  2026-09-04 05:45 ` Re: Report relation extension blockers within parallel lock groups Kirill Reshke <reshkekirill@gmail.com>
  0 siblings, 2 replies; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-31 02:39 UTC (permalink / raw)
  To: pgsql-hackers@lists.postgresql.org; +Cc: Amit Kapila <amit.kapila16@gmail.com>

Hi hackers,

While working on providing more informations related to locks (patch not shared
yet), it appeared that pg_blocking_pids() can omit the process that is actually
blocking a relation extension request.

Indeed, commit 85f6b49c2c53 made relation extension locks conflict between members
of the same parallel lock group, but did not update the same group filtering in
pg_blocking_pids().

The attached adds the relation extension exception in pg_blocking_pids().

pg_blocking_pids() reports parallel workers using their lock group leader PID.
Therefore, when one member of a parallel lock group blocks another, the PID
supplied to pg_blocking_pids() can appear in the result. This does not mean
that a process blocks itself. Rather, a lock held by one member of its parallel
lock group blocks a lock request made by another member of that group. The patch
documents this behavior.

No regression test is added because ensuring relation extension lock contention
between members of the same parallel lock group would be more complicated than
needed for this simple patch.

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

  [text/x-diff] v1-0001-Report-relation-extension-blockers-within-paralle.patch (0B, ../../apTpV8h+CYHf+1PJ@bdtpg/2-v1-0001-Report-relation-extension-blockers-within-paralle.patch)
  download

^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* Re: Report relation extension blockers within parallel lock groups
  2026-08-31 02:39 Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
@ 2026-08-31 09:22 ` Chao Li <li.evan.chao@gmail.com>
  2026-08-31 10:38   ` Re: Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  1 sibling, 1 reply; 144+ messages in thread

From: Chao Li @ 2026-08-31 09:22 UTC (permalink / raw)
  To: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>; +Cc: pgsql-hackers@lists.postgresql.org, Amit Kapila <amit.kapila16@gmail.com>



> On Aug 31, 2026, at 10:39, Bertrand Drouvot <bertranddrouvot.pg@gmail.com> wrote:
> 
> Hi hackers,
> 
> While working on providing more informations related to locks (patch not shared
> yet), it appeared that pg_blocking_pids() can omit the process that is actually
> blocking a relation extension request.
> 
> Indeed, commit 85f6b49c2c53 made relation extension locks conflict between members
> of the same parallel lock group, but did not update the same group filtering in
> pg_blocking_pids().
> 
> The attached adds the relation extension exception in pg_blocking_pids().
> 
> pg_blocking_pids() reports parallel workers using their lock group leader PID.
> Therefore, when one member of a parallel lock group blocks another, the PID
> supplied to pg_blocking_pids() can appear in the result. This does not mean
> that a process blocks itself. Rather, a lock held by one member of its parallel
> lock group blocks a lock request made by another member of that group. The patch
> documents this behavior.
> 
> No regression test is added because ensuring relation extension lock contention
> between members of the same parallel lock group would be more complicated than
> needed for this simple patch.
> 
> Regards,
> 
> -- 
> Bertrand Drouvot
> PostgreSQL Contributors Team
> RDS Open Source Databases
> Amazon Web Services: https://aws.amazon.com
> <v1-0001-Report-relation-extension-blockers-within-paralle.patch>

Looks like 3ba59ccc896e did the same thing for page locks, so I wonder if this patch should include page lock as well, something like:
```
if (instance->leaderPid == blocked_instance->leaderPid &&
    blocked_instance->locktag.locktag_type != LOCKTAG_RELATION_EXTEND &&
    blocked_instance->locktag.locktag_type != LOCKTAG_PAGE)
    continue;
```

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/










^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* Re: Report relation extension blockers within parallel lock groups
  2026-08-31 02:39 Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  2026-08-31 09:22 ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
@ 2026-08-31 10:38   ` Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  2026-08-31 11:28     ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
  0 siblings, 1 reply; 144+ messages in thread

From: Bertrand Drouvot @ 2026-08-31 10:38 UTC (permalink / raw)
  To: Chao Li <li.evan.chao@gmail.com>; +Cc: pgsql-hackers@lists.postgresql.org, Amit Kapila <amit.kapila16@gmail.com>

Hi,

On Mon, Aug 31, 2026 at 05:22:20PM +0800, Chao Li wrote:
> > On Aug 31, 2026, at 10:39, Bertrand Drouvot <bertranddrouvot.pg@gmail.com> wrote:
> Looks like 3ba59ccc896e did the same thing for page locks,

Right, but 3ba59ccc896e was reverted by cc32ec24fdf (and backpatched through 13).

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com





^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* Re: Report relation extension blockers within parallel lock groups
  2026-08-31 02:39 Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
  2026-08-31 09:22 ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
  2026-08-31 10:38   ` Re: Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
@ 2026-08-31 11:28     ` Chao Li <li.evan.chao@gmail.com>
  0 siblings, 0 replies; 144+ messages in thread

From: Chao Li @ 2026-08-31 11:28 UTC (permalink / raw)
  To: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>; +Cc: pgsql-hackers@lists.postgresql.org, Amit Kapila <amit.kapila16@gmail.com>



> On Aug 31, 2026, at 18:38, Bertrand Drouvot <bertranddrouvot.pg@gmail.com> wrote:
> 
> Hi,
> 
> On Mon, Aug 31, 2026 at 05:22:20PM +0800, Chao Li wrote:
>>> On Aug 31, 2026, at 10:39, Bertrand Drouvot <bertranddrouvot.pg@gmail.com> wrote:
>> Looks like 3ba59ccc896e did the same thing for page locks,
> 
> Right, but 3ba59ccc896e was reverted by cc32ec24fdf (and backpatched through 13).
> 

Ah, then sorry for the noise.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/










^ permalink  raw  reply  [nested|flat] 144+ messages in thread

* Re: Report relation extension blockers within parallel lock groups
  2026-08-31 02:39 Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
@ 2026-09-04 05:45 ` Kirill Reshke <reshkekirill@gmail.com>
  1 sibling, 0 replies; 144+ messages in thread

From: Kirill Reshke @ 2026-09-04 05:45 UTC (permalink / raw)
  To: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>; +Cc: pgsql-hackers@lists.postgresql.org, Amit Kapila <amit.kapila16@gmail.com>

On Mon, 31 Aug 2026 at 07:39, Bertrand Drouvot
<bertranddrouvot.pg@gmail.com> wrote:
>
> Hi hackers,
>
> While working on providing more informations related to locks (patch not shared
> yet), it appeared that pg_blocking_pids() can omit the process that is actually
> blocking a relation extension request.
>
> Indeed, commit 85f6b49c2c53 made relation extension locks conflict between members
> of the same parallel lock group, but did not update the same group filtering in
> pg_blocking_pids().
>
> The attached adds the relation extension exception in pg_blocking_pids().
>
> pg_blocking_pids() reports parallel workers using their lock group leader PID.
> Therefore, when one member of a parallel lock group blocks another, the PID
> supplied to pg_blocking_pids() can appear in the result. This does not mean
> that a process blocks itself. Rather, a lock held by one member of its parallel
> lock group blocks a lock request made by another member of that group. The patch
> documents this behavior.


Your fix looks correct to me, matches deadlock detector code.

> No regression test is added because ensuring relation extension lock contention
> between members of the same parallel lock group would be more complicated than
> needed for this simple patch.

Isolation test you mean? Shouldn't be that hard using injection
points, but Anyway, I think I agree, too much cpu cycles will be
wasted on this small issue.


-- 
Best regards,
Kirill Reshke






^ permalink  raw  reply  [nested|flat] 144+ messages in thread


end of thread, other threads:[~2026-09-04 05:45 UTC | newest]

Thread overview: 144+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-29 04:24 [PATCH v1] Report relation extension blockers within parallel lock groups in pg_blocking_pids() Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-31 02:39 Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-31 09:22 ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
2026-08-31 10:38   ` Re: Report relation extension blockers within parallel lock groups Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
2026-08-31 11:28     ` Re: Report relation extension blockers within parallel lock groups Chao Li <li.evan.chao@gmail.com>
2026-09-04 05:45 ` Re: Report relation extension blockers within parallel lock groups Kirill Reshke <reshkekirill@gmail.com>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox