Release v2.11.0#965
Merged
Merged
Conversation
GitHub will force JS actions to Node 24 on June 2nd, 2026, and remove Node 20 from runners on September 16th, 2026. Bumps the four actions called out in the runner deprecation warning: - actions/checkout v4 → v5 - actions/setup-dotnet v4 → v5 - actions/upload-artifact v4 → v6 - signpath/github-action-submit-signing-request v1 → v2 Matches the bump PerformanceStudio just made for the same reason. dorny/paths-filter@v3 not in the warning, left as-is. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI: bump actions to Node 24-compatible majors
PR #905 wired config.collector_database_exclusions into the 8 collectors that iterate sys.databases, but missed default_trace_collector and trace_analysis_collector because they filter trace events by DatabaseID/DatabaseName rather than looping sys.databases. - 29_collect_default_trace.sql: NOT EXISTS against config.collector_database_exclusions joined to sys.databases to translate the exclusion list (by name) into ids matching ft.DatabaseID. - 31_collect_trace_analysis.sql: NOT EXISTS directly on trc.DatabaseName (trace exposes the name here). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tor-exclusions Honor collector_database_exclusions in default trace and trace analysis collectors (#887 follow-up)
The in-memory DuckDB connections used for parquet compaction had a 4 GB memory_limit pragma but no temp_directory, so the cap acted as a hard wall — DuckDB had nowhere to spill and OOM'd the moment it was hit. Co-locate the spill dir with the archive folder so the writes land on the same volume as the parquet files. Verified end-to-end: 4-server HammerDB load, second 512 MB reset triggered ArchiveAllAndResetAsync, all 21 groups went through the multi-file pair-merge path with two sources each, completed in ~3.5s with no OOM. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…emp-directory Lite: fix compaction OOM by setting DuckDB temp_directory (#933)
#936) Servers that crossed 2.4 -> 2.5 before PR #828's USE-statement fix shipped in v2.7.0 ran the widen script as a no-op against master and advanced their installer_version past 2.5. The upgrade filter (ToVersion > current) then permanently skipped the now-fixed script, leaving sql_server_version and sql_server_edition stuck at nvarchar(255) -- which truncates SQL 2022+ @@Version strings (~260 chars) on every install attempt. Re-applies the same idempotent widen in 2.10.0-to-2.11.0 so any server upgrading to the next release picks it up. The IF EXISTS guards on max_length = 510 mean already-widened servers skip both ALTERs. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
) PR #919 / #921 / #922 addressed the WPF Popup wedge but missed the underlying bug: MemoryContent, ResourceMetricsContent, and QueryPerformanceContent all called DisposeChartHelpers() from their per-control Unloaded event handler. WPF fires Unloaded on every TabControl tab switch, not just on destruction, so switching away from the Memory tab unsubscribed every chart's MouseMove handlers — which were never re-registered when the user came back. The popup-wedge fixes were running inside helpers that had already torn themselves down. ServerTab_Unloaded had the same comment warning future maintainers, but the inner UserControls didn't follow that rule. Changes: - MemoryContent / ResourceMetricsContent / QueryPerformanceContent: drop DisposeChartHelpers() (and ThemeManager unsubscribe) from the tab-switch Unloaded handler. Move the ThemeManager unsubscribe into DisposeChartHelpers() so it runs only on real cleanup. - SystemEventsContent: same pattern — add a DisposeChartHelpers() method that disposes the 19 hover helpers, unsubscribes filter-popup events, and unsubscribes ThemeManager. Empty out OnUnloaded. - ServerTab.CleanupOnClose: add SystemEventsContent.DisposeChartHelpers() to the cleanup chain (its hovers leaked on tab close before this). Final disposal still happens correctly via ServerTab.CleanupOnClose, which only fires when a server tab is actually removed. Lite is unaffected — its Unloaded handler never disposed hovers. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When monitor.duckdb exceeds 512 MB, ArchiveAllAndResetAsync deletes the file and reinitializes empty tables. config_mute_rules was not in ArchivableTables, so all mute rules — including permanent rules with expires_at_utc = NULL — were silently lost. Export config_mute_rules and dismissed_archive_alerts to a temp Parquet dir before the reset and re-import after. Parquet roundtrip keeps this schema-agnostic. On restore failure, the temp dir is retained for manual recovery. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…urvive-reset Fix #938 — preserve mute rules across size-triggered DB reset
#935 added temp_directory so DuckDB could spill, but on wider workloads the working set still blew past the 4 GB cap before spill caught up (reporter saw OOM at 3.7 GiB compacting 15 query_snapshots files). Three knobs combined to feed that: - memory_limit = 4 GB was too high — DuckDB held off spilling until late - threads defaulted to N cores, multiplying per-thread row-group buffers - ROW_GROUP_SIZE 122880 buffered up to 122k wide-VARCHAR rows per group Drop memory_limit to 1 GB, cap threads to 2, and shrink ROW_GROUP_SIZE to 8192. On 1.7 M rows of real query_stats data this drops peak working set from 1236 MB → 166 MB (87% reduction) at a 31% wall-time cost. Memory now plateaus instead of growing with row count, which is the load-bearing change for issue #933. Adds tools/CompactionRepro — a standalone reproducer that splits a real monthly parquet file into N per-cycle-shaped chunks and runs the same pair-merge logic with the tuning knobs exposed on the command line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…emory-tuning Fix #933 — bound compaction memory so wide-row tables don't OOM
Replaces the standard non-interactive Windows toast for the seven fired alerts (CPU, Blocking, Deadlocks, Poison Wait, Long-Running Query, TempDB Space, Long-Running Job) with a custom WPF balloon that has "Snooze 15m / 1h / 4h" + "Dismiss" buttons. Snoozing creates a temporary mute rule scoped to ServerName + MetricName with the chosen expiration, which the existing alert-fire path already honors for both email and Teams/Slack webhook delivery. Status notifications (Online/Offline + 7 Cleared/Resolved) keep using the standard non-interactive balloon since there's nothing to snooze. Addresses the firefighting workflow described in #943. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tray-popup Fix #944 — one-click snooze from alert tray popup
Adds a one-line discoverability footer to alert delivery channels other than the desktop popup, since neither email nor webhooks can round-trip a click back to a desktop process: "To silence this alert: open Performance Monitor Lite → Settings → Manage Mute Rules" Placed in the email HTML footer (under the cooldown line), the plain-text body tail, the Teams MessageCard (a small section after the facts), and the Slack context block at the bottom of the message. Suppressed on test deliveries so the test card stays minimal. Pairs with the snooze popup from #946 to close out #944. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…in-email-webhook Fix #944 — snooze hint in email and Teams/Slack payloads
Lite went from 190 warnings to 0, Dashboard from 3 to 0, Installer was
already clean. Total fixes:
- Add repo-root .editorconfig suppressing CA1873 ("potentially expensive
logging") with rationale. This rule fires on every non-literal
argument to a logging method including trivial field accesses, which
accounts for ~97% of Lite's warning count and is pure noise — the
cost the rule warns about is consistently negligible. Proper fix is
migrating to LoggerMessage source generators, tracked separately.
- Lite/Controls/CorrelatedTimelineLanesControl.xaml.cs: guard against
null .Result on completed comparison-data tasks before passing to
.Select() (CS8604 ×2). The author already wrote `?.Count ?? 0` for
the same fields elsewhere, so null was anticipated; the .Select calls
just missed the guard.
- Lite/Mcp/McpAnalysisTools.cs: tighten FormatBaselineContext return
type from object? to Dictionary<string, object>?, removing the
unnecessary boxing (CA1859).
- Dashboard/ServerTab.Plans.cs: discard the bool returns from three
int.TryParse calls with `_ =`, making the "ignore failure, use
default 0" intent explicit (CA1806 ×3). Behavior unchanged —
TryParse already sets the out param to default on failure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…gs-cleanup Fix #945 — clean up build warnings (Lite 190→0, Dashboard 3→0)
The standalone InstallerGui was retired in #755 — its functionality folded into the Dashboard's Add Server dialog and the new Installer.Core shared library. The .sln no longer references it, but the source directory was left on disk. Cleaning that up: removes the dead source, eliminates a stray CS8604 warning that was only surfaced when building the project directly, and keeps the repo lean. CHANGELOG already documented the retirement; no docs changes needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Delete retired InstallerGui project directory
The Blocking, Memory, and IO branches in the comparison overlay section of CorrelatedTimelineLanesControl were missing the `&& Result != null` guard the CPU and Wait branches already had. Apply uniformly so a null result from `_dataService.Get*TrendAsync` can't NRE on the subsequent .Select / .GroupBy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…l-guards Add nullability guards to comparison overlay tasks
#942 lowered the cap to 1 GB on the theory that a tight memory_limit plus temp_directory would force DuckDB to spill earlier and keep peak working set down. That validation ran against query_stats (narrow, ~1.7M rows) and showed peak 1236 MB → 166 MB. The reporter's actual failure is on query_snapshots, which carries query_text + query_plan + live_query_plan per row. With the 1 GB cap, the nightly logs show OOM at "906/953 MiB used" before any merge progress. The standalone reproducer (tools/CompactionRepro) confirms the cause: parquet COPY in DuckDB v1.5.2 makes allocations that bypass the buffer manager and can't be spilled. The cap acts as a hard ceiling for those, not a spill trigger. Spill on disk = 0 MB across every configuration we tested (memory_limit 1/2/4 GB, accumulator vs tournament merge, threads 1 vs 2, :memory: vs file-backed DB). The same failure reproduces in standalone DuckDB CLI v1.5.2, so it's an engine issue — see upstream issues duckdb#16482 and discussion#10084. DuckDB's own OOM guide explicitly warns about this case and recommends memory_limit at 50-60% of system RAM, not a tight cap. 4 GB sits well inside that range for typical workstation/server hosts and leaves real headroom on top of the un-spillable allocations. Reporter's actual file sizes (15-25 chunks of 2-6 MB plus a 35-45 MB monthly file per group) are well below the level where 4 GB has any trouble. The reproducer confirms 4 GB succeeds on a synthetic query_snapshots-shaped dataset of ~1.5 GB with peak working set of ~400 MB; the reporter's data is ~143 MB at worst. Also updates the stale comment about spilling — temp_directory was set per #935 but the buffer-manager-bypassing allocations don't use it. The comment now describes what actually happens. The tools/CompactionRepro changes add --strategy {accumulator|tournament}, --db-mode {memory|file}, --merge-files, --synthetic data generation, and --cycles for leak testing. These are kept so a future regression in this area can be reproduced and diagnosed quickly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
config.data_retention only purged rows from collect.* tables, leaving
the .trc files written by collect.trace_management_collector to
accumulate forever in the SQL Server error log directory. Reporter saw
~7 GB / 106 files going back 2 months on a busy server.
Adds a trace file cleanup block to config.data_retention that:
- reads retention_days from config.collection_schedule for
trace_management_collector (30-day fallback), honoring the same
@retention_days override semantics as the table cleanup above it
- derives the error log directory via SERVERPROPERTY('ErrorLogFileName')
the same way collect.trace_management_collector does
- pre-checks via xp_dirtree to skip xp_delete_file when no matching
files exist, suppressing the "Msg 22049" noise xp_delete_file prints
on empty matches
- calls master.dbo.xp_delete_file to delete files older than the cutoff
(active trace file stays locked open, so it survives)
- TRY/CATCH treats Msg 22049 as benign (no files needed cleanup) on
older SQL versions where it surfaces as a catchable error
- logs a separate config.collection_log row so trace cleanup is auditable
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ion-memory-limit Fix #933: raise compaction memory_limit to 4 GB
…leanup Fix #951 — clean up Monitor_LongQueries_*.trc files in data_retention
CompactParquetFiles detected CompactionExcludeColumns once, globally, across the union schema of every source file in a group. It then applied that "* EXCLUDE (col)" clause to each pair in the pairwise merge. query_plan_text was added to query_store_stats in migration v13 (2026-02-23). A reporter's archive contains both pre-v13 files (no column) and post-v13 files (column present). The global DESCRIBE saw the column in the newer files, so every merge step ran with "* EXCLUDE (query_plan_text)" — including the steps that merged two pre-v13 files, which fail with: Binder Error: Column "query_plan_text" in EXCLUDE list not found in FROM clause Extract the schema detection into BuildSelectClause(table, paths) and call it per merge-set instead of once globally — with the actual pair in the pairwise path, and with all sources in the small-group path. A pair that doesn't carry an exclude-column now merges with a plain "*". Verified against DuckDB CLI v1.5.2: DESCRIBE of an [old, old] pair correctly omits the column, and "* EXCLUDE (query_plan_text)" on that pair reproduces the reporter's exact Binder Error. Cost is one extra DESCRIBE per merge step — parquet footer reads, not data. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#933's titled complaint is "Memory usage on client": Lite holds ~2.7-2.9 GB after 10 minutes with 4 servers. The compaction OOMs everyone has been chasing in this thread are a downstream symptom — by the time compaction runs the app already holds 2.7 GB, leaving little headroom on the reporter's 16 GB / ~1.6 GB-free machine. Root cause: the main DuckDB ConnectionString set no memory_limit, so the buffer pool ran at the DuckDB default of 80% of system RAM (~12.8 GB on a 16 GB box). With archive parquet files accumulating on disk, every UI query over an archive view caches pages and the buffer pool grows freely. The fix has to navigate one wrinkle: parquet COPY in DuckDB v1.5.2 hits a buffer-manager-bypass pre-reservation that needs ~2-4 GB headroom. Capping the main connection at 1 GB statically would break ExportToParquet and the two COPY paths in ArchiveAllAndResetAsync. So: - ConnectionString: memory_limit=1GB (caps resting buffer pool — addresses the actual complaint by stopping the archive-page cache from growing unbounded). - Around each parquet COPY on the main connection: SET memory_limit='4GB', run the COPY, SET back to '1GB'. Factored into a WithRaisedCopyMemoryLimit helper so the three call sites stay consistent (ExportToParquet, and the two COPYs in ArchiveAllAndResetAsync). - Compaction connections (separate :memory: instances) keep their 4 GB cap from #952. Verified against DuckDB CLI v1.5.2 with synthetic query_snapshots-shaped data: - COPY table→parquet at 256MB/512MB/1GB: OOMs (pre-reservation, matches the read_parquet→parquet path we saw in #952 testing). - COPY table→parquet at 2GB/4GB: succeeds, peak RSS well under cap. - INSERT (Appender) and SELECT (including GROUP BY across 11k rows) work fine at 256MB cap — confirms collectors and UI queries don't have the pre-reservation behavior and aren't affected by the resting cap. Tradeoff: the resting cap forces buffer-pool eviction of cached archive parquet pages. Long-range historical UI queries that re-scan many parquet files will do more disk I/O. Live/recent-data queries against the hot DB are unaffected (hot DB is small enough to fit in 1 GB easily). Plus the per-merge-step BuildSelectClause from the previous commit fixes the separate query_store_stats Binder Error on archives that span the v13 schema change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…inder-and-adaptive-memory Fix #933: cap main DuckDB memory_limit, per-pair compaction exclude detection
Lite has had no internal record of its own memory usage. Bug reporters (see #933) had to read it off Task Manager, and we had no historical trace for diagnosing growth patterns. After every collection cycle — which is also after archival and retention run, so it captures the quiescent state — log: Process memory: WS=XXX MB, Private=XXX MB, GC heap=XXX MB WS is Working Set (what Task Manager shows). Private is private bytes (unique to this process, the more honest "actual RAM cost" number). GC heap is .NET-managed memory only — together with WS-Private this splits managed vs native vs shared. One INFO log line per minute. Three property reads — negligible overhead. Errors swallowed at DEBUG level (don't ever break the collection loop because we couldn't read memory stats). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ry-per-cycle Log process memory at the end of each collection cycle
After PR #955 the main connection cap and Binder fix landed, but the reporter's next nightly hit a different failure mode: query_snapshots compaction OOM'd at "failed to pin block of size 102.9 MiB (3.6 GiB/3.7 GiB used)" with a 72-file backlog. Not the pre-reservation bug — DuckDB has legitimately consumed nearly the full 4 GB cap doing real work. Wide-VARCHAR plan XML expands ~10x on read; merging 72 files into a single COPY needs more than 4 GB in memory. The existing pairwise merge accumulates: by step 70 of 72, the accumulator is the merge of 71 files combined being read alongside one more. Bounded if file count is bounded; unbounded otherwise. This change caps a merge by total on-disk input bytes, not file count: - BuildSizeBudgetedBatches greedily groups smallest-first-sorted paths into batches whose total bytes don't exceed MaxBatchInputBytes (200 MB). - A group that fits in one batch keeps the existing YYYYMM_table.parquet output name — fully backward compatible. - A group that needs multiple batches produces YYYYMM_table_ptNNN.parquet part files (numbered from 001). Archive views already glob *_table.parquet, so readers see all parts as one logical month. - New regex case in the file-recognition pass recognizes _ptNNN suffixes so subsequent compactions round-trip part files correctly. - MergeBatchToFile factors out the single-pass-vs-pairwise logic so each batch is a standalone call; the cleanup orchestration (delete originals, promote temps) runs once after all batches succeed. For the reporter's specific 72-file backlog at ~5 MB each (~360 MB total), this produces roughly two batches of ~36 files each. Memory demand of each batch is half what the un-batched merge needed, well within the 4 GB compaction cap. Naturally adaptive: narrow tables (wait_stats, perfmon_stats) fit hundreds of files per batch; wide tables (query_snapshots, query_store_stats with plan XML) get fewer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump TargetFramework to net10.0 / net10.0-windows across all 7 projects, update CI workflows and build scripts, and refresh Microsoft.Extensions.* / System.Text.Json / ModelContextProtocol / Microsoft.NET.Test.Sdk to their current versions. Removes the explicit System.Text.Json reference from Lite since .NET 10 ships it in-runtime (NU1510). packages.lock.json files regenerated via --force-evaluate; transitive dependency lists shrank ~30% thanks to .NET 10 package pruning. Build: 0 warnings, 0 errors. Lite.Tests: 260/260, Installer.Tests fast filter: 27/27. .NET 8 LTS support ends 2026-11-10; .NET 9 already ended 2026-05-12. .NET 10 is LTS through 2028-11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Upgrade to .NET 10 (#958)
…ize-budget-batching Compact parquet in size-budgeted batches (#933 followup)
Tester feedback: after running the bare-ZIP "install" the app didn't
appear in Start Menu / Apps & Features, and a second DBA on the same
machine couldn't see the server list the first DBA had configured.
Installer:
- Drop the Dashboard/Lite portable ZIPs from CI and local build scripts.
Velopack Setup.exe stays as the only Dashboard/Lite release artifact;
its defaults already create Start Menu + Desktop shortcuts and register
the app under HKCU\...\Uninstall (so it shows in Apps & Features).
- Keep the Installer ZIP (it bundles the CLI installer + SQL scripts —
a different artifact).
- Update README Quick Start to direct users at Setup.exe with a note
about shortcuts and Apps & Features registration.
Shared server list:
- Move servers.json from %APPDATA%/%LOCALAPPDATA% to
%ProgramData%\PerformanceMonitor{Dashboard,Lite}\ so every Windows
user on the machine sees the same server list.
- On first directory creation, grant Authenticated Users Modify with
container+object inheritance so other users can edit the file.
- One-time migration: if a per-user servers.json exists and no shared
one does, copy old -> new. The legacy file is left in place as a
backup.
- Other config stays per-user — Lite settings.json, schedules,
collector preferences, the DuckDB database, and the Parquet archive
all remain in %LOCALAPPDATA% (collection data is single-instance and
Velopack-managed).
- Credentials remain per-user in Windows Credential Manager: each DBA
will need to re-enter SQL passwords on first connect. Windows Auth
works without re-entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Setup.exe (Velopack) remains the README-promoted install path, but the portable ZIPs are still produced in both the local build scripts and the CI release pipeline (including the signing path) so advanced and air-gapped users have an explicit fallback. The README change made in the previous commit still steers end users at Setup.exe — only the release artifacts and local build outputs change here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
servers.json now lives under %ProgramData% (shared across users); the other Lite config files stay in %LOCALAPPDATA% per-user. Add a Location column to the config table and a short note about the cross-user behavior so the storage split matches the code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ared-server-list Ship via Setup.exe only and share servers.json across users
Today's nightly build on main failed restoring Installer with NU1004: 'Microsoft.NET.ILLink.Tasks version has changed from [10.0.8, ) to [10.0.7, )'. ILLink.Tasks is bundled with the SDK, so its version tracks whatever SDK the runner image happens to ship. The lockfiles were generated against SDK 10.0.204 (runtime 10.0.8); the runner now ships SDK 10.0.107 (runtime 10.0.7), and `--locked-mode` refuses to proceed against the mismatch. global.json tells the SDK host (and actions/setup-dotnet) to use 10.0.204 or higher within the same major.minor — so CI installs the SDK that matches the lockfile instead of inheriting whatever the runner image came with. Local dev and CI now agree on the SDK version, and the only way to bump it is to update global.json and regenerate lockfiles in the same commit. Verified locally: `dotnet --version` → 10.0.204, `dotnet restore --locked-mode` succeeds. Note: dev's nightly.yml is already on 10.0.x. main's still has the .NET 8.0 leftover but that'll clear on the next dev → main release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…globaljson Pin .NET SDK to 10.0.204 via global.json
Bumps Dashboard, Lite, Installer, and Installer.Core to 2.11.0. Drafts the v2.11.0 changelog entry covering the .NET 10 upgrade, Setup.exe-only distribution, shared servers.json location, Lite compaction memory tuning (#933), one-click snooze (#944), trace collector exclusions (#887 follow-up), and the silent rewiden of installation_history version columns for pre-v2.7.0 no-op upgrades (#828). Stamps v2.10.0 with its actual release date (2026-05-04). Tested: - Build clean (0/0) - 46 adversarial Installer.Tests pass - Fresh install on sql2016, upgrades on sql2017/2019/2022/2025 with data survival verified; idempotent re-run on sql2022 - Uninstall path verified (DB dropped, jobs + XE sessions removed) - Cloud: Lite collecting from Azure SQL DB and AWS RDS for 30 min with zero errors; Dashboard installed PerformanceMonitor on RDS via Add Server flow (148 runs, 0 errors) - New process-memory-per-cycle log lines observed in Lite Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Release v2.11.0
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
Release v2.11.0 — promotes 44 commits from
devtomain. See CHANGELOG.md for the full entry.Highlights
Important
Setup.exeonly — portable ZIPs removedservers.jsonmoved to%ProgramData%\PerformanceMonitor{Dashboard,Lite}\(machine-shared)Added
Changed
config.collector_database_exclusions(Per-database exclusions for collectors #887 follow-up)Fixed
installation_historycolumn widening for pre-v2.7.0 no-op upgrades ([BUG] Installation History - Truncation Error #828)Monitor_LongQueries_*.trcfiles cleaned up by data_retention ([BUG] Trace files never get cleaned up #951)Test plan
dotnet build -c Debugclean (0/0)Installer.TestspassAfter merge, tag
v2.11.0and create the GitHub release to trigger the build pipeline.🤖 Generated with Claude Code