Hi Shihao, On Fri, Oct 02, 2026 at 10:47:03PM -0600, shihao zhong wrote: > Hi Bertrand, > > > The description in the documentation is getting quite dense. This could > be > > a good opportunity to restructure it for readability. > > The attached 0002 goes on top of v1. > > It moves the prepared transaction sentence up and > gives parallel query its own paragraph.
Thanks for the proposal! Moving the prepared transaction sentence up and giving parallel query its own paragraph make sense to me. That said, I think that the parallel query paragraph could be made a bit shorter like in v2 attached. Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
>From b09ceeab9d6f217f39d3cb6cb64b3e0c398aabcd Mon Sep 17 00:00:00 2001 From: Bertrand Drouvot <[email protected]> Date: Sat, 29 Aug 2026 04:24:42 +0000 Subject: [PATCH v2] Report relation extension blockers within parallel lock groups in pg_blocking_pids() 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 <[email protected]> Reviewed-by: shihao zhong <[email protected]> Reviewed-by: Kirill Reshke <[email protected]> Reviewed-by: Chao Li <[email protected]> Discussion: https://postgr.es/m/apTpV8h%2BCYHf%2B1PJ%40bdtpg --- doc/src/sgml/func/func-info.sgml | 20 +++++++++++++------- src/backend/utils/adt/lockfuncs.c | 10 ++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) 75.1% doc/src/sgml/func/ 24.8% src/backend/utils/adt/ diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index e56c9a22c42..8f55a1cb755 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -243,13 +243,19 @@ One server process blocks another if it either holds a lock that conflicts with the blocked process's lock request (hard block), or is waiting for a lock that would conflict with the blocked process's lock - 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 - represented by a zero process ID. + request and is ahead of it in the wait queue (soft block). A prepared + transaction that holds a conflicting lock is represented by a zero + process ID. + </para> + <para> + 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. + Thus, the result can contain duplicate PIDs or, for relation extension + locks (lock type <literal>extend</literal> in <link + linkend="view-pg-locks"><structname>pg_locks</structname></link>), the + PID of the blocked session itself when one process participating in + the parallel query blocks another. </para> <para> Frequent calls to this function could have some impact on database 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
