Repository navigation
After an outage across an upgrade, the raw purge gate releases within the hour on a running store (#4300) - #4430
Merged
Conversation
… seam within the hour, no second start (#4300)
… a doc pin (#4300) - The interior-hole fixture in SeamOnlyRepair_NeverTouchesAnOrdinaryInteriorHoleOnANonLegacyTarget left a bucket with no source row between two materialized spans, which is legitimately empty, not a hole -- the full walk's sanity assertion failed because there was nothing to repair. Seed a real row in the hole bucket so the full walk actually closes it. - RetentionReevaluationTests: the seam repair's own failure-isolated try/catch (added ahead of the coverage sweep) sits before the outer shutdown/budget/everything-else catches the existing pin checked the order of, and adds a third LogWarning site. Scoped the ordering/no-rethrow check to the outer catches and updated the warning count and text to match. - Added a doc pin (RetentionReevaluationTests) asserting the storage source no longer says the gate needs a SECOND start.
…ath repair runs, and pin its wiring (#4300)
erikdarlingdata
marked this pull request as ready for review
September 26, 2026 16:06
This was referenced Sep 26, 2026
Closed
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.
Refs #4300 (item 1).
Why
The raw-tier purge gate stays held until every hole between a frozen legacy rollup and its successor is repaired. Before this change, the only thing that ever re-ran that repair walk was a full service start — a legacy/successor seam an outage opened across an upgrade would sit un-repaired, and the gate would stay Short, until the store was restarted a second time. A store that keeps running after the upgrade could hold the raw purge indefinitely with no restart in sight.
Why the earlier relaunch doesn't cover this
A prior, related fix (#4391) changed when the periodic repair relaunches the full hole-scan walk, but only when the store's repair-epoch stamp is stale under the current postmaster start. A first start whose repair completed cleanly (0 failures, the successor skipped because it had materialized nothing yet) stamps that epoch, so the periodic pass never relaunches the full walk — #4391 does not cover this seam shape.
What changes
TimescaleSupport.MaterializationHoles.cs: the per-target hole-repair walk is factored into a sharedRepairMaterializationTargetsAsync, with a newRepairMaterializationSeamsAsync— a seam-only variant restricted to legacy-paired targets and their seam window, using the exact same per-target body, cap and failure isolation as the full walk.RepairMaterializationHolesAsyncdelegates to the same shared method unchanged.DarlingWorker.ReevaluateRetentionPoliciesAsync(the hourly Periodic pass) now runs the seam-only repair before the coverage sweep re-judges the gate, so a seam closed this tick is already gone when the gate is re-evaluated a moment later.Test plan
Outage_SeamBetweenFrozenLegacyAndSuccessor_SingleStart_HourlySeamRepairReleasesTheGateand adapted to what dev's hourly pass actually does (onlyEnsureRetentionPoliciesAsync, no repair of any kind —RepairMaterializationSeamsAsyncdoes not exist on dev), built and run in a detached worktree oforigin/dev: after one start's repair skips the still-empty successor, the successor's first refresh runs on the running service, and a dev-shaped hourly tick (coverage re-judged, no repair in between) is simulated. The assertion that the gate should read Covered fails withon dev, the single-start hourly tick never runs a seam repair, so the gate stays Short— confirmed RED.Outage_SeamBetweenFrozenLegacyAndSuccessor_SingleStart_HourlySeamRepairReleasesTheGatepasses: one start, no restart, the hourly seam-only repair alone closes 7 buckets and the gate reads Covered.SeamOnlyRepair_NeverTouchesAnOrdinaryInteriorHoleOnANonLegacyTargetwas failing on its own trailing sanity check (the full walk should have closed the interior hole the seam-only call left standing) because the fixture's gap had no source row in it — a bucket with nothing in the source is legitimately empty, not a hole, under this repair's own definition of a hole. Seeded a real row in the gap bucket instead of weakening the assertion; now the full walk genuinely closes it and the test passes.RetentionReevaluationTestsreads the storage source (the repo's existingReadStorageSource()helper) and asserts it no longer contains "SECOND start".Worker_ReevaluationMethod_RunsThePeriodicPass_UnderOneBudget_FailureIsolated) now:throw;to the outer shutdown catch fails it (Assert.DoesNotContain() Failure: Sub-string found … "throw"). Restored, it passes.HolesRemaining,BucketsDeferredandFailuresare all 0.FrozenRollupLiveTests24/24,RawPurgeTriggerLiveTests+RetentionReevaluationLiveTests9/9,RetentionReevaluationTests10/10,MaterializationHoleRepairTests20/20,DocCommentHygieneTests77/77.Darling.Tests.csprojandLite.Tests.csprojbuild 0 errors with-p:EnableWindowsTargeting=true;Darling.Tests/Lite.Teststargetnet10.0-windowsand cannot execute on macOS outside the in-process runner used above — CI decides the Windows-only suites.CHANGELOG entry
SECTION: Fixed
ENTRY:
REF:
[After an outage across an upgrade, the raw purge gate releases within the hour on a running store (#4300) #4430]: After an outage across an upgrade, the raw purge gate releases within the hour on a running store (#4300) #4430