diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 37c471219d0..c433690fe18 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -22426,13 +22426,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 023a004ac89..634e9b4ae45 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)