mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix pg_blocking_pids() for relation extension locks.
pg_blocking_pids() assumes that members of the same lock group
never block each other, but that hasn't been true for relation
extension locks since v13. This commit teaches the function to
report lock group members as blockers for relation extension locks.
Since parallel workers are reported with their leader's PID, the
result may now include the blocked session's own PID.
Oversight in commit 85f6b49c2c.
Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Shihao Zhong <zhong950419@gmail.com>
Discussion: https://postgr.es/m/apTpV8h%2BCYHf%2B1PJ%40bdtpg
Backpatch-through: 14
This commit is contained in:
@@ -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, <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.
|
||||
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 <literal>extend</literal> in
|
||||
<link linkend="view-pg-locks"><structname>pg_locks</structname></link>),
|
||||
in which case the result contains the blocked session's own process
|
||||
ID.
|
||||
</para>
|
||||
<para>
|
||||
Frequent calls to this function could have some impact on database
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user