AG fixture: land the suspended-row evidence, and correct the lag latch claim (#991) - #1707
Merged
Merged
Conversation
…ag claim #1702 and #1703 both cite tools/ag-fixture/VALIDATION.md for how a suspended row behaves, and the file did not contain the measurements behind several of those claims. This lands them. It also corrects something I got wrong in #1704. I wrote that secondary_lag_seconds "only latched at the +30s sample", which implied a short bounded window. ag-alerts-builder measured it never latching across a whole 60s suspension on a quiet group, and I reproduced that independently here: 0 at every sample through a full 60-second suspension, already NOT SYNCHRONIZING, with the last hardened log ~29 minutes stale. One earlier idle run latched at +30s and these did not, so the timing is not dependable in either direction. The file now says so, and states the consequence plainly: a lag threshold alone cannot detect suspended data movement on a quiet group. Also added, with sample tables from a loaded run and an idle one: - All four *_time columns freeze at their last pre-suspension instant, so a cross-replica commit-time delta stops growing exactly when replication stops - the opposite direction from secondary_lag_seconds. - redo_queue_size freezes rather than growing. - est_redo_completion_time_min is the sharpest edge: queue over rate with both frozen holds a small static reassuring number for the whole suspension (0.0144 min loaded, 0 idle), so a suspended replica looks healthier than a working one. - last_received_time read NULL in every sample on both runs. - last_commit_time is not a heartbeat - measured 1757 seconds behind wall clock on a SYNCHRONIZED, non-suspended, zero-lag replica, purely because the database was quiet. Loaded-run table is ag-collector-builder's; the idle run and the never-latch reproduction are mine. Evidence file and CHANGELOG only, no code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The PR came out as 1707, not the 1705 predicted at write time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
erikdarlingdata
enabled auto-merge
July 26, 2026 20:00
pull Bot
pushed a commit
to ehtick/PerformanceMonitor
that referenced
this pull request
Jul 29, 2026
Non-executable changes now skip .NET setup, restore and versioning in the required build job. The job still RUNS, so the check reports a result and cannot go missing and block a merge. The gate is an explicit ALLOWLIST of non-executable content, not a subtraction of known-code paths: **/*.md, LICENSE, CITATION.cff, .gitignore, .gitattributes, docs/**, Screenshots/**. An unfamiliar new file type therefore defaults to being treated as code, which is the safe direction to be wrong in. Deliberately NOT in the allowlist: *.sql (the installer and sql-validation compile it), *.yml (workflows), *.csproj / *.props / packages.lock.json (build inputs), and *.cs however comment-only a change looks - an XML doc comment still recompiles, and the compiler is what proves it still builds. Two guards against silently under-building: - The fast path never engages on a release event, or on a push to dev/main. Those restore unconditionally. Note this only forces the RESTORE back on; the per-product build/test steps stay path-gated exactly as before, so push times are unchanged for code commits. - Both jobs emit a ::notice:: naming why they took the path they took, and the build job lists the files it classified as documentation. A job reporting success having quietly run nothing is otherwise indistinguishable from one that tested everything. On what this actually fixes: markdown-only changes were ALREADY skipping every heavy step - erikdarlingdata#1707 was pure .md and its build ran in 1m43s, which is checkout and the paths filter with nothing after it. The real gap was non-markdown documentation, which matched the '**' catch-all in the code filter and paid a six-project locked-mode restore to compile nothing. The remaining ~1m45s floor is actions/checkout on a Windows runner and is not something this gate can remove. The docs allowlist and the code filter's exclusions are the same list stated twice - paths-filter has no "not in that other filter" operator - so they carry a comment to keep them in step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Evidence file and CHANGELOG only, no code. Two files.
#1702 and #1703 both cite
tools/ag-fixture/VALIDATION.mdfor how a suspended row behaves, and the file did not contain the measurements behind several of those claims. This lands them - and corrects one of mine.Correction to #1704
I wrote that
secondary_lag_seconds"only latched at the +30s sample", which implied a short bounded window. That was too generous. @ag-alerts-builder measured it never latching at all across a full 60-second suspension on a quiet group, and I reproduced it independently rather than take it on report:Zero at every sample, already
NOT SYNCHRONIZING, last hardened log ~29 minutes stale. One earlier idle run latched at +30s and these did not, which is the actual lesson: the timing is not dependable in either direction and nothing should be built on it.Stated plainly in the file now, because the intuitive assumption is the opposite:
The dedicated suspended-state alert owns that case. This is what makes #1700's "a sub-threshold reading on a suspended row is never caught up" load-bearing for a far more common scenario than the inverted-docs one it was written for.
Also landed (new section 6b)
With sample tables from a loaded run and an idle one:
*_timecolumns freeze at their last pre-suspension instant, so a cross-replica commit-time delta stops growing exactly when replication stops - understating the problem at the moment it is worst, the opposite direction fromsecondary_lag_seconds.redo_queue_sizefreezes (21896 KB flat) rather than growing.est_redo_completion_time_minis the sharpest edge. Queue over rate with both frozen holds a small static reassuring value for the whole suspension - 0.0144 min under load, 0 when idle - so a suspended replica looks healthier than a working one.est_send_drain_time_minat least reads NULL.last_received_timeread NULL in every sample, healthy and suspended alike, on both runs. Optional rather than expected.last_commit_timeis not a heartbeat. Measured 1757 seconds behind wall clock on aSYNCHRONIZED, non-suspended, zero-lag replica, purely because the database was quiet. Sonow - last_commit_timeis not a lag measure - on a healthy idle replica it grows without bound, and anything alerting on it pages about an idle database. This one bites on healthy replicas, not just suspended ones.The summary table at the top is updated so it no longer contradicts any of this.
Attribution
The loaded-run table is @ag-collector-builder's, supplied as raw data; the idle run, the never-latch reproduction, and the
last_commit_timebaseline are mine. @ag-alerts-builder found the never-latch case first.Test plan
*_timefreeze,last_received_timeNULL, and thelast_commit_timegap all confirmed in my own idle run as well.[#1702]/[#1703]refs, no conflict markers.CHANGELOG.md+tools/ag-fixture/VALIDATION.md- no collector or app code, so it cannot conflict with anything in flight.Fixture left as found: both replicas
SYNCHRONIZED,is_suspended = 0, healthy.🤖 Generated with Claude Code