Merged
Conversation
…ystem (#218) Root cause: archival DELETEs + CHECKPOINT reorganized/truncated the DuckDB file while UI connections had stale file offsets, causing "Reached the end of the file" crashes after ~1 hour of uptime. Fix: ReaderWriterLockSlim coordinates UI readers with maintenance writers. UI queries hold read locks (unlimited concurrency) via LockedConnection wrapper. CHECKPOINT and archive DELETEs hold exclusive write locks (<1s duration). Maintenance overhaul: - Replaced compaction cycle (File.Replace race condition) with archive-all-and-reset - Size-based trigger at 512MB archives ALL data to parquet, deletes .duckdb, reinits - Tested: 515MB → 19MB in <1s, 65K rows to ~400KB ZSTD parquet per cycle - Per-reset timestamped parquet naming (20260221_1925_table.parquet) eliminates merge logic and simplifies 90-day retention (delete by date prefix) - RetentionService handles both new timestamped and legacy monthly formats - Wired AppLoggerAdapter<T> for all 8 services that had null loggers - Removed dead CompactAsync method (~140 lines) Tested with 4 SQL Servers under HammerDB load, 3 successful archive+reset cycles, zero errors, archive views correctly serve data from all parquet file sets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r-corruption Fix DuckDB file corruption during maintenance (#218)
…kDB-first plans, lock wait trend, clipboard fix, procedure stats parity Issues addressed: - #185: Consolidate Server/Database/Trace Flag config change tabs into single ConfigChangesContent UserControl with sub-tabs (Dashboard) - #201: Add option to drop PerformanceMonitor database when removing a server, with confirmation dialog (Dashboard) - #219: Try DuckDB cache first for query plan downloads before falling back to live server (Lite) - #141: Add lock waits trend chart to Blocking > Trends tab with multi-series per LCK% wait type (Lite) Additional fixes: - Fix clipboard copy: "Copy All Rows" and "Export to CSV" context menu items now extract TextBlock text from StackPanel column headers instead of showing "System.Windows.Controls.StackPanel" (both apps, 22 call sites) - Add missing columns to Lite procedure stats grid: Total Spills, Min/Max CPU, Min/Max Duration, Plan Handle, and Download Plan button with DuckDB-first lookup - Filter out zero-activity rows from query stats and procedure stats grids (HAVING clause on delta sums) - Make query stats grid plan download DuckDB-first (was live-server only) - Fix plan download button text resetting to "Save" instead of "Download" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ig-changes v1.4.0: Config consolidation, DB drop, DuckDB-first plans, lock wait chart, clipboard fix
Memory clerks data was already being collected but had no UI. Added a Memory Clerks sub-tab under Memory with a type picker (matching the wait stats pattern), trend chart showing MB over time per clerk type, and a summary footer showing non-buffer-pool total and top clerk. Also added missing DuckDB index on memory_clerks(server_id, collection_time). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lite: Add memory clerks tab with picker-driven chart (#145)
…cators (#110) - Add sort direction arrows to DataGrid column headers via custom ControlTemplate with Path geometry and SortDirection triggers (both Dashboard and Lite themes) - Right-align ~321 numeric columns across both projects using NumericCell ElementStyle - Show initial sort arrow on pre-sorted grids (Query Stats, Proc Stats, Query Store, Regressions, Long Running Patterns) so users see current sort before clicking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Visual polish: sort arrows, right-aligned numerics, initial sort indicators (#110)
) Port duration trends chart from Lite to Dashboard. Shows per-collector execution times over 24h with one colored line per collector. Excludes scheduled_master_collector to keep individual collector durations readable. Wired into parallel refresh flow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on-chart Add collector duration trends chart to Dashboard (#138)
Collection log drill-down: double-click a collector in Health Summary to see its full history (runs, duration breakdown, errors). Daily summary: new tab with date picker showing aggregated daily metrics — total waits, top wait type, deadlocks, blocking, high CPU, and collection errors for the selected day. Closes #138 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…log-drilldown Add collection log drill-down and daily summary to Lite (#138)
Dashboard: New "Current Active Queries" sub-tab under Queries that runs dm_exec_requests directly against the server for a live view of running queries. Independent refresh button, column filtering, and query plan download (.sqlplan) from in-memory results. No PerformanceMonitor DB involvement — pure DMV snapshot. Lite: "Live Snapshot" button on Active Queries tab runs the same collector query directly against the server, bypassing DuckDB. Results populate the existing grid with a gold "LIVE at HH:mm:ss" indicator that clears on next auto-refresh. Both: Enhanced query with 5 new columns from dm_exec_sessions — login_name, host_name, program_name, open_transaction_count, percent_complete. Lite schema bumped to v12 with ALTER TABLE migration. Tested on sql2022 and sql2016. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Current Active Queries live snapshot view (#149)
- Add --help/-h flag to CLI installer showing usage, options, env vars, and exit codes - Fix Lite status bar text from gray (ForegroundMutedBrush) to white (ForegroundBrush) for readability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CLI --help flag and fix Lite status bar text (#111)
Phase 1: ShowPlanXML rendering as interactive operator graph in a new Plan Viewer tab. Right-click any query row → View Estimated Plan to parse and display the plan inline (fetches on-demand when needed). - LINQ-to-XML parser with cost computation, warnings, missing indexes - SSMS-style layout: left-to-right with first-child horizontal spine - 113 MIT-licensed operator icons from vscode-mssql - Synthetic SELECT/INSERT/UPDATE/DELETE root node - Rich tooltips, zoom/pan, save .sqlplan, multi-statement selector - Missing index banner with CREATE INDEX suggestions - Warnings banner (spills, implicit conversions, no join predicate) - View Actual Plan menu item stubbed for Phase 2 (query execution) Tested on sql2022 with TPC-H plans. Both apps build clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add collapsible properties panel (right-side, GridSplitter) with node selection - Add rich tooltips with costs, rows, I/O, predicates, output columns - Parse ~30 new operator properties: OrderBy, GroupBy, DefinedValues, OuterReferences, join columns, adaptive join, extended I/O stats, scan hints (ForcedIndex/ForceScan/ForceSeek/NoExpandHint), etc. - Fix XML scoping bug: ScopedDescendants() prevents child RelOp property leakage (seek predicates, object names no longer bleed to parent operators) - Fix EstimatedRowsRead/TableCardinality parsing (attributes are on RelOp, not the physical operator element) - Fix DefinedValues to include column-only entries (no scalar expression) - Gate Statement Memory Grant and Statement Info to root node only - Always show boolean properties (Ordered, ForceScan, etc.) for scan/seek ops - Always show I/O/CPU costs, rebinds/rewinds, estimated executions - Add node context menus (Properties, Copy Operator/Object/Predicate) - Statement-level metadata: CE version, DOP, compile stats, query hashes Both Dashboard and Lite updated and tested against SSMS properties output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nt_complete type cast (#234) - UNION ALL → UNION ALL BY NAME in archive views so schema migrations don't break parquet unions (query_snapshots grid was empty) - Lazy<HashSet<string>> for ignored wait types to prevent concurrent HashSet corruption when multiple servers collect in parallel - Convert.ToDecimal for percent_complete (dm_exec_requests returns real, not decimal) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-union-234 Fix archive view column mismatch, wait_stats thread-safety, percent_complete cast, status bar color
Parse all operator-specific attributes per ShowPlan XSD schema: - RelOp: Partitioned, IsAdaptive/AdaptiveThresholdRows/EstimatedJoinType (fixed: these are on <RelOp>, not the physical operator element) - IndexScan: Lookup, DynamicSeek - NestedLoops: Optimized, WithOrderedPrefetch, WithUnorderedPrefetch - Sort: Distinct - Filter: StartupExpression - Top: WithTies - Hash: BitmapCreator - Parallelism: Remoting, LocalParallelism Fix Lite ViewEstimatedPlan_Click missing switch cases: - ProcedureStatsRow: fetch via FetchProcedurePlanOnDemandAsync - QueryStoreRow: fetch via FetchQueryStorePlanAsync Both apps build clean, properties panel displays all new attributes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xunit is deprecated, they reccomend using xunit.v3 instead.
warning xUnit1051: Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
Wave 1 bug fixes: StatementEstRows int→double, IsMemoryGrantFeedbackAdjusted bool→string (shows actual feedback status), CE version read from StmtSimple. Wave 2 high priority: Merge/NL residual+PassThru predicates, stale stats warning, per-operator memory grants, MaxQueryMemory, Parallelism HashKeys, Top offset/rows, QueryPlan-level warnings. Wave 3 medium priority: EffectiveDOP, MemoryFractions, RunTimePartitionSummary, PlanGuide/UsePlan, ParameterizedText, QS hints, enhanced spill details, Spool stack/PrimaryNodeId, Update DML sort/ActionColumn, columnstore segment stats, UDF timing, TraceFlags, IndexedViewInfo, EstimatedDOP per-operator. Wave 4 structural: StmtCond (IF/ELSE recursive parsing), StmtCursor with cursor metadata and operation sub-plans. All changes applied to both Dashboard and Lite. Both build clean, 0 errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update nuget again
…etention (#237) The data retention procedure now reads retention_days from config.collection_schedule for each table instead of using a hardcoded 30-day value. Direct name matching handles most tables; special mappings cover HealthParser, blocking_BlockedProcessReport, and deadlocks tables. The @retention_days parameter remains as a fallback for unmatched tables. The SQL Agent job step no longer passes @retention_days = 30, letting the procedure use per-collector settings by default. Tested on sql2022: query_snapshots used 10-day retention, running_jobs used 7-day retention, batch deletion confirmed working with @batch_size = 1000. Closes #237 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tention-237 Use per-collector retention from collection_schedule (#237)
…rties-copyable Issue #269: Make plan viewer properties copyable
…ltips - Add 3 missing columns to Query Trace Patterns grid (AvgWrites, Recommendation, QueryPattern with tooltip) - Remove redundant SampleQueryText column (duplicate of QueryPattern) - Create TracePatternHistoryWindow drill-down showing individual executions of a pattern over time - Add GetTracePatternHistoryAsync with ROW_NUMBER dedup (trace events collected multiple times) - Add hover tooltips to all query text columns across Dashboard (matching Lite behavior) - Make DarkToolTip the implicit default so tooltips use dark theme - Switch query text cells from single-line ellipsis to TextWrapping with MaxHeight=90 - Remove fixed RowHeight from grids with query text so rows auto-size Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…pattern-drilldown Issue #273: Trace pattern drill-down, missing columns, query text tooltips
…harts Both apps now collect from dm_exec_query_resource_semaphores (previously Lite used dm_exec_query_memory_grants). Added two new per-pool charts to the Memory Grants sub-tab in both apps: Sizing (available/granted/used MB) and Activity (grantees/waiters/timeouts/forced grants). Dashboard: simplified collector by removing inline OUTER APPLY delta, added memory_grant_stats to the proper delta framework (calculate_deltas), removed unused warning columns, added upgrade script for 1.3.0-to-2.0.0. Lite: new DuckDB schema (v14 migration), DeltaCalculator seeding for timeout/forced counters, new Memory Grants sub-tab with two ScottPlot charts. Also includes waiting_tasks collector simplification. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-grant-charts Issue #281: Standardize memory grant stats and add charts
…ued I/O overlay
**New features (both apps):**
- Add "File I/O Throughput" sub-tab with read/write MB/s charts per file
- Restructure "File I/O" tab into "File I/O Latency" and "File I/O Throughput" sub-tabs
- Add queued I/O overlay (dashed lines) to latency charts showing OS queue wait time
**Lite-specific:**
- Switch File I/O latency charts from database-level to file-level (top 10 by activity)
- Add io_stall_queued_read/write columns to DuckDB schema (v15 migration)
- Update collector to collect queued stall data from sys.dm_io_virtual_file_stats
- Use DuckDB LAG() window function for throughput MB/s interval calculation
**Dashboard-specific:**
- Fix double-brace interpolation bug in GetFileIoThroughputTimeSeriesAsync
({{dbFilter}}/{{dateFilter}} produced literal text instead of interpolating variables)
**CI fix:**
- Update 50_configuration_issues_analyzer.sql and 97_test_procedures.sql to remove
references to warning columns dropped from collect.memory_grant_stats in Gap 1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… Lite Both apps now have a "Current Waits" tab next to the Blocking/Deadlock Trends tab, showing two charts from collected waiting_tasks data: - Wait Duration by Wait Type: multi-series line chart of total wait_duration_ms per wait type over time (raw point-in-time values, not deltas) - Blocked Sessions by Database: multi-series line chart of session count with blocking_session_id > 0 per database over time Also aligns Lite collector with SQL Server collector from issue #281 — stops collecting resource_description (now passed as NULL to match the trimmed-down SQL Server collector which only populates session_id, wait_type, wait_duration_ms, blocking_session_id, and database_name). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt-waits Issue #280: Add Current Waits charts to Blocking tab
Remove collect.session_wait_stats entirely — table, collector procedure, reporting view, schedule entries, schema metadata, CI checks, and all references. This collector had 12 columns and zero UI in either app. Adds cleanup DROPs to 02_create_tables.sql so existing installations get cleaned up on upgrade (drops view, procedure, table, schedule row). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-grant-charts Issue #281 Gaps 1+2: Memory grant charts + File I/O throughput/latency/queued overlay
… and Lite Add chart right-click context menu to all 21 Lite charts (Copy Image, Save Image As, Open in New Window, Revert, Export CSV) with descriptive filenames using yyyy-MM-dd_HH-mm-ss timestamp format. Consolidate Dashboard's duplicate SetupChartSaveMenu into the shared TabHelpers.SetupChartContextMenu, and add context menus to the 2 Current Waits charts that had none. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-export Issue #284: Standardize chart save/export filenames
…e_on sys.databases.is_query_store_on can be out of sync with reality on Azure SQL DB, reporting 0 when Query Store is actually enabled. Replace the filter with a per-database check against sys.database_query_store_options.actual_state, which reflects the true state. The EXISTS pattern handles empty views, NULL, and disabled states cleanly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tection Issue #287: Use database_query_store_options for QS detection
…and query store grids Gap #6: Add 4 memory summary fields (available physical, total/available page file, memory model) Gap #7: Add 9 procedure stats columns (min/max reads, physical reads, writes, spills, cached time) Gap #9: Add 9 query store columns (exec type, first execution, CLR, tempdb, log bytes, plan type, force failures, compat level) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…m-gaps Issue #281: Surface hidden columns in memory, procedure, and query store grids
…ore gaps, improve collector health logic Query Stats: Add min/max physical reads, rows, grant KB, spills to Lite grids. Add min/max physical reads to Dashboard query stats main grid. Procedure Stats: Add min/max logical reads, physical reads, logical writes, spills to Lite grid. Query Store: Wire 3 broken XAML bindings (ForceFailureCount, LastForceFailureReasonDesc, PlanForcingType), add 6 hidden columns (CLR time, num physical IO reads, log bytes), add min memory/tempdb MB display. Collector Health: Add consecutive failure detection to report.collection_health view — 5+ recent errors = FAILING, 3+ = WARNING, regardless of 7-day percentage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ry-grant-charts # Conflicts: # Lite/Controls/ServerTab.xaml # Lite/Services/LocalDataService.QueryStats.cs
…-grant-charts Issue #281 Gap 3: Min/max extremes, Query Store gaps, collector health
The two throughput charts (FileIoReadThroughputChart, FileIoWriteThroughputChart) were missed when wiring up custom context menus, showing ScottPlot's default menu. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…m-gaps Fix missing chart context menu on File I/O Throughput charts
- Bump all 4 csproj versions to 2.0.0 - Add comprehensive CHANGELOG entry for 2.0.0 - Add session_wait_stats cleanup upgrade script - Fix silent plan button failures (6 handlers across Dashboard and Lite) - Add CPU scheduler pressure status below CPU chart - Fix server timezone race on first tab open (fetch offset synchronously if background check hasn't completed yet) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Release prep v2.0.0
- Fix TRUNCATE TABLE using three-part name to avoid master context error when --reset-schedule is used (both CLI and GUI installers) - Fix Version comparison bug: normalize to 3-part versions to avoid Revision=-1 vs Revision=0 mismatch breaking upgrade detection (both installers) - Fix GUI installer upgrade detection: use AppAssemblyVersion instead of AppVersion (which includes +commithash suffix that breaks Version.TryParse) - Add SQL Agent job cleanup (all 3 jobs) to Dashboard's DropMonitorDatabaseAsync so removing a server doesn't leave orphaned erroring jobs - Update RemoveServerDialog text to mention Agent job removal Tested: fresh install, v1.3.0→v2.0.0 upgrade, and idempotent re-run on sql2016 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and-agent-cleanup Fix installer upgrade bugs and add Agent job cleanup
The GUI installer was missing from v1.3.0 release because the publish step produced 280 loose files but only the exe was copied to the release zip. Without its DLLs, the exe would crash on launch. Add PublishSingleFile, SelfContained, and related properties to match the CLI installer csproj. Remove now-redundant flags from build.yml. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-file Fix GUI installer: publish as single-file self-contained exe
SQL collector was missing 14 counters that sp_PressureDetector collects and the UI packs reference. TempDB Pressure pack only showed Forwarded Records/sec (which isn't even a tempdb counter) because the 8 actual tempdb counters were never collected. Also missing: Full Scans/sec, Index Searches/sec, Page Splits/sec, Free list stalls/sec, Processes blocked, Lock Timeouts/sec. Remove Forwarded Records/sec from TempDB Pressure pack in both apps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ters Add missing perfmon counters to SQL collector, fix TempDB Pressure pack
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.
Summary
v2.0.0 release — 93 commits since v1.3.0. Major additions across Dashboard, Lite, and Installer.
New features
database_query_store_options(Issue [FEATURE] Don't rely on sys.databases.is_query_store_on #287)Bug fixes
Improvements
Test plan
🤖 Generated with Claude Code