Skip to content

Review/test: Add wait events for server logging destination writes (v4-0001)#45

Open
NikolayS wants to merge 1 commit into
masterfrom
review/logging-dest-wait-events
Open

Review/test: Add wait events for server logging destination writes (v4-0001)#45
NikolayS wants to merge 1 commit into
masterfrom
review/logging-dest-wait-events

Conversation

@NikolayS

Copy link
Copy Markdown
Owner

What this is

Patch v4-0001 from Seongjun Shin's thread "Add wait events for server
logging destination writes"
, applied on top of current upstream master for
review and testing. Authorship is preserved (git am).

The text below is my review, recorded here and intended to be sent to
pgsql-hackers.


Review

Hi Seongjun,

I reviewed and tested v4-0001 (the portable part). Short version: it applies
cleanly, builds without new warnings, and does exactly what it claims — log
write stalls that previously showed wait_event IS NULL ("on CPU") are now
attributable in pg_stat_activity. +1 on the approach.

Test setup

  • Base: PostgreSQL master (assert-enabled build); the patch also rebases
    cleanly onto the current tip.
  • Platforms: Linux and macOS (functional test of 0001 only; I don't have a
    Windows box for 0002).
  • Workload: 8 concurrent backends, each emitting 120k large (~8 KB)
    RAISE LOG lines, while a server-side sampler snapshotted
    pg_stat_activity every ~2 ms (~5000 samples).

Results

Configuration Path exercised Observed wait event
logging_collector=on write_pipe_chunks() -> syslogger pipe IO / SysloggerWrite (33,575 samples)
logging_collector=off write_console() -> stderr IO / StderrWrite (34,206 samples)

On unpatched master the same workload shows wait_event IS NULL throughout.
I did not exercise IO / SyslogWrite (no syslog destination configured),
but its instrumentation is structurally identical to the two paths above.

Code

  • Instrumentation is minimal and correctly placed at the leaf calls: both
    write() sites in write_pipe_chunks() (the full-payload loop and the
    final chunk), the write() in write_console(), and both syslog()
    branches in write_syslog(). No Unix-side path is missed.
  • Error-path safety checks out. pgstat_report_wait_start() writes to
    *my_wait_event_info, which defaults to a process-local variable
    (local_my_wait_event_info) until pgstat_set_wait_event_storage() runs at
    backend startup. So invoking these before MyProc is attached — or from the
    postmaster — is safe; it simply won't be visible in pg_stat_activity.
    That's the expected/acceptable behavior, but it might be worth a one-line
    comment so readers don't expect postmaster-side log writes to surface.
  • No new allocations, consistent with the stated goal of staying safe inside
    error reporting.

Minor / open

  • (nit) A brief comment at each pgstat_report_wait_start() site could help,
    though the event names are self-explanatory.
  • Naming LGTM and matches the per-routine granularity Michael suggested
    upthread.
  • The only real gap remains Windows runtime testing of 0002
    (WriteConsoleW / EventlogWrite) — already flagged in the thread.

From my side the Unix portion is ready-for-committer; the outstanding item is
Windows verification of 0002.

Tested-by: Nikolay Samokhvalov nik@postgres.ai

When a backend writes server log output, the underlying call can
block: write(2) to the syslogger pipe or to stderr once the pipe
buffer fills up or the output device is slow, and syslog(3) when the
system logger is slow.  These blocking calls were not instrumented, so
pg_stat_activity reported wait_event IS NULL during that time.  Many
monitoring tools interpret NULL as on-CPU work, which made
heavy-logging stalls hard to attribute.

Add three new WaitEventIO events and report them around the relevant
calls:

  IO / SysloggerWrite - write(2) to the syslogger pipe inside
                        write_pipe_chunks().
  IO / StderrWrite    - write(2) to stderr inside write_console().
  IO / SyslogWrite    - syslog(3) inside write_syslog().

The instrumentation is limited to the leaf write/syslog call.  It uses
only the existing pgstat_report_wait_start()/end() inline helpers,
which are allocation-free and safe to call before MyProc is set up, so
this remains safe to invoke from within error reporting paths.
@NikolayS

NikolayS commented Jun 14, 2026

Copy link
Copy Markdown
Owner Author

Subject: Re: Add wait events for server logging destination writes

Hi Seongjun,

I tested v4-0001 on Linux and macOS. It applies and builds cleanly, and
under heavy logging the new events show up in pg_stat_activity exactly as
expected -- IO/SysloggerWrite with logging_collector on, IO/StderrWrite
with it off -- where master shows NULL. Looks good to me, +1.

On Andrey's nesting concern: I checked the most likely case,
log_lock_waits, and it doesn't clobber -- a lock wait sets PG_WAIT_LOCK
only inside WaitLatch, and the "still waiting" LOG is emitted after
WaitLatch returns, when the event is already 0. The same holds for other
WaitLatch-scoped waits. A clobber would need an ereport() fired while a
manually-held wait-event region is open, which these leaf calls don't sit
inside -- so the risk looks real but narrow, and it's inherent to the
single-slot model rather than new here.

One minor thing: a short comment noting that the write happens before
MyProc is set up in the postmaster (so it isn't surfaced there) might
save the next reader some confusion. Not a blocker.

I also exercised 0002 on Windows via CI (MSVC build, heavy logging into
log_destination = 'stderr,eventlog'): IO/EventlogWrite shows up in
pg_stat_activity as expected. The one path I couldn't cover is the
interactive-console WriteConsoleW branch of StderrWrite, since CI
redirects stderr to a file rather than a real console.

Nik

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.

2 participants