diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 1cf71f8903a..bb36e803e19 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -22011,13 +22011,20 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 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, pg_backend_pid 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. + + + When using parallel queries the result always lists client-visible + process IDs (that is, pg_backend_pid 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. Note + that the processes of a parallel query can block each other on + relation extension locks (lock type extend in + pg_locks), + in which case the result contains the blocked session's own process + ID. 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 5dc0a5882cf..54355d97088 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -497,8 +497,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 don't block each other, either, + * except on relation extension locks (see LockCheckConflicts()). + */ + if (instance->leaderPid == blocked_instance->leaderPid && + blocked_instance->locktag.locktag_type != + LOCKTAG_RELATION_EXTEND) continue; if (conflictMask & instance->holdMask)