Skip to content

Commit 8a8becc

Browse files
Attribute check_id 9 blocking wait time to the chain's lead blocker
The "Top Blocking Query" rollup previously summed each BPR's victim wait_time against the direct blocker's sql_handle. In a chain like A blocks B blocks C, B would show up as a blocker "responsible" for C's wait — but B was itself stuck behind A, so blaming B is misleading. The only query that needs tuning is A. This commit rewrites the rollup so every BPR's victim wait cascades up to the chain's lead blocker (level-0 session in the monitor_loop): - New #session_leads temp table materializes a (monitor_loop, lead_desc, session_desc) map via a recursive CTE. Anchor rows are lead blockers (sessions that never appear as a blocked_desc in the same monitor_loop); recursion walks downstream, keeping lead_desc constant so every descendant inherits the same root. - Cycle guard mirrors the existing hierarchy CTE pattern (lead_path LIKE check, MAXRECURSION 100). - Fallback pass inserts any blocking_desc not reached by the recursion as its own lead — catches true cycle cases (mutual blocking before deadlock detection fires) so their waits don't silently drop. - bpr_with_lead CTE joins #blocking to #session_leads on session_desc to find each BPR's chain lead, extracts victim waittime from the blocked-process/@WaitTime XPath (the correct "how long did the victim wait" value), and applies the @database_name / @object_name filters at the BPR level rather than the chain level so we can still trace waits that cascade across objects. - lead_sql CTE pulls a representative sql_handle / stmtstart / stmtend / query_text_pre per (monitor_loop, lead_desc) from any #blocking row where the lead appears as the blocking-process. - per_victim CTE dedupes to (lead_sql_identity, victim_tx) with peak wait, matching the existing dedup pattern across repeat BPR fires. - Final INSERT groups by (database_name, lead_sql_handle, stmtstart, stmtend), keeps the existing "must be >= 10% of total" HAVING filter, and renames finding_group to 'Top Lead Blocker'. The finding text now reads 'This lead blocker accounted for ... across N blocked sessions in its chain.' to make the cascaded-attribution semantic explicit. Intermediate blockers (sessions that blocked downstream but were themselves victims) no longer appear in the rollup — by design. Their apparent blocking time cascaded up to whoever's actually holding the lock at the top of the chain. Smoke-tested on sql2022 against real hammerdb_tpcc BPR data: the #session_leads debug dump shows correct (monitor_loop, lead, session) mappings for chains of depth 2-4, and the rollup surfaces three neword/delivery procs that together account for 100% of chain wait time (43.3% + 30.2% + 26.5%). Previously intermediate blockers that clogged this list no longer appear. Also compiled cleanly on sql2017 as a syntax sanity check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a08cdb3 commit 8a8becc

1 file changed

Lines changed: 258 additions & 63 deletions

File tree

0 commit comments

Comments
 (0)