Heal the v8 sizing block on stores resized before #4225 (#4207) - #4342
Merged
Merged
Conversation
ShouldAppendHardwareSizing only fired on a fingerprint mismatch, so a store whose hardware has not changed since its last v8 write never retriggers the heal - even when the conf still carries duplicate v8 blocks from the append-not-replace bug, or when the surviving block's content predates a formula change (work_mem rejoining the block in #4207 itself). Add two more conditions, gated the same way on an authoritative RAM reading: more than one v8 block present, or the newest block's rendered text (CRLF-normalised) differing from what this build would write for the same inputs. Log which of the three reasons fired. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
erikdarlingdata
marked this pull request as ready for review
September 25, 2026 19:44
erikdarlingdata
added a commit
that referenced
this pull request
Sep 26, 2026
…nt blocks Adds these five block versions to CoveredMarkers: none of them derive from host RAM, disk, or the hypertable count, so each key rebuilds as a plain constant the way v14/v15 already do. v1 stays uncovered: its port line depends on the store's configured port, an input ClassifyLines is never given. v2, v3, v5, v7, v8, v12 stay Unclassified: they derive from RAM, disk, or hypertable-count inputs this classifier does not yet have rebuild machinery for. v8 in particular needs care (see the design's hardware-sizing block and #4342's staleness heal on dev) -- the sources available to this lane (design section 3 and review comment 5827863184) describe how staleness is detected on live stores but do not give a rebuild test this pure classifier can use without a data directory, so v8 is left exactly where the prior lane put it, with two new pins recording that a v8 block -- current or stale inputs -- must never classify as Ours until a follow-up lane adds that machinery. Also pins a duplicated v15 marker: both copies are byte-identical to the builder's output today, so both classify Ours -- this classifier has no duplicate-marker special case yet, and the pin makes that explicit so a future change to the rule is deliberate, not a regression caught by accident.
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.
Closes #4207.
Why
#4225 fixed the v8 hardware-sizing block's append-not-replace bug (collapsing duplicate blocks to one) and put
work_memback into the formula. Its heal only re-runs whenShouldAppendHardwareSizingsees the newest fingerprint in the conf differ from the current hardware and hypertable count. A store whose hardware has not moved since its last v8 write has no fingerprint change left to trigger on, so upgrading it past #4225 changed nothing: its conf still held its old duplicate v8 blocks, none of them carryingwork_mem, so the store's actually-livework_memvalue kept coming from the frozen v3 block instead.This is exactly what issuecomment-5837990283 on #4207 reported after #4225 shipped:
--check-settingsstill exits 3 (work_mem 31MB / derived 62MB: stale-after-hardware-change), and postgresql.conf still held three v8 blocks plus the v3 block's stalework_mem = 31MB. The store's hardware had not changed since its last v8 write, so #4225's own fix never ran on it.What changes
ShouldAppendHardwareSizing(DarlingManagedPostgres.cs) now also heals, still only with an authoritative RAM reading, when either of two new conditions holds: the conf carries more than one v8 block, or the newest v8 block's rendered content (CRLF-normalised) does not match what this build would write for the current inputs. The second condition is what catches a block whose fingerprint is current but whose formula is stale, which is the field case above — the fingerprint only encodes RAM and hypertable count, never the code version that turned them into settings.NewestHardwareSizingBlockIsCurrentdoes the content comparison, comparing only the LAST v8 block's span against the textBuildHardwareSizingConfAppendwould produce right now, with\r\nnormalised to\non both sides (the file can be CRLF; the freshly-rendered text is always LF).postgresql.auto.confis still never touched by any of this, soALTER SYSTEMvalues keep winning exactly as before.xUnit2013analyzer warning the new tests introduced (Assert.Equal(1, x.Count)toAssert.Single(x)) to keep the build at 0 warnings.Lite has no equivalent: it does not manage its own PostgreSQL install, so there is nothing to mirror there.
CHANGELOG entry
SECTION: Fixed
ENTRY:
work_memrejoined the formula, stayed on stale settings even after upgrading past the earlier fix. The heal now also runs when the conf carries more than one sizing block, or when the newest block's content no longer matches what the current build would write.REF:
[Heal the v8 sizing block on stores resized before #4225 (#4207) #4342]: Heal the v8 sizing block on stores resized before #4225 (#4207) #4342
Test plan
dotnet build Darling/Darling.Tests/Darling.Tests.csproj— 0 Warning(s), 0 Error(s).DarlingManagedPostgresTestsalone — 170 tests, 0 failed, 6 skipped (gated live tests, no rig env vars in this pass).*ManagedPostgres*,*CheckSettings*,*StoreHostProfile*,StartupCommandTimeoutTests,DocCommentHygiene*— 317 tests, 0 failed.ExistingStore_HealsPreFixV8Blocks_OnNextStart_Gatedalone, withDARLING_TEST_PGRUNTIMEpointed at a freshly extracted runtime: provisions a real store, stripswork_memfrom its own real v8 block and triples it (reproducing the field shape without needing a specific RAM figure), restarts, and confirmsSHOW work_memon the live server matches the derived value — passed. Rig runtime directory removed afterward.ShouldAppendHardwareSizing_FieldCase_OldFingerprintOnlyPredicate_WouldWronglySkipreproduces Managed-store memory sizing never re-derives after a host resize (effective_cache_size stale at 75% of the OLD RAM) #2845's original single-condition expression inline (the function's signature changed, so the old expression can no longer be called directly) and asserts it returnsfalse— "nothing to do" — on the exact fixture the sibling test proves needs healing.git merge origin/dev(clean, no conflicts) and a rebuild: fullDarling.Testssuite once — 14228 total, 0 errors, 0 failed, 784 skipped, 1 "Not Run". The "Not Run" count is a pre-existing runner artifact with no name or reason logged against it; Errors and Failed are both 0, and nothing in this PR's diff touches test discovery or collection machinery, so I did not chase it further.Lite.Tests— not run; this PR does not touch Lite, which has no managed-PostgreSQL install of its own to heal.DARLING_TEST_PG/DARLING_TEST_PGRUNTIMEset (every other live-gated test) — not run; out of scope for this lane, which was asked only to add the one new live test "if cheap."🤖 Generated with Claude Code
https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3