Add backendType to PGPROC, replacing isRegularBackend

We can immediately make use of it in pg_signal_backend(), which
previously fetched the process type from the backend status array with
pgstat_get_backend_type_by_proc_number(). That was correct but felt a
little questionable to me: backend status should be for observability
purposes only, not for permission checks.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/b77e4962-a64a-43db-81a1-580444b3e8f5@iki.fi
This commit is contained in:
Heikki Linnakangas 2026-02-04 13:06:04 +02:00
parent 4cfce4e62c
commit 084e42bc71
7 changed files with 9 additions and 37 deletions

View file

@ -470,7 +470,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, FullTransactionId fxid,
proc->databaseId = databaseid;
proc->roleId = owner;
proc->tempNamespaceId = InvalidOid;
proc->isRegularBackend = false;
proc->backendType = B_INVALID;
proc->lwWaiting = LW_WS_NOT_WAITING;
proc->lwWaitMode = 0;
proc->waitLock = NULL;

View file

@ -3589,7 +3589,7 @@ CountDBConnections(Oid databaseid)
if (proc->pid == 0)
continue; /* do not count prepared xacts */
if (!proc->isRegularBackend)
if (proc->backendType != B_BACKEND)
continue; /* count only regular backend processes */
if (!OidIsValid(databaseid) ||
proc->databaseId == databaseid)
@ -3660,7 +3660,7 @@ CountUserBackends(Oid roleid)
if (proc->pid == 0)
continue; /* do not count prepared xacts */
if (!proc->isRegularBackend)
if (proc->backendType != B_BACKEND)
continue; /* count only regular backend processes */
if (proc->roleId == roleid)
count++;

View file

@ -87,10 +87,7 @@ pg_signal_backend(int pid, int sig)
*/
if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
{
ProcNumber procNumber = GetNumberFromPGProc(proc);
BackendType backendType = pgstat_get_backend_type_by_proc_number(procNumber);
if (backendType == B_AUTOVAC_WORKER)
if (proc->backendType == B_AUTOVAC_WORKER)
{
if (!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_AUTOVACUUM_WORKER))
return SIGNAL_BACKEND_NOAUTOVAC;

View file

@ -486,7 +486,7 @@ InitProcess(void)
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->tempNamespaceId = InvalidOid;
MyProc->isRegularBackend = AmRegularBackendProcess();
MyProc->backendType = MyBackendType;
MyProc->delayChkptFlags = 0;
MyProc->statusFlags = 0;
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
@ -684,7 +684,7 @@ InitAuxiliaryProcess(void)
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->tempNamespaceId = InvalidOid;
MyProc->isRegularBackend = false;
MyProc->backendType = MyBackendType;
MyProc->delayChkptFlags = 0;
MyProc->statusFlags = 0;
MyProc->lwWaiting = LW_WS_NOT_WAITING;

View file

@ -1164,31 +1164,6 @@ pgstat_get_my_plan_id(void)
return MyBEEntry->st_plan_id;
}
/* ----------
* pgstat_get_backend_type_by_proc_number() -
*
* Return the type of the backend with the specified ProcNumber. This looks
* directly at the BackendStatusArray, so the return value may be out of date.
* The only current use of this function is in pg_signal_backend(), which is
* inherently racy, so we don't worry too much about this.
*
* It is the caller's responsibility to use this wisely; at minimum, callers
* should ensure that procNumber is valid and perform the required permissions
* checks.
* ----------
*/
BackendType
pgstat_get_backend_type_by_proc_number(ProcNumber procNumber)
{
volatile PgBackendStatus *status = &BackendStatusArray[procNumber];
/*
* We bypass the changecount mechanism since fetching and storing an int
* is almost certainly atomic.
*/
return status->st_backendType;
}
/* ----------
* cmp_lbestatus
*

View file

@ -17,6 +17,7 @@
#include "access/clog.h"
#include "access/xlogdefs.h"
#include "lib/ilist.h"
#include "miscadmin.h"
#include "storage/latch.h"
#include "storage/lock.h"
#include "storage/pg_sema.h"
@ -166,7 +167,7 @@ typedef enum
* but its myProcLocks[] lists are valid.
*
* We allow many fields of this struct to be accessed without locks, such as
* delayChkptFlags and isRegularBackend. However, keep in mind that writing
* delayChkptFlags and backendType. However, keep in mind that writing
* mirrored ones (see below) requires holding ProcArrayLock or XidGenLock in
* at least shared mode, so that pgxactoff does not change concurrently.
*
@ -233,7 +234,7 @@ struct PGPROC
Oid tempNamespaceId; /* OID of temp schema this backend is
* using */
bool isRegularBackend; /* true if it's a regular backend. */
BackendType backendType; /* what kind of process is this? */
/*
* Info about LWLock the process is currently waiting for, if any.

View file

@ -331,7 +331,6 @@ extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
int buflen);
extern int64 pgstat_get_my_query_id(void);
extern int64 pgstat_get_my_plan_id(void);
extern BackendType pgstat_get_backend_type_by_proc_number(ProcNumber procNumber);
/* ----------