Created
October 19, 2021 01:22
-
-
Save zhuomingliang/14cb1358786e2b85db7f7fe8ff0176bc to your computer and use it in GitHub Desktop.
Useful queries to analyze PostgreSQL lock trees (a.k.a. lock queues)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- from: https://postgres.ai/blog/20211018-postgresql-lock-trees | |
with recursive activity as ( | |
select | |
pg_blocking_pids(pid) blocked_by, | |
*, | |
age(clock_timestamp(), xact_start)::interval(0) as tx_age, | |
age(clock_timestamp(), state_change)::interval(0) as state_age | |
from pg_stat_activity | |
where state is distinct from 'idle' | |
), blockers as ( | |
select | |
array_agg(distinct c order by c) as pids | |
from ( | |
select unnest(blocked_by) | |
from activity | |
) as dt(c) | |
), tree as ( | |
select | |
activity.*, | |
1 as level, | |
activity.pid as top_blocker_pid, | |
array[activity.pid] as path, | |
array[activity.pid]::int[] as all_blockers_above | |
from activity, blockers | |
where | |
array[pid] <@ blockers.pids | |
and blocked_by = '{}'::int[] | |
union all | |
select | |
activity.*, | |
tree.level + 1 as level, | |
tree.top_blocker_pid, | |
path || array[activity.pid] as path, | |
tree.all_blockers_above || array_agg(activity.pid) over () as all_blockers_above | |
from activity, tree | |
where | |
not array[activity.pid] <@ tree.all_blockers_above | |
and activity.blocked_by <> '{}'::int[] | |
and activity.blocked_by <@ tree.all_blockers_above | |
) | |
select | |
pid, | |
blocked_by, | |
tx_age, | |
state_age, | |
backend_xid as xid, | |
backend_xmin as xmin, | |
replace(state, 'idle in transaction', 'idletx') as state, | |
datname, | |
usename, | |
wait_event_type || ':' || wait_event as wait, | |
(select count(distinct t1.pid) from tree t1 where array[tree.pid] <@ t1.path and t1.pid <> tree.pid) as blkd, | |
format( | |
'%s %s%s', | |
lpad('[' || pid::text || ']', 7, ' '), | |
repeat('.', level - 1) || case when level > 1 then ' ' end, | |
left(query, 1000) | |
) as query | |
from tree | |
order by top_blocker_pid, level, pid | |
\watch 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment