Look up backend type in pg_signal_backend() more cheaply.
Commit ccd38024bc, which introduced the pg_signal_autovacuum_worker role, added a call to pgstat_get_beentry_by_proc_number() for the purpose of determining whether the process is an autovacuum worker. This function calls pgstat_read_current_status(), which can be fairly expensive and may return cached, out-of-date information. Since we just need to look up the target backend's BackendType, and we already know its ProcNumber, we can instead inspect the BackendStatusArray directly, which is much less expensive and possibly more up-to-date. There are some caveats with this approach (which are documented in the code), but it's still substantially better than before. Reported-by: Andres Freund Reviewed-by: Andres Freund Discussion: https://postgr.es/m/ujenaa2uabzfkwxwmfifawzdozh3ljr7geozlhftsuosgm7n7q%40g3utqqyyosb6
This commit is contained in:
parent
6a5bcf7f7d
commit
61171a632d
@ -88,9 +88,9 @@ pg_signal_backend(int pid, int sig)
|
||||
if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
|
||||
{
|
||||
ProcNumber procNumber = GetNumberFromPGProc(proc);
|
||||
PgBackendStatus *procStatus = pgstat_get_beentry_by_proc_number(procNumber);
|
||||
BackendType backendType = pgstat_get_backend_type_by_proc_number(procNumber);
|
||||
|
||||
if (procStatus && procStatus->st_backendType == B_AUTOVAC_WORKER)
|
||||
if (backendType == B_AUTOVAC_WORKER)
|
||||
{
|
||||
if (!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_AUTOVACUUM_WORKER))
|
||||
return SIGNAL_BACKEND_NOAUTOVAC;
|
||||
|
@ -1036,6 +1036,31 @@ pgstat_get_my_query_id(void)
|
||||
return MyBEEntry->st_query_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
|
||||
*
|
||||
|
@ -323,6 +323,7 @@ extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
|
||||
extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
|
||||
int buflen);
|
||||
extern uint64 pgstat_get_my_query_id(void);
|
||||
extern BackendType pgstat_get_backend_type_by_proc_number(ProcNumber procNumber);
|
||||
|
||||
|
||||
/* ----------
|
||||
|
Loading…
x
Reference in New Issue
Block a user