Skip to content

A carried maintenance_work_mem is capped for PostgreSQL 17 and earlier when the managed settings move (#4336) - #4444

Merged
erikdarlingdata merged 2 commits into
devfrom
fix/n473-carried-maintenance-work-mem-cap
Sep 26, 2026
Merged

erikdarlingdata merged 2 commits into
devfrom
fix/n473-carried-maintenance-work-mem-cap

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Refs #4336. Found by the nightly's gated upgrade-path tests.

Why

ManagedConfMigrationRunner.RunStepA moves a data directory's settings from the old postgresql.conf blocks into the new darling-managed.conf file. Any of our own keys that the fresh render does not itself derive a value for are carried forward verbatim from the before-migration snapshot, so the migrated file still has them.

maintenance_work_mem is one of the keys that fresh renders re-derive under normal conditions, but on an older store that key can carry a value from before the PostgreSQL 17 cap was introduced (2048 MB, one MB over the 2 GB limit PostgreSQL 17 and earlier enforce on Windows). The rendered file's own cap logic only ever looks at values the CURRENT render produced, so a carried, unrendered 2048 MB slipped through uncapped. postgres -C then refuses to start: PostgreSQL 17 accepts at most 2097151 kB, and 2048 MB is 2097152 kB.

This surfaced as a gated nightly test failure once the store settings started moving into the included file (#4336).

What changes

RunStepA now runs the carried maintenance_work_mem value through the same predicate the fresh-render path already uses (DarlingManagedPostgres.NeedsLegacyMaintenanceWorkMemCap, checked against the running PostgreSQL major already available on RunStepA's render inputs) before writing it into the before-values map that becomes the migrated file's content. When the predicate says the carried value would stop PostgreSQL 17 or earlier from starting, the carried value is replaced with the same cap the fresh render already applies (MaintenanceWorkMemCapMb, 2047 MB). PostgreSQL 18 and later are unaffected — the predicate is major-aware, so a carried 2048 MB is kept as-is on PostgreSQL 18. There is still exactly one place the cap rule itself lives.

Test plan

Two new unit pins on ManagedConfMigrationRunner.RunStepA (Darling.Tests.ManagedConfMigrationRunnerTests), covering the runner's own snapshot/inputs shape used throughout that test class, no database:

  • RunStepA_CarriedMaintenanceWorkMemOver2047_Postgres17_Caps: a before snapshot reporting maintenance_work_mem = 2048MB as applied, PostgreSQL major 17 → the migrated darling-managed.conf holds maintenance_work_mem = '2047MB' and never '2048MB'.
  • RunStepA_CarriedMaintenanceWorkMemOver2047_Postgres18_KeepsIt: the same carried 2048MB, PostgreSQL major 18 → kept exactly, uncapped.

RED confirmed against the pre-fix code: the new pin file, copied into a detached worktree of origin/dev (49761f909, no product change), fails:

Darling.Tests.ManagedConfMigrationRunnerTests.RunStepA_CarriedMaintenanceWorkMemOver2047_Postgres17_Caps [FAIL]
Assert.Contains() Failure: Sub-string not found
Not found: "maintenance_work_mem = '2047MB'"

Mutation confirmed on this branch: short-circuiting the new cap check back off (&& false /* ... */) reproduced the identical failure; restoring the check went back to green.

Green on this branch, macOS in-process xUnit v3 runner, Darling.Tests.dll:

  • ManagedConfMigrationRunnerTests: 18/18.
  • ManagedConfFileTests, DocCommentHygieneTests, ManagedConfUpgradePathTests (combined with the above): 132 total, 1 skipped (a live/gated fact, unrelated to this change), 0 failed.
  • DarlingManagedPostgresTests: 5 failures, identically reproduced with and without this change on macOS (platform path assumptions — not run on Windows here) — pre-existing, not caused by this fix.

Both test projects build 0 errors: Darling.Tests.csproj and Lite.Tests.csproj (-p:EnableWindowsTargeting=true). Lite.Tests and Darling.Tests target net10.0-windows and cannot run their full Windows-only suites on this machine; CI decides those. The gated live test named in the nightly failure (a store carrying the old cap starting through the real bootstrap) is proven by the next nightly run.

CHANGELOG entry

SECTION: Fixed
ENTRY:

RunStepA now runs a carried maintenance_work_mem value through the same
NeedsLegacyMaintenanceWorkMemCap predicate the fresh-render path already
uses, so a pre-existing 2048 MB value moved into darling-managed.conf on
a PostgreSQL 17 or earlier store is capped at 2047 MB instead of landing
uncapped and failing to start. PostgreSQL 18 and later are unaffected.

Adds two unit pins through RunStepA (PostgreSQL 17 caps a carried
2048 MB; PostgreSQL 18 keeps it).
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 26, 2026 20:08
@erikdarlingdata
erikdarlingdata merged commit 12893bc into dev Sep 26, 2026
15 of 16 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/n473-carried-maintenance-work-mem-cap branch September 26, 2026 20:08
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