mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Add background worker type
Add bgw_type field to background worker structure. It is intended to be set to the same value for all workers of the same type, so they can be grouped in pg_stat_activity, for example. The backend_type column in pg_stat_activity now shows bgw_type for a background worker. The ps listing also no longer calls out that a process is a background worker but just show the bgw_type. That way, being a background worker is more of an implementation detail now that is not shown to the user. However, most log messages still refer to 'background worker "%s"'; otherwise constructing sensible and translatable log messages would become tricky. Reviewed-by: Michael Paquier <michael.paquier@gmail.com> Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
This commit is contained in:
parent
8b304b8b72
commit
5373bc2a08
@ -800,7 +800,8 @@ apw_start_master_worker(void)
|
||||
worker.bgw_start_time = BgWorkerStart_ConsistentState;
|
||||
strcpy(worker.bgw_library_name, "pg_prewarm");
|
||||
strcpy(worker.bgw_function_name, "autoprewarm_main");
|
||||
strcpy(worker.bgw_name, "autoprewarm");
|
||||
strcpy(worker.bgw_name, "autoprewarm master");
|
||||
strcpy(worker.bgw_type, "autoprewarm master");
|
||||
|
||||
if (process_shared_preload_libraries_in_progress)
|
||||
{
|
||||
@ -840,7 +841,8 @@ apw_start_database_worker(void)
|
||||
worker.bgw_start_time = BgWorkerStart_ConsistentState;
|
||||
strcpy(worker.bgw_library_name, "pg_prewarm");
|
||||
strcpy(worker.bgw_function_name, "autoprewarm_database_main");
|
||||
strcpy(worker.bgw_name, "autoprewarm");
|
||||
strcpy(worker.bgw_name, "autoprewarm worker");
|
||||
strcpy(worker.bgw_type, "autoprewarm worker");
|
||||
|
||||
/* must set notify PID to wait for shutdown */
|
||||
worker.bgw_notify_pid = MyProcPid;
|
||||
|
@ -51,6 +51,7 @@ typedef void (*bgworker_main_type)(Datum main_arg);
|
||||
typedef struct BackgroundWorker
|
||||
{
|
||||
char bgw_name[BGW_MAXLEN];
|
||||
char bgw_type[BGW_MAXLEN];
|
||||
int bgw_flags;
|
||||
BgWorkerStartTime bgw_start_time;
|
||||
int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
|
||||
@ -64,8 +65,14 @@ typedef struct BackgroundWorker
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<structfield>bgw_name</> is a string to be used in log messages, process
|
||||
listings and similar contexts.
|
||||
<structfield>bgw_name</> and <structfield>bgw_type</structfield> are
|
||||
strings to be used in log messages, process listings and similar contexts.
|
||||
<structfield>bgw_type</structfield> should be the same for all background
|
||||
workers of the same type, so that it is possible to group such workers in a
|
||||
process listing, for example. <structfield>bgw_name</structfield> on the
|
||||
other hand can contain additional information about the specific process.
|
||||
(Typically, the string for <structfield>bgw_name</structfield> will contain
|
||||
the type somehow, but that is not strictly required.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -467,6 +467,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
|
||||
memset(&worker, 0, sizeof(worker));
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "parallel worker for PID %d",
|
||||
MyProcPid);
|
||||
snprintf(worker.bgw_type, BGW_MAXLEN, "parallel worker");
|
||||
worker.bgw_flags =
|
||||
BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION
|
||||
| BGWORKER_CLASS_PARALLEL;
|
||||
|
@ -344,6 +344,8 @@ BackgroundWorkerStateChange(void)
|
||||
*/
|
||||
ascii_safe_strlcpy(rw->rw_worker.bgw_name,
|
||||
slot->worker.bgw_name, BGW_MAXLEN);
|
||||
ascii_safe_strlcpy(rw->rw_worker.bgw_type,
|
||||
slot->worker.bgw_type, BGW_MAXLEN);
|
||||
ascii_safe_strlcpy(rw->rw_worker.bgw_library_name,
|
||||
slot->worker.bgw_library_name, BGW_MAXLEN);
|
||||
ascii_safe_strlcpy(rw->rw_worker.bgw_function_name,
|
||||
@ -630,6 +632,12 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If bgw_type is not filled in, use bgw_name.
|
||||
*/
|
||||
if (strcmp(worker->bgw_type, "") == 0)
|
||||
strcpy(worker->bgw_type, worker->bgw_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -671,7 +679,7 @@ bgworker_die(SIGNAL_ARGS)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_ADMIN_SHUTDOWN),
|
||||
errmsg("terminating background worker \"%s\" due to administrator command",
|
||||
MyBgworkerEntry->bgw_name)));
|
||||
MyBgworkerEntry->bgw_type)));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -700,7 +708,6 @@ void
|
||||
StartBackgroundWorker(void)
|
||||
{
|
||||
sigjmp_buf local_sigjmp_buf;
|
||||
char buf[MAXPGPATH];
|
||||
BackgroundWorker *worker = MyBgworkerEntry;
|
||||
bgworker_main_type entrypt;
|
||||
|
||||
@ -710,8 +717,7 @@ StartBackgroundWorker(void)
|
||||
IsBackgroundWorker = true;
|
||||
|
||||
/* Identify myself via ps */
|
||||
snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name);
|
||||
init_ps_display(buf, "", "", "");
|
||||
init_ps_display(worker->bgw_name, "", "", "");
|
||||
|
||||
/*
|
||||
* If we're not supposed to have shared memory access, then detach from
|
||||
@ -1233,3 +1239,40 @@ LookupBackgroundWorkerFunction(const char *libraryname, const char *funcname)
|
||||
return (bgworker_main_type)
|
||||
load_external_function(libraryname, funcname, true, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a PID, get the bgw_type of the background worker. Returns NULL if
|
||||
* not a valid background worker.
|
||||
*
|
||||
* The return value is in static memory belonging to this function, so it has
|
||||
* to be used before calling this function again. This is so that the caller
|
||||
* doesn't have to worry about the background worker locking protocol.
|
||||
*/
|
||||
const char *
|
||||
GetBackgroundWorkerTypeByPid(pid_t pid)
|
||||
{
|
||||
int slotno;
|
||||
bool found = false;
|
||||
static char result[BGW_MAXLEN];
|
||||
|
||||
LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
|
||||
|
||||
for (slotno = 0; slotno < BackgroundWorkerData->total_slots; slotno++)
|
||||
{
|
||||
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
|
||||
|
||||
if (slot->pid > 0 && slot->pid == pid)
|
||||
{
|
||||
strcpy(result, slot->worker.bgw_type);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LWLockRelease(BackgroundWorkerLock);
|
||||
|
||||
if (!found)
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -3117,8 +3117,9 @@ CleanupBackgroundWorker(int pid,
|
||||
exitstatus = 0;
|
||||
#endif
|
||||
|
||||
snprintf(namebuf, MAXPGPATH, "%s: %s", _("worker process"),
|
||||
rw->rw_worker.bgw_name);
|
||||
snprintf(namebuf, MAXPGPATH, _("background worker \"%s\""),
|
||||
rw->rw_worker.bgw_type);
|
||||
|
||||
|
||||
if (!EXIT_STATUS_0(exitstatus))
|
||||
{
|
||||
|
@ -422,6 +422,7 @@ retry:
|
||||
else
|
||||
snprintf(bgw.bgw_name, BGW_MAXLEN,
|
||||
"logical replication worker for subscription %u", subid);
|
||||
snprintf(bgw.bgw_type, BGW_MAXLEN, "logical replication worker");
|
||||
|
||||
bgw.bgw_restart_time = BGW_NEVER_RESTART;
|
||||
bgw.bgw_notify_pid = MyProcPid;
|
||||
@ -775,6 +776,8 @@ ApplyLauncherRegister(void)
|
||||
snprintf(bgw.bgw_function_name, BGW_MAXLEN, "ApplyLauncherMain");
|
||||
snprintf(bgw.bgw_name, BGW_MAXLEN,
|
||||
"logical replication launcher");
|
||||
snprintf(bgw.bgw_type, BGW_MAXLEN,
|
||||
"logical replication launcher");
|
||||
bgw.bgw_restart_time = 5;
|
||||
bgw.bgw_notify_pid = 0;
|
||||
bgw.bgw_main_arg = (Datum) 0;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "funcapi.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "postmaster/bgworker_internals.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
@ -823,8 +824,19 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
|
||||
}
|
||||
}
|
||||
/* Add backend type */
|
||||
values[17] =
|
||||
CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType));
|
||||
if (beentry->st_backendType == B_BG_WORKER)
|
||||
{
|
||||
const char *bgw_type;
|
||||
|
||||
bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
|
||||
if (bgw_type)
|
||||
values[17] = CStringGetTextDatum(bgw_type);
|
||||
else
|
||||
nulls[17] = true;
|
||||
}
|
||||
else
|
||||
values[17] =
|
||||
CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -88,6 +88,7 @@ typedef enum
|
||||
typedef struct BackgroundWorker
|
||||
{
|
||||
char bgw_name[BGW_MAXLEN];
|
||||
char bgw_type[BGW_MAXLEN];
|
||||
int bgw_flags;
|
||||
BgWorkerStartTime bgw_start_time;
|
||||
int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
|
||||
@ -122,6 +123,7 @@ extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle,
|
||||
extern BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pid);
|
||||
extern BgwHandleStatus
|
||||
WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *);
|
||||
extern const char *GetBackgroundWorkerTypeByPid(pid_t pid);
|
||||
|
||||
/* Terminate a bgworker */
|
||||
extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle);
|
||||
|
@ -219,7 +219,7 @@ setup_background_workers(int nworkers, dsm_segment *seg)
|
||||
worker.bgw_restart_time = BGW_NEVER_RESTART;
|
||||
sprintf(worker.bgw_library_name, "test_shm_mq");
|
||||
sprintf(worker.bgw_function_name, "test_shm_mq_main");
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "test_shm_mq");
|
||||
snprintf(worker.bgw_type, BGW_MAXLEN, "test_shm_mq");
|
||||
worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(seg));
|
||||
/* set bgw_notify_pid, so we can detect if the worker stops */
|
||||
worker.bgw_notify_pid = MyProcPid;
|
||||
|
@ -111,7 +111,7 @@ initialize_worker_spi(worktable *table)
|
||||
StartTransactionCommand();
|
||||
SPI_connect();
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
pgstat_report_activity(STATE_RUNNING, "initializing spi_worker schema");
|
||||
pgstat_report_activity(STATE_RUNNING, "initializing worker_spi schema");
|
||||
|
||||
/* XXX could we use CREATE SCHEMA IF NOT EXISTS? */
|
||||
initStringInfo(&buf);
|
||||
@ -359,7 +359,8 @@ _PG_init(void)
|
||||
*/
|
||||
for (i = 1; i <= worker_spi_total_workers; i++)
|
||||
{
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i);
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "worker_spi worker %d", i);
|
||||
snprintf(worker.bgw_type, BGW_MAXLEN, "worker_spi");
|
||||
worker.bgw_main_arg = Int32GetDatum(i);
|
||||
|
||||
RegisterBackgroundWorker(&worker);
|
||||
@ -385,7 +386,8 @@ worker_spi_launch(PG_FUNCTION_ARGS)
|
||||
worker.bgw_restart_time = BGW_NEVER_RESTART;
|
||||
sprintf(worker.bgw_library_name, "worker_spi");
|
||||
sprintf(worker.bgw_function_name, "worker_spi_main");
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i);
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "worker_spi worker %d", i);
|
||||
snprintf(worker.bgw_type, BGW_MAXLEN, "worker_spi");
|
||||
worker.bgw_main_arg = Int32GetDatum(i);
|
||||
/* set bgw_notify_pid so that we can use WaitForBackgroundWorkerStartup */
|
||||
worker.bgw_notify_pid = MyProcPid;
|
||||
|
Loading…
Reference in New Issue
Block a user