From 1e7169a0afe8a09c8a1953f9813f3f2ece5faee7 Mon Sep 17 00:00:00 2001 From: Seongjun Shin Date: Fri, 29 May 2026 14:52:11 +0900 Subject: [PATCH v5 2/2] Add wait events for Windows-specific logging output paths On Windows, log output goes through paths other than write(2) that can also block: write_console() emits to the console with WriteConsoleW(), and write_eventlog() writes to the Windows event log with ReportEventW()/ReportEventA(). Like the write(2) path, these calls can block and previously left wait_event IS NULL in pg_stat_activity. Wrap WriteConsoleW() with the StderrWrite event introduced in the previous patch, and add a new EventlogWrite event for the event log path: IO / EventlogWrite - ReportEventW()/ReportEventA() inside write_eventlog(). This instruments the Windows logging paths consistently with the write(2) and syslog(3) paths. It is split out from the previous patch since it is platform-specific. --- src/backend/utils/activity/wait_event_names.txt | 1 + src/backend/utils/error/elog.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index d4a0f6361ad..bcfe9049734 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -228,6 +228,7 @@ DATA_FILE_TRUNCATE "Waiting for a relation data file to be truncated." DATA_FILE_WRITE "Waiting for a write to a relation data file." DSM_ALLOCATE "Waiting for a dynamic shared memory segment to be allocated." DSM_FILL_ZERO_WRITE "Waiting to fill a dynamic shared memory backing file with zeroes." +EVENTLOG_WRITE "Waiting for a write to the Windows event log." LOCK_FILE_ADDTODATADIR_READ "Waiting for a read while adding a line to the data directory lock file." LOCK_FILE_ADDTODATADIR_SYNC "Waiting for data to reach durable storage while adding a line to the data directory lock file." LOCK_FILE_ADDTODATADIR_WRITE "Waiting for a write while adding a line to the data directory lock file." diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index da17efd88c1..2a03dd6ff0b 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -3006,6 +3006,11 @@ write_eventlog(int level, const char *line, int len) { const WCHAR *utf16_const = utf16; + /* + * A nested log write briefly masks any outer wait event + * (wait events are single-slot). + */ + pgstat_report_wait_start(WAIT_EVENT_EVENTLOG_WRITE); ReportEventW(evtHandle, eventlevel, 0, @@ -3015,12 +3020,14 @@ write_eventlog(int level, const char *line, int len) 0, &utf16_const, NULL); + pgstat_report_wait_end(); /* XXX Try ReportEventA() when ReportEventW() fails? */ pfree(utf16); return; } } + pgstat_report_wait_start(WAIT_EVENT_EVENTLOG_WRITE); ReportEventA(evtHandle, eventlevel, 0, @@ -3030,6 +3037,7 @@ write_eventlog(int level, const char *line, int len) 0, &line, NULL); + pgstat_report_wait_end(); } #endif /* WIN32 */ @@ -3071,11 +3079,14 @@ write_console(const char *line, int len) DWORD written; stdHandle = GetStdHandle(STD_ERROR_HANDLE); + pgstat_report_wait_start(WAIT_EVENT_STDERR_WRITE); if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL)) { + pgstat_report_wait_end(); pfree(utf16); return; } + pgstat_report_wait_end(); /* * In case WriteConsoleW() failed, fall back to writing the -- 2.50.1 (Apple Git-155)