pg_stat_get_backend_wait_event() and
pg_stat_get_backend_wait_event_type() functions don't work for aux
processes:
postgres=# select pid, backend_type, wait_event, wait_event_type from
pg_stat_activity ;
pid | backend_type | wait_event | wait_event_type
---------+------------------------------+---------------------+-----------------
3665058 | client backend | |
3665051 | autovacuum launcher | AutovacuumMain | Activity
3665052 | logical replication launcher | LogicalLauncherMain | Activity
3665044 | io worker | IoWorkerMain | Activity
3665045 | io worker | IoWorkerMain | Activity
3665046 | io worker | IoWorkerMain | Activity
3665047 | checkpointer | CheckpointerMain | Activity
3665048 | background writer | BgwriterMain | Activity
3665050 | walwriter | WalWriterMain | Activity
(9 rows)
postgres=# SELECT pg_stat_get_backend_pid(backendid) AS pid,
pg_stat_get_backend_wait_event_type(backendid) as wait_event_type,
pg_stat_get_backend_wait_event(backendid) as wait_event
FROM pg_stat_get_backend_idset() AS backendid;
pid | wait_event_type | wait_event
---------+-----------------+---------------------
3665058 | |
3665051 | Activity | AutovacuumMain
3665052 | Activity | LogicalLauncherMain
3665044 | |
3665045 | |
3665046 | |
3665047 | |
3665048 | |
3665050 | |
(9 rows)
We added aux processes to pg_stat_activity in commit fc70a4b0df, but
apparently forgot to do the same for those functions.
With the attached fix:
postgres=# SELECT pg_stat_get_backend_pid(backendid) AS pid,
pg_stat_get_backend_wait_event_type(backendid) as wait_event_type,
pg_stat_get_backend_wait_event(backendid) as wait_event
FROM pg_stat_get_backend_idset() AS backendid;
pid | wait_event_type | wait_event
---------+-----------------+---------------------
3667552 | |
3667545 | Activity | AutovacuumMain
3667546 | Activity | LogicalLauncherMain
3667538 | Activity | IoWorkerMain
3667539 | Activity | IoWorkerMain
3667540 | Activity | IoWorkerMain
3667541 | Activity | CheckpointerMain
3667542 | Activity | BgwriterMain
3667544 | Activity | WalWriterMain
(9 rows)
While looking at this, I noticed that pg_stat_activity has a
"backend_type" field, but there's no corresponding
"pg_stat_get_backend_type(backend_id)" function, similar to
"pg_stat_get_backend_wait_event(backend_id)" et al. I wonder if that was
on purpose, or we just forgot to add it when we added it to
pg_stat_activity?
Another thing I didn't do in this patch yet: I feel we should replace
BackendPidGetProc() with a function like "PGPROC *PidGetPGProc(pid_t)",
that would work for backends and aux processes alike. It's a common
pattern to call BackendPidGetProc() followed by AuxiliaryPidGetProc()
currently. Even for the callers that specifically want to only check
backend processes, I think it would be more natural to call
PidGetPGProc(), and then check the process type.
- Heikki
From 4035675111869c637883848a23b60cc1c64b473b Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <[email protected]>
Date: Mon, 2 Feb 2026 16:12:06 +0200
Subject: [PATCH 1/1] Fix pg_stat_get_backend_wait_event() for aux processes
The pg_stat_activity view shows the information for aux processes, but
the pg_stat_get_backend_wait_event() and
pg_stat_get_backend_wait_event_type() functions did not.
The straightforward fix would've been to call AuxiliaryPidGetProc(pid)
if BackendPidGetProc(pid) returns NULL, like we do in
pg_stat_get_activity(). It's a little inefficient though: we already
have the ProcNumber of the process, so we're really only using
BackendPidGetProc(pid) to check if the process is still alive. Make
that check a little cheaper while we're at it.
---
src/backend/utils/adt/pgstatfuncs.c | 30 +++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 73ca0bb0b7f..2a573b603bd 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -817,15 +817,24 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
{
int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- PGPROC *proc;
const char *wait_event_type = NULL;
if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
wait_event_type = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event_type = "<insufficient privilege>";
- else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
- wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+ else
+ {
+ PGPROC *proc = GetPGProcByNumber(procNumber);
+ uint32 raw_wait_event;
+
+ raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
+
+ /* check if the process is still running */
+ pg_read_barrier();
+ if (proc->pid == beentry->st_procpid)
+ wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
+ }
if (!wait_event_type)
PG_RETURN_NULL();
@@ -838,15 +847,24 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
{
int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- PGPROC *proc;
const char *wait_event = NULL;
if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
wait_event = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event = "<insufficient privilege>";
- else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
- wait_event = pgstat_get_wait_event(proc->wait_event_info);
+ else
+ {
+ PGPROC *proc = GetPGProcByNumber(procNumber);
+ uint32 raw_wait_event;
+
+ raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
+
+ /* check if the process is still running */
+ pg_read_barrier();
+ if (proc->pid == beentry->st_procpid)
+ wait_event = pgstat_get_wait_event(raw_wait_event);
+ }
if (!wait_event)
PG_RETURN_NULL();
--
2.47.3