Repository navigation
PostgreSQL config change history sees per-database and per-role overrides: changed, set and reset, server-wide rows unchanged (#3937) - #3957
Merged
Conversation
…override changes - SET, RESET and value changes over the server's snapshot sequence, V138 applied_at as the baseline cut (#3937)
…ange reader merges the server-wide and scoped reads newest first (#3937)
…ws byte-identical, scoped rows name only their scope plus change_kind, the note attached only when a scoped row is present (#3937)
…entical, live SET / baseline / changed / RESET over a V138-straddling history, tool payload shapes, reader census 10 -> 12 (#3937)
erikdarlingdata
enabled auto-merge (squash)
September 23, 2026 00:40
This was referenced Sep 23, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Sep 23, 2026
…3920, #3927, #3931, #3932, #3940, #3942, #3946, #3947, #3950, #3952, #3955, #3956, #3957, #3964, #3965, #3966, #3968, #3972, #3975, #3979, #3980, #3981, #3983, #3984, #3985) (#3989) The wave's fix PRs deliberately carried no CHANGELOG edits (parallel-agent hot-spot protocol); each agent reported its entry and this commit lands them together, byte-verified against origin/dev. Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv 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.
Closes #3937. This is a derivative of #3691 (V138, the per-database and per-role override rows in
pg_server_config).What a PostgreSQL operator now learns
get_pg_server_config_changes, and its web twin, now reportsALTER DATABASE … SETandALTER ROLE … SEThistory. Before this change it went silent on overrides. V138 had to exclude override rows from the server-wideLAG, because a same-name override in the same partition would invent a change on every snapshot. That exclusion was correct, and it left the feed blind to overrides. Even a per-scopeLAGcould only see a value moving on an override that already existed. It could never see one being SET, because a first row is hidden byprev_time IS NOT NULL, or RESET, because an absent row is never read.The design
The server-wide read is the same statement.
ConfigChangesSqlchanged in its comment only. Its text with comments stripped is pinned verbatim against the pre-get_pg_server_config_changes is blind to per-database and per-role overrides: an ALTER DATABASE … SET or ALTER ROLE … SET change never appears (derivative of #3691 / V138) #3937 statement, so its rows and their order cannot move.The scoped read is a second statement,
ScopedConfigChangesSql, not aUNION ALLin the first. Folding it in would have changed the server-wide read's text, its row order and its census classification. As a second statement it is the census's second override-selecting read, carrying the positive arm on its ownFROM.It walks the SERVER's snapshot sequence, not the key's.
snapshotspairs each windowed snapshot instant with the one before it, and each(name, database_name, role_name)key is compared across that pair:changed;set, withold_valuenull;reset, withnew_valuenull.The instants are read off every row, not off the override rows alone. RESETting the last override leaves a snapshot that holds no overrides, and that pair still has to exist.
The baseline cut. A
setis reported only when the snapshot it is compared against was taken at or after V138'sdarling_schema_version.applied_at. Overrides present on the first post-V138 snapshot are baseline: the collector started seeing them, nobody set them then. A store with no V138 stamp reports no SETs, which is the conservative failure. Value changes and RESETs need no cut.Bounds. Both snapshots of every pair sit inside
[$2, $3], and both reads areserver_id = $1plus the window. No index was added, and neither read is on the alert path.Payload. A server-wide row keeps the SAME anonymous shape, byte for byte. A scoped row is a
JsonObjectcarryingchanged_at,name, only the scope names it has (database_nameand/orrole_name), thenchange_kind,old_value,new_valueandsource.McpHelpers.JsonOptionswrites nulls, so a shared shape would have put"database_name": nullon every server-wide row.scoped_changes_noteis attached only when a scoped row is on the page. A page without one goes through the original serialize path unchanged.Row order.
GetConfigChangesAsyncasks both statements for the fulllimitand merges them newest first. At onecollection_timethe server-wide rows come first. The tool'slimit + 1over-fetch therefore still observes truncation over the union.Inherent limits (not defects)
changed_atis the snapshot that first saw the new state, as it already was for server-wide rows.server_idand the window.Pins
(i)
PgServerConfigTests.TheServerWideChangeRead_IsTheStatementItWasBeforeTheScopedFeed: raw-text pin, comments stripped, against the pre-get_pg_server_config_changes is blind to per-database and per-role overrides: an ALTER DATABASE … SET or ALTER ROLE … SET change never appears (derivative of #3691 / V138) #3937 statement verbatim.(ii)–(v)
PgServerConfigOverrideLivePostgresTests.TheChangeFeed_ReportsOverrideChangesSetsAndResets_AndLeavesTheServerWideRowsUnchanged(live). It plants a four-snapshot history straddling the real V138applied_at:changed), moves server-widework_mem, and adds a database+role override (iii,setwith a nullold_value);resetwith a nullnew_value).It asserts exactly four rows in order: the reset, then the server-wide change ahead of the scoped rows at t2. Then it checks the tool:
scoped_changes_note,change_kind,database_nameorrole_nameanywhere, and has the pre-get_pg_server_config_changes is blind to per-database and per-role overrides: an ALTER DATABASE … SET or ALTER ROLE … SET change never appears (derivative of #3691 / V138) #3937 page and row key lists.(vi)
PgServerConfigScopeRungTests.EveryProductReadOfTheConfigTable_…: the census goes from 10 to 12 reads with the reason.ScopedConfigChangesSql'ssnapshotssubquery andoverridesCTE are both aliasedFROM pg_server_config AS c, and both are classified "selects". New assertions pin exactly twoFROMs, the positive arm on the CTE, no negative arm anywhere, and the arm inside the census's statement window. The prose moves from "ten" to "twelve" and from "eleventh" to "thirteenth".DarlingPgReadSqlParsesLiveTests:ScopedConfigChangesSqlis parse-checked live by reflection, and the threePgConfigChangeKindspellings joinNotQueryFieldsbecause they are values, not statements.Reviewer checklist
ScopedConfigChangesSql: thesetarm'ss.prev_time >= (SELECT applied_at … version = 138), the reset arm'sNOT EXISTSagainst the NEXT snapshot, andIS NOT DISTINCT FROMon both scope columns.GetConfigChangesAsyncmerge: server-wide rows are taken first on equalcollection_time, and the merge is capped atlimit.rows.All(server-wide)branch returns the originalJsonSerializer.Serialize(page, …)path.Tests run (macOS harness, in-worktree, net10.0, live against timescale/timescaledb:2.28.1-pg18, migrated)
255 tests, 0 failed, 0 skipped, with
DARLING_TEST_PGset:The runner counts rows, including theory cases. The Viewer-dependent probe fact and every Lite/Viewer census first run on Windows CI.
CHANGELOG entry
get_pg_server_config_changesreportsALTER DATABASE/ROLE … SEToverrides whose value changed, that were set, or that were reset, interleaved with the server-wide changes and markedchange_kind. Overrides already present when the collector first read them are not reported as set. Server-wide rows are unchanged.