S
Supanote
Sign in Sign up

Live PostgreSQL Lock Tree (pg_blocking_pids) & Safe Killer

plain (sql) 1 day ago · 69 lines · 4 views
Verified Blueprint PostgreSQL

Recursive PostgreSQL lock tree query using pg_blocking_pids() to pinpoint root blocker transactions holding DDL or row locks.

  • ✓ Builds an indented visual blocking hierarchy from root idle-in-transaction blockers down to queued victims
  • ✓ Surfaces exact lock modes, wait events, state durations, and truncated SQL statements
  • ✓ Generates ready-to-run pg_cancel_backend() and pg_terminate_backend() commands only for root blockers
Quick Fetch
1-- Live PostgreSQL Hierarchical Lock Tree & Root Blocker Inspector (PG 14 - PG 18)
2-- Run during migration hangs or row-lock pileups to identify the exact root cause PID
3
4WITH RECURSIVE activity AS (
5 SELECT
6 pid,
7 usename,
8 application_name,
9 client_addr,
10 state,
11 wait_event_type || ':' || wait_event AS wait_info,
12 now() - xact_start AS xact_age,
13 now() - query_start AS query_age,
14 pg_blocking_pids(pid) AS blocked_by,
15 left(regexp_replace(query, 's+', ' ', 'g'), 140) AS sql_preview
16 FROM pg_stat_activity
17 WHERE pid <> pg_backend_pid()
18),
19blockers AS (
20 -- Root blockers: processes that block someone else, but are NOT blocked themselves
21 SELECT
22 a.pid,
23 a.usename,
24 a.application_name,
25 a.state,
26 a.wait_info,
27 a.xact_age,
28 a.query_age,
29 0 AS depth,
30 ARRAY[a.pid] AS path,
31 a.sql_preview
32 FROM activity a
33 WHERE cardinality(a.blocked_by) = 0
34 AND EXISTS (
35 SELECT 1 FROM activity w WHERE a.pid = ANY(w.blocked_by)
36 )
38 UNION ALL
40 -- Blocked waiters recursively attached underneath their blocker
41 SELECT
42 w.pid,
43 w.usename,
44 w.application_name,
45 w.state,
46 w.wait_info,
47 w.xact_age,
48 w.query_age,
49 b.depth + 1 AS depth,
50 b.path || w.pid AS path,
51 w.sql_preview
52 FROM activity w
53 JOIN blockers b ON b.pid = ANY(w.blocked_by)
54 WHERE NOT (w.pid = ANY(b.path))
56SELECT
57 repeat(' -> ', depth) || pid::text AS lock_hierarchy_pid,
58 state,
59 coalesce(wait_info, 'CPU / IDLE') AS waiting_on,
60 date_trunc('second', xact_age) AS tx_duration,
61 application_name AS app,
62 sql_preview,
63 CASE
64 WHEN depth = 0 THEN format('SELECT pg_terminate_backend(%s); -- ROOT BLOCKER', pid)
65 ELSE ''
66 END AS safe_remediation_sql
67FROM blockers
68ORDER BY path;

No replies yet

Every reply is a note. Start a discussion, ask a question, or attach a code snippet.

Related PostgreSQL & Database, Cache & SQL Blueprints

Production-ready configurations and diagnostics from the verified Supanote library.

All Database, Cache & SQL →
Interactive Developer Workbench: .env, Log & API Key Secret Scanner

Detect and redact leaked AWS keys, JWTs, database URIs, private keys, and Bearer tokens before sharing.

Open Secret Scanner →

Share Note

Open
Download SVG
Social Card Preview
Open on mobile
Point your phone camera to open this note directly

Report this note

Notification