Skip to content

Heal the v8 sizing block on stores resized before #4225 (#4207) - #4342

Merged
erikdarlingdata merged 2 commits into
devfrom
fix/4207-heal-pre-fix-stores
Sep 25, 2026
Merged

erikdarlingdata merged 2 commits into
devfrom
fix/4207-heal-pre-fix-stores

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Closes #4207.

Why

#4225 fixed the v8 hardware-sizing block's append-not-replace bug (collapsing duplicate blocks to one) and put work_mem back into the formula. Its heal only re-runs when ShouldAppendHardwareSizing sees 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 carrying work_mem, so the store's actually-live work_mem value kept coming from the frozen v3 block instead.

This is exactly what issuecomment-5837990283 on #4207 reported after #4225 shipped: --check-settings still exits 3 (work_mem 31MB / derived 62MB: stale-after-hardware-change), and postgresql.conf still held three v8 blocks plus the v3 block's stale work_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.
  • New NewestHardwareSizingBlockIsCurrent does the content comparison, comparing only the LAST v8 block's span against the text BuildHardwareSizingConfAppend would produce right now, with \r\n normalised to \n on both sides (the file can be CRLF; the freshly-rendered text is always LF).
  • The call site now builds the candidate append text before the decision (the content-comparison condition needs it to decide, not just to write), and logs which of the three reasons fired — fingerprint changed, duplicate blocks found, or stale content — at Information, in addition to the existing Appended/Rewrote and collapsed-copies detail.
  • postgresql.auto.conf is still never touched by any of this, so ALTER SYSTEM values keep winning exactly as before.
  • In-lane: fixed an xUnit2013 analyzer warning the new tests introduced (Assert.Equal(1, x.Count) to Assert.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:

Test plan

  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj — 0 Warning(s), 0 Error(s).
  • DarlingManagedPostgresTests alone — 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.
  • New live test ExistingStore_HealsPreFixV8Blocks_OnNextStart_Gated alone, with DARLING_TEST_PGRUNTIME pointed at a freshly extracted runtime: provisions a real store, strips work_mem from its own real v8 block and triples it (reproducing the field shape without needing a specific RAM figure), restarts, and confirms SHOW work_mem on the live server matches the derived value — passed. Rig runtime directory removed afterward.
  • Proved the regression once: ShouldAppendHardwareSizing_FieldCase_OldFingerprintOnlyPredicate_WouldWronglySkip reproduces 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 returns false — "nothing to do" — on the exact fixture the sibling test proves needs healing.
  • After git merge origin/dev (clean, no conflicts) and a rebuild: full Darling.Tests suite 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.
  • Full suite with DARLING_TEST_PG/DARLING_TEST_PGRUNTIME set (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

erikdarlingdata and others added 2 commits September 25, 2026 15:22
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
erikdarlingdata marked this pull request as ready for review September 25, 2026 19:44
@erikdarlingdata
erikdarlingdata merged commit 3bb11e3 into dev Sep 25, 2026
16 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4207-heal-pre-fix-stores branch September 25, 2026 19:45
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant