Skip to content

v3.5.5 - Re-entrancy guard ALREADY_RUNNING fix (i7by)

Choose a tag to compare

@nanoDBA nanoDBA released this 10 Jun 18:30

sp_StatUpdate.sql (v3.5.5)

sp_StatUpdate-i7by (false ALREADY_RUNNING after validation-error exit): when a caller wraps EXEC sp_StatUpdate in TRY/CATCH, the CATCH intercepts the proc's severity-16 validation RAISERROR before the proc reaches its own DELETE cleanup, leaving a stale row in dbo.StatUpdateLock. A second call in the same session then saw the stale row, found the holding session "alive" in sys.dm_exec_sessions (it IS the caller), and falsely raised ALREADY_RUNNING. Three-part fix in the re-entrancy guard:

  • S (primary): a lock row held by the caller's own session (SessionID = @@SPID) is unconditionally stale - the prior call has by definition ended, since we are now executing in that same session. Reclaim without probing the DMVs (the probes would match our own active request).
  • A: for DIFFERENT sessions, the dead-holder reclaim now also fires when the session has no active request AND last_request_end_time is more than 60s in the past (catches async TCP teardown where a SPID lingers briefly in sys.dm_exec_sessions after client disconnect).
  • D: TTL guard - any lock row with AcquiredAt older than 8 hours reclaims unconditionally regardless of session state.

Genuine concurrency is unaffected: a different session with an active sp_StatUpdate request still blocks as intended.

sp_StatUpdate_Diag.sql (2026.06.08.2)

sp_StatUpdate-g4c0: registers the QS_PARALLEL_UNRELIABLE category (introduced in 2026.06.08.1) in the diagnostic checks catalog as I9b / INFO. Cosmetic, no behavior change.

Test gate (all PASS on SQL 2019 / 2022 / 2025)

Suite Result
V3Core 16/16
V3Fixes 10/10
V3Coverage 11/11
Diag (StatUpdateDiag) 221/221

The diag suite gained an 8-assertion "W5 Parallel-QS Scenario" section (sp_StatUpdate-hr21) that exercises the new 2026.06.08.x branches end to end: QS_PARALLEL_UNRELIABLE INFO emission, QS_NOT_EFFECTIVE suppression, I10 QS retention with parallel-artifact rationale, TimeLimit jitter normalization (21598/21599 to 21600), and the W9-gated @CriticalTables hint. Additional targeted verification: the i7by repro (TRY/CATCH validation error followed by same-session calls) now completes with NO_QUALIFYING_STATS instead of ALREADY_RUNNING, and a fresh-stat case (3 consecutive @Execute = Y runs in one session, 8 successful UPDATE STATISTICS CommandLog rows) leaves dbo.StatUpdateLock empty after each run.