Repository navigation
PostgreSQL 13 csvlog records (24 columns) are parsed instead of rejected, and rejected records are counted (#4709) - #4714
Merged
Conversation
…he real discard count (#4709) PostgreSQL 13 writes 24 csvlog columns; leader_pid and query_id arrived in 14. The parser required exactly 26, so every PostgreSQL 13 record was rejected and the whole read counted as one discard. It now accepts 24 or 26 fields, carries the query_id column as PgLogEntry.QueryIdText (null when absent), reads the plan capture query id from that member instead of the last comma of the record, and counts the records it dropped when no parity could be confirmed.
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 #4709.
Why
PostgreSQL 13 writes 24 csvlog columns.
leader_pidandquery_idarrived in 14.PgServerLogCsvParserrequired exactly 26 fields, so every PostgreSQL 13 record was rejected. Csvlog is now the preferred reader wheneverlog_destinationlists it, so on a 13 server with both stderr and csvlog enabled the log events, deadlocks and plan capture came back empty. The run also reported one discard however many records were rejected, so a server whose every record failed the shape check looked almost quiet. PostgreSQL 13 is a supported target (docs/postgres-first-target-runbook.md).The first 24 columns are identical in 13 and 14 through 18 (checked against the PostgreSQL 13 documentation's
postgres_logtable: 24 columns,backend_typelast). The highest index the entry's own members read is 21 (location), so a 24-field record carries everything the parser reads. Nothing shifts.What changes
PerformanceMonitor.Collectors/PgServerLogCsvParser.csExpectedColumnCount.query_idcolumn (index 25) is carried asPgLogEntry.QueryIdText, and is null on a 24-field record. It is absent, never the last field read as if it were the id.consumedLengthstays 0 so the RDS carry is untouched. What changes is the count: the segments that could not be used are now counted instead of the whole body counting as one discard. At least one is still reported for a non-empty body.PerformanceMonitor.Collectors/PgLogEntry.cs: new trailing memberQueryIdText(default null), following theLocationprecedent so every existing construction still compiles.PerformanceMonitor.Collectors/PgPlanCaptureCollector.cs: the query id used to be the text after the last comma of the raw record. On a 24-field record that is the quotedbackend_type, so every real capture would have been counted as forged. It now readsQueryIdText. A null id is stored as query id 0, which this collector already uses for "no attribution" (a plan captured on a target that never configured%Q), and a present but unparseable id is still counted as forged. The method that split on the last comma is gone.PgLogEventsCollector.cs,PgDeadlocksCollector.csorPgLogFormatCapability.cs: the measurement plumbing already reports whatever count the parser returns, and csvlog stays preferred on PostgreSQL 13 (no fallback to stderr).Tests
Tests added in
PgServerLogCsvParserTestsandPgPlanCaptureCsvUnitTestsand run against the old code first. Eight test cases failed there:Pg13Record_With24Fields_ParsesIntoOneEntryPg13Record_MapsEveryFieldTheParserReads_ToTheValueTheSame26FieldRecordGivesAMixedBody_OfPg13AndPg14PlusRecords_ParsesEveryRecordABatchOfNMalformedRecords_ReportsNDiscardswith n = 3 and n = 7 (n = 1 passed before, since one record is one discard)NoneMode_MalformedRecordsBeforeATrailingPartial_AreEachReported_AndNothingIsConsumedAResumeOffsetAtALineStartInsideAQuotedMultiLineField_YieldsEachLaterRecordExactlyOncefor the 24-field shape (the 26-field case passes before and after)PgPlanCaptureCsvUnitTests.APg13Record_With24Fields_HasNoQueryIdColumn_SoItYieldsAnOrphanRowNotAForgeryThe resume-offset test is the pin for the self-hosted tail marker (#4704): a resume offset at a line start inside a quoted multi-line field still yields every later record exactly once, and never the straddling record's tail, for both column shapes.
Lite.TestsPostgreSQL log and plan classes: 114 run, 0 failed.Darling.Testsafter a merge check withorigin/dev(no drift): 17058 run, 0 failed, 1111 skipped (live classes that need a store), 1 not run. Build: 0 warnings, 0 errors.backend_type, which is how the two formats differ.Worth a second look
plan_attributionreadiness facet already describes, so the orphan route was chosen.CHANGELOG
SECTION: Fixed
ENTRY:
leader_pidandquery_idarrived in 14), so every PostgreSQL 13 record was rejected. Log events, deadlocks and plan capture came back empty, and the run counted one discard however many records were rejected. The parser now accepts 24 or 26 fields, and a read it cannot use reports how many records it dropped. A PostgreSQL 13 auto_explain capture has no query id, so it is stored as an orphan plan (query id 0) instead of being counted as forged.REF:
[PostgreSQL 13 csvlog records (24 columns) are parsed instead of rejected, and rejected records are counted (#4709) #4714]: PostgreSQL 13 csvlog records (24 columns) are parsed instead of rejected, and rejected records are counted (#4709) #4714