Doc update proposal for the note on log_statement in the runtime config for logging page

First seen: 2025-07-25 22:24:48+00:00 · Messages: 13 · Participants: 4

Latest Update

2026-05-08 · opus 4.7

Documentation Semantics: Durability Guarantees of the Logging Collector

Core Problem

A first-time contributor (Daniel) raised a documentation clarity issue that sits at an interesting intersection of PostgreSQL's architecture and user expectations: the relationship between transaction commit semantics (ACID) and server log output. Users — particularly those using log_statement or the logging collector for audit, security, or compliance purposes — may incorrectly assume that server logs form a consistent record of committed work, when in fact the logging subsystem is entirely outside the WAL/MVCC guarantees.

Two specific mismatches between user expectation and implementation exist:

  1. Temporal ordering vs. commit state: In exec_simple_query() (src/backend/tcop/postgres.c around line 1070), log_statement fires after parse analysis but before execution. A logged statement may subsequently error out, be rolled back, or have its effects lost due to a crash before commit. Conversely, for the extended query protocol, the log entry is emitted on receipt of the Execute message, again before the transaction outcome is known.

  2. Durability of the log file itself: The log write path (ereporterrfinishEmitErrorReportsend_message_to_server_logwrite_syslogger_file) deliberately does not fsync, and write_syslogger_file in syslogger.c handles write errors by falling back to stderr rather than raising an error that would abort the transaction. This is a conscious design choice — crashing the server because the log disk is full would be "overly harsh" — but it means a committed transaction can have no corresponding log record on disk after a power loss.

The Design Tension

This is not a bug; it is a deliberate architectural separation. Integrating server logging into the WAL would be both a massive layering violation and a severe performance penalty (synchronous fsync on every logged statement). Logging is intentionally a best-effort side channel, not a transactional artifact. The question is purely one of documentation: should this separation be made explicit for users who might otherwise rely on logs as an audit trail?

Bruce Momjian's initial pushback ("Why do you think log_statement is best effort?") and subsequent comments reflect a reluctance to adopt the phrase "best effort" — which carries connotations of flakiness — when the actual behavior is well-defined: log on entry, regardless of outcome. David Johnston reinforced this by noting that a SELECT returning rows to a client is worth logging even if its enclosing transaction rolls back; tying log emission to commit status would be "an insane design choice" and would also break use cases like debugging failed transactions.

Bruce's pointer to log_min_duration_statement=0 is technically significant: that parameter logs after statement completion, so it does provide a closer (though still not commit-synchronized) approximation of "statements that actually ran to completion." This is a useful distinction for users who care about post-hoc correlation.

Evolution of the Proposed Patch

Daniel's proposal migrated based on feedback:

The patch also questioned the existing wording "The logging collector is designed to never lose messages" — which, taken literally, overstates the guarantee. The collector's actual invariant is that it applies backpressure (blocking writers via pipe semantics) rather than dropping messages in-memory under load, unlike syslog's rate-limiting behavior. It makes no promise about post-crash durability.

Fujii Masao's Refinement

Fujii Masao (committer) provided the key wording improvements that tighten the semantics:

  1. For the "never lose messages" claim, he proposed: "The logging collector is designed to avoid dropping messages even under very high log volume." This correctly scopes the guarantee to the in-memory/backpressure behavior that distinguishes it from syslog, without making durability claims.

  2. For the durability caveat, he rejected "writes to disk asynchronously" as ambiguous (it could be read as referring to OS-level write buffering, or to the collector's async pipe architecture) and proposed: "The logging collector does not guarantee that log messages have reached durable storage. A system crash, power loss, or an error while writing the log file can still result in messages being lost." This is precise: it names the failure modes (crash, power loss, write error) and the consequence (message loss) without overcommitting on mechanism.

Key Technical Insights

Participant Dynamics

Bruce Momjian and David Johnston initially pushed back on the framing — not the underlying observation. Their resistance to "best effort" language is substantive: the term is imprecise and implies unreliability rather than a clean architectural boundary. Once Daniel refocused on durability (a concrete, demonstrable property) and moved the documentation to the logging_collector section, the objection dissolved.

Fujii Masao's endorsement as a committer, along with his concrete wording suggestions, effectively moves the patch toward a committable form. His refinements show the typical committer-level attention to exactly what is being guaranteed and what is not — avoiding both overclaiming and vagueness.