[receiver/sqlserver] Fix query sample dropping sessions blocked on schema locks - #49984
Merged
ChrsMark merged 7 commits intoAug 5, 2026
Merged
Conversation
…hema locks The query sample template used `CROSS APPLY sys.dm_exec_sql_text(r.plan_handle)`. For a session waiting on `LCK_M_SCH_S` or `LCK_M_SCH_M`, `sys.dm_exec_sql_text` returns zero rows because the plan-cache lookup itself needs schema stability that the wait is holding up. `CROSS APPLY` then drops the outer row, so blocked sessions were silently omitted from `db.server.query_sample` events. Fix: - Change `CROSS APPLY` to `OUTER APPLY` on `sys.dm_exec_sql_text(r.plan_handle)` so rows are preserved when the TVF returns nothing. - Add `OUTER APPLY sys.dm_exec_input_buffer(r.session_id, r.request_id)` as a fallback source for statement_text. `dm_exec_input_buffer` reads directly from the connection buffer and works even when plan_handle is unresolvable. - Wrap statement_text extraction in `COALESCE(SUBSTRING(...), ib.event_info, '')` so statement-level granularity is preserved for healthy sessions and only falls back to whole-batch text when plan_handle lookup fails. - Make the `WHERE` clause NULL-safe for both `o.TEXT` and `ib.event_info`. Also adds a targeted regression test `TestQuerySampleQueryDetectsSchemaLockBlocking` that asserts each invariant needed to prevent this class of bug from recurring. Fixes open-telemetry#49983 Assisted-by: Claude Sonnet 4.6
github-actions
Bot
requested review from
XSAM,
akshays-19,
ebrdarSplunk,
sincejune and
sv-splunk
July 31, 2026 08:13
splunk-shanu
marked this pull request as draft
July 31, 2026 08:14
Pull request dashboard statusMerged · refreshed 2026-08-05 06:45 UTC Status above doesn't look right?
|
splunk-shanu
marked this pull request as ready for review
August 3, 2026 11:47
crobert-1
approved these changes
Aug 4, 2026
Member
|
/rerun |
ChrsMark
approved these changes
Aug 5, 2026
ChrsMark
left a comment
Member
There was a problem hiding this comment.
LGTM, approved by code-owner. Will merge.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The query sample template used
CROSS APPLY sys.dm_exec_sql_text(r.plan_handle). For a session waiting onLCK_M_SCH_S(Schema Stability) orLCK_M_SCH_M(Schema Modification),sys.dm_exec_sql_textreturns zero rows — because the plan-cache lookup itself needs schema stability that the wait is holding up.CROSS APPLYthen eliminates the outer row entirely, so blocked sessions were silently omitted fromdb.server.query_sampleevents. Users lost visibility into all schema-related blocking (index rebuilds,ALTER TABLE, statistics updates during load).This PR:
CROSS APPLYtoOUTER APPLYonsys.dm_exec_sql_text(r.plan_handle)so rows are preserved when the TVF returns nothing.OUTER APPLY sys.dm_exec_input_buffer(r.session_id, r.request_id)as a fallback source forstatement_text.dm_exec_input_bufferreads directly from the client connection's TDS buffer and still works whenplan_handleis unresolvable.statement_textextraction inCOALESCE(SUBSTRING(...), ib.event_info, '')so statement-level granularity (viastatement_start_offset/statement_end_offset) is preserved for healthy sessions and only falls back to whole-batch text frominput_bufferwhen the plan-cache lookup fails.WHEREclause NULL-safe for botho.TEXTandib.event_infoso encrypted stored procedures and other zero-row scenarios are no longer silently dropped.The same class of bug also affected encrypted procs (
WITH ENCRYPTION), plans aged out of cache during long blocks, and pre-parse sessions — all fixed by the same change.sys.dm_exec_input_bufferrequires the sameVIEW SERVER STATEpermission the receiver already needs.Link to tracking issue
Fixes #49983
Testing
LCK_M_SCH_Sblocked by Session A holdingLCK_M_SCH_M→ confirmed row now emitted.LCK_M_SCH_Mblocked by Session A holdingLCK_M_SCH_S(via long-running SELECT withHOLDLOCK) → confirmed row now emitted.statement_textstill returns the specific waiting statement (e.g.WAITFOR DELAY '00:05:00'), not the whole batch — statement-level granularity preserved.testQuerySampleQuery.txtto match the new query.TestQuerySampleQueryDetectsSchemaLockBlockingthat asserts each invariant needed to prevent this class of bug:CROSS APPLY sys.dm_exec_sql_textOUTER APPLY sys.dm_exec_sql_text(r.plan_handle)sys.dm_exec_input_bufferWHEREmust be NULL-safe for botho.TEXTandib.event_infostatement_textmust use aCOALESCE(...)chain withib.event_infofallbackgo test ./...inreceiver/sqlserverreceiverpasses.Documentation
No user-facing documentation changes.
documentation.mdunchanged (no metric/attribute additions).Authorship