Skip to content

sp_PerfCheck Phase 2+3: real wait analysis, sane thresholds, trace-flag interpretation, tunable parameters - #837

Merged
erikdarlingdata merged 3 commits into
devfrom
perfcheck/phase2-health-signals
Jul 18, 2026
Merged

sp_PerfCheck Phase 2+3: real wait analysis, sane thresholds, trace-flag interpretation, tunable parameters#837
erikdarlingdata merged 3 commits into
devfrom
perfcheck/phase2-health-signals

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Making sp_PerfCheck useful, as a health check (cumulative/config signals). Live problems stay sp_PressureDetector's job. Three phases, held for a HammerDB validation on 2025 before merge.

Phase 1 (already merged, #836)

Cut the checklist noise and inverted the backwards config logic — a 27-finding run dropped to 10, all meaningful.

Phase 2 — depth on the signals

  • Wait stats (6001) — no longer a flat "High Impact Wait Type" for everything. Findings are named by category (Storage-Related Waits, Lock / Blocking Waits, Memory-Related Waits, TempDB Contention Waits, CPU / Scheduling Waits, Transaction Log Waits, Parallelism Waits), the wait type + meaning in object_name, severity calibrated per category.
  • Storage (3001/3002/3003) — thresholds were 500ms (catastrophic-storage territory); now 20ms (Medium) / 100ms (High).
  • Memory grants (4101/4103) — were High on any cumulative count; severity now scales with magnitude.
  • Trace flags (1012, new) — the notable/problematic global flags get per-flag interpretation.

Phase 3 — tunable thresholds

The calibrated values are now parameters (defaults unchanged, so default behavior is identical):
@slow_read_ms, @slow_write_ms, @significant_wait_threshold_pct, @wait_high_pct, @wait_medium_pct, @memory_grant_warning, @memory_grant_critical. Each defaults NULL/negative back to its documented value; @help documents all seven.

Plus a harness fix: force SET OFFLINE with ROLLBACK IMMEDIATE so the inaccessible-database tests can't hang.

Compiles on all five versions; assertion harness 39/39. Storage/memory behavior is best seen under load — that's the HammerDB run.

🤖 Generated with Claude Code

erikdarlingdata and others added 3 commits July 18, 2026 10:02
…lds, trace-flag interpretation

Health-check depth on the cumulative/config signals (live problems remain
sp_PressureDetector's job).

Wait stats (6001): stop labeling every wait a flat "High Impact Wait Type".
Name the finding by category so the list reads as a diagnosis (Storage /
Lock / Memory / TempDB / CPU / Transaction Log / Parallelism ...), put the
wait type and its meaning in object_name, and calibrate severity by category:
resource-pressure waits earn High by dominating uptime OR by long average
waits; parallelism tops out at Medium (it's a cost-threshold/MAXDOP symptom);
the rest stay Low. Idle-box CXCONSUMER drops from a flagged wait to a Low
"Parallelism Waits" note.

Storage (3001/3002/3003): the slow-read/write thresholds defaulted to 500ms,
which is catastrophic-storage territory, so real latency never surfaced. Drop
to 20ms (data-file I/O should be under 20ms), with High at 5x (100ms).

Memory grants (4101/4103): these are cumulative counts since startup, so
firing High on any count > 0 over-reacts to a handful of transient events.
Scale severity with magnitude instead.

Trace flags (1012, new): the global flags were only listed in server-info.
Interpret the notable ones with per-flag meaning and severity -- 1211/3608/
3609 High, 1224/834 Medium, redundant-on-2016+ ones (1117/1118/2371) and
behavior-changers (4199/8048) Low -- leaving benign flags in the list only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The inaccessible-database tests took a database OFFLINE without ROLLBACK
IMMEDIATE, so any open connection made the ALTER wait indefinitely and the
suite hung (300s subprocess timeout). Force it, so the transition is
immediate and the test can't hang in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The values calibrated in Phase 2 were still hardcoded. Expose the tunable
ones as parameters (defaults = the Phase 2 values, so default behavior is
unchanged), letting a caller adjust to their environment:

  @slow_read_ms / @slow_write_ms          storage latency (ms)
  @significant_wait_threshold_pct         floor for a wait to be reported
  @wait_high_pct / @wait_medium_pct       resource-wait severity bands
  @memory_grant_warning / _critical       forced-grant severity bands

Each defaults NULL or negative back to its documented value, so a caller can
override just the ones they care about. Help text (description / valid inputs
/ defaults) covers all seven. The secondary avg-ms wait bands and the grant-
timeout bands stay internal for now. Compiles on all five versions; the
assertion harness passes 39/39.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata changed the title sp_PerfCheck Phase 2: real wait analysis + sane storage/memory thresholds + trace-flag interpretation sp_PerfCheck Phase 2+3: real wait analysis, sane thresholds, trace-flag interpretation, tunable parameters Jul 18, 2026
@erikdarlingdata
erikdarlingdata merged commit 795c8df into dev Jul 18, 2026
6 checks passed
@erikdarlingdata
erikdarlingdata deleted the perfcheck/phase2-health-signals branch July 18, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant