The log-rotation live test expects every "still waiting" line a lock wait writes, each once, and pins a wait that logs twice - #4885
Merged
Conversation
When a count check in the csv/json rotation test fails, the message now lists the rows matching the wait's identity or carrying its pid (hash, time, pid, severity, family, message, detail, context), the resume state going in and coming out, and the target's log directory. The checks are exactly as strict as before.
…m the log files, and pin a wait that logs twice
… 3 s lock_timeout
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.
What failed
On dev
d36306e41(Build run, attempt 1, a Windows PG shard),PgServerLogTailCsvJsonRotationLiveTests.ARotationBetweenReads_DoesNotLoseTheLinesWrittenBeforeIt(json: True, binary: True)failed withAssert.Equal() Failure: Expected: 1, Actual: 2. The same tree had passed all four PG shards at the PR head, so the failure was intermittent. Nothing was lost; the wait was counted twice.Why: the test's identity, not the tail
The test identified "its" lock wait as rows with the waiter's pid, occurred at or after a floor, and containing "still waiting", and required exactly one.
PostgreSQL 18 can write more than one such line for ONE wait. In
src/backend/storage/lmgr/proc.c(REL_18_STABLE),ProcSleep's wait loop runsif (log_lock_waits && deadlock_state != DS_NOT_YET_CHECKED)on every latch wakeup, and logsprocess %d still waiting for %s on %s after %ld.%03d mswhile the backend is still waiting. After logging, it resetsdeadlock_state = DS_NO_DEADLOCK, which still passes that test. So every latch wakeup betweendeadlock_timeout(100 ms here) and the end of the wait writes another line, with a larger "after N ms" and so a differentraw_line_hash.Reproduced deterministically on a local PostgreSQL 18.6 jsonlog cluster configured like the CI cluster:
lock_timeout = 800ms.pg_log_backend_memory_contexts(<waiter pid>), which sets the waiter's latch through a procsignal.after 104.946 msandafter 458.799 ms).The tail itself is not implicated, from reading
PgServerLogTail.cs:.logcompanion is excluded by the\.json$/\.csv$filter;What changed (tests only)
The expected set comes from the files themselves.
ExpectedWaitLinesAsyncreads each of the route's log files once, from byte 0 (pg_ls_logdir()+pg_read_file), and parses them with the product's ownPgServerLogJsonParser/PgServerLogCsvParser. It collects the messages of every entry with the wait's pid, at or after the floor, startingprocess <pid> still waiting for.The resumed read must equal that set exactly:
raw_line_hashrepeats within the cycle;Nothing is loosened. A lost line, a duplicated line (the same hash twice) or a stranger line still fails.
New permanent pin,
ALockWaitThatLogsTwice_IsReadAsTwoLinesEachOnce(json/csv × binary/text): it forces the second line withpg_log_backend_memory_contexts350 ms into the wait, asserts the files hold exactly two lines, and runs the same exact checks.lock_timeout = 3000ms(the unpoked path keeps 800 ms), so the poke lands inside the wait even on a slow runner.Every count check is self-describing on failure (
PgLogRotationEvidence). It prints:pg_ls_logdir()listing at failure time.A passing run never builds it.
Verification
Count(...) == 1check in the new pin reported 2 in 4 of 4 variants. GREEN: the new checks pass.DocCommentHygieneTests77/77 andPgLogRotationEvidenceTests2/2.--no-incrementalRelease build, 0 warnings and 0 errors.Findings: 0 substantial, 1 hygiene fixed in this PR (the test identity), 0 polish dropped.
CHANGELOG
None: test-only; the log-rotation live test's identity for a lock wait's "still waiting" lines, and no product code changes.