1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Replace postmaster.c's own backend type codes with BackendType

Introduce a separate BackendType for dead-end children, so that we
don't need a separate dead_end flag.

Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://www.postgresql.org/message-id/a102f15f-eac4-4ff2-af02-f9ff209ec66f@iki.fi
This commit is contained in:
Heikki Linnakangas
2024-11-14 16:06:16 +02:00
parent a274bbb1b3
commit 18d67a8d7d
6 changed files with 168 additions and 116 deletions

View File

@ -174,6 +174,7 @@ static child_process_kind child_process_kinds[] = {
[B_INVALID] = {"invalid", NULL, false}, [B_INVALID] = {"invalid", NULL, false},
[B_BACKEND] = {"backend", BackendMain, true}, [B_BACKEND] = {"backend", BackendMain, true},
[B_DEAD_END_BACKEND] = {"dead-end backend", BackendMain, true},
[B_AUTOVAC_LAUNCHER] = {"autovacuum launcher", AutoVacLauncherMain, true}, [B_AUTOVAC_LAUNCHER] = {"autovacuum launcher", AutoVacLauncherMain, true},
[B_AUTOVAC_WORKER] = {"autovacuum worker", AutoVacWorkerMain, true}, [B_AUTOVAC_WORKER] = {"autovacuum worker", AutoVacWorkerMain, true},
[B_BG_WORKER] = {"bgworker", BackgroundWorkerMain, true}, [B_BG_WORKER] = {"bgworker", BackgroundWorkerMain, true},

View File

@ -126,15 +126,71 @@
/* /*
* Possible types of a backend. Beyond being the possible bkend_type values in * CountChildren and SignalChildren take a bitmask argument to represent
* struct bkend, these are OR-able request flag bits for SignalSomeChildren() * BackendTypes to count or signal. Define a separate type and functions to
* and CountChildren(). * work with the bitmasks, to avoid accidentally passing a plain BackendType
* in place of a bitmask or vice versa.
*/ */
#define BACKEND_TYPE_NORMAL 0x0001 /* normal backend */ typedef struct
#define BACKEND_TYPE_AUTOVAC 0x0002 /* autovacuum worker process */ {
#define BACKEND_TYPE_WALSND 0x0004 /* walsender process */ uint32 mask;
#define BACKEND_TYPE_BGWORKER 0x0008 /* bgworker process */ } BackendTypeMask;
#define BACKEND_TYPE_ALL 0x000F /* OR of all the above */
StaticAssertDecl(BACKEND_NUM_TYPES < 32, "too many backend types for uint32");
static const BackendTypeMask BTYPE_MASK_ALL = {(1 << BACKEND_NUM_TYPES) - 1};
#if 0 /* unused */
static const BackendTypeMask BTYPE_MASK_NONE = {0};
#endif
static inline BackendTypeMask
btmask(BackendType t)
{
BackendTypeMask mask = {.mask = 1 << t};
return mask;
}
#if 0 /* unused */
static inline BackendTypeMask
btmask_add(BackendTypeMask mask, BackendType t)
{
mask.mask |= 1 << t;
return mask;
}
#endif
static inline BackendTypeMask
btmask_del(BackendTypeMask mask, BackendType t)
{
mask.mask &= ~(1 << t);
return mask;
}
static inline BackendTypeMask
btmask_all_except(BackendType t)
{
BackendTypeMask mask = BTYPE_MASK_ALL;
mask = btmask_del(mask, t);
return mask;
}
static inline BackendTypeMask
btmask_all_except2(BackendType t1, BackendType t2)
{
BackendTypeMask mask = BTYPE_MASK_ALL;
mask = btmask_del(mask, t1);
mask = btmask_del(mask, t2);
return mask;
}
static inline bool
btmask_contains(BackendTypeMask mask, BackendType t)
{
return (mask.mask & (1 << t)) != 0;
}
/* /*
* List of active backends (or child processes anyway; we don't actually * List of active backends (or child processes anyway; we don't actually
@ -145,7 +201,7 @@
* As shown in the above set of backend types, this list includes not only * As shown in the above set of backend types, this list includes not only
* "normal" client sessions, but also autovacuum workers, walsenders, and * "normal" client sessions, but also autovacuum workers, walsenders, and
* background workers. (Note that at the time of launch, walsenders are * background workers. (Note that at the time of launch, walsenders are
* labeled BACKEND_TYPE_NORMAL; we relabel them to BACKEND_TYPE_WALSND * labeled B_BACKEND; we relabel them to B_WAL_SENDER
* upon noticing they've changed their PMChildFlags entry. Hence that check * upon noticing they've changed their PMChildFlags entry. Hence that check
* must be done before any operation that needs to distinguish walsenders * must be done before any operation that needs to distinguish walsenders
* from normal backends.) * from normal backends.)
@ -154,7 +210,7 @@
* the purpose of sending a friendly rejection message to a would-be client. * the purpose of sending a friendly rejection message to a would-be client.
* We must track them because they are attached to shared memory, but we know * We must track them because they are attached to shared memory, but we know
* they will never become live backends. dead_end children are not assigned a * they will never become live backends. dead_end children are not assigned a
* PMChildSlot. dead_end children have bkend_type NORMAL. * PMChildSlot. dead_end children have bkend_type B_DEAD_END_BACKEND.
* *
* "Special" children such as the startup, bgwriter, autovacuum launcher, and * "Special" children such as the startup, bgwriter, autovacuum launcher, and
* slot sync worker tasks are not in this list. They are tracked via StartupPID * slot sync worker tasks are not in this list. They are tracked via StartupPID
@ -166,8 +222,7 @@ typedef struct bkend
{ {
pid_t pid; /* process id of backend */ pid_t pid; /* process id of backend */
int child_slot; /* PMChildSlot for this backend, if any */ int child_slot; /* PMChildSlot for this backend, if any */
int bkend_type; /* child process flavor, see above */ BackendType bkend_type; /* child process flavor, see above */
bool dead_end; /* is it going to send an error and quit? */
RegisteredBgWorker *rw; /* bgworker info, if this is a bgworker */ RegisteredBgWorker *rw; /* bgworker info, if this is a bgworker */
bool bgworker_notify; /* gets bgworker start/stop notifications */ bool bgworker_notify; /* gets bgworker start/stop notifications */
dlist_node elem; /* list link in BackendList */ dlist_node elem; /* list link in BackendList */
@ -404,15 +459,12 @@ static void ExitPostmaster(int status) pg_attribute_noreturn();
static int ServerLoop(void); static int ServerLoop(void);
static int BackendStartup(ClientSocket *client_sock); static int BackendStartup(ClientSocket *client_sock);
static void report_fork_failure_to_client(ClientSocket *client_sock, int errnum); static void report_fork_failure_to_client(ClientSocket *client_sock, int errnum);
static CAC_state canAcceptConnections(int backend_type); static CAC_state canAcceptConnections(BackendType backend_type);
static void signal_child(pid_t pid, int signal); static void signal_child(pid_t pid, int signal);
static void sigquit_child(pid_t pid); static void sigquit_child(pid_t pid);
static bool SignalSomeChildren(int signal, int target); static bool SignalChildren(int signal, BackendTypeMask targetMask);
static void TerminateChildren(int signal); static void TerminateChildren(int signal);
static int CountChildren(BackendTypeMask targetMask);
#define SignalChildren(sig) SignalSomeChildren(sig, BACKEND_TYPE_ALL)
static int CountChildren(int target);
static Backend *assign_backendlist_entry(void); static Backend *assign_backendlist_entry(void);
static void LaunchMissingBackgroundProcesses(void); static void LaunchMissingBackgroundProcesses(void);
static void maybe_start_bgworkers(void); static void maybe_start_bgworkers(void);
@ -1751,12 +1803,12 @@ ServerLoop(void)
/* /*
* canAcceptConnections --- check to see if database state allows connections * canAcceptConnections --- check to see if database state allows connections
* of the specified type. backend_type can be BACKEND_TYPE_NORMAL, * of the specified type. backend_type can be B_BACKEND, B_AUTOVAC_WORKER, or
* BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet * B_BG_WORKER. (Note that we don't yet know whether a normal B_BACKEND
* know whether a NORMAL connection might turn into a walsender.) * connection might turn into a walsender.)
*/ */
static CAC_state static CAC_state
canAcceptConnections(int backend_type) canAcceptConnections(BackendType backend_type)
{ {
CAC_state result = CAC_OK; CAC_state result = CAC_OK;
@ -1767,7 +1819,7 @@ canAcceptConnections(int backend_type)
* bgworker_should_start_now() decided whether the DB state allows them. * bgworker_should_start_now() decided whether the DB state allows them.
*/ */
if (pmState != PM_RUN && pmState != PM_HOT_STANDBY && if (pmState != PM_RUN && pmState != PM_HOT_STANDBY &&
backend_type != BACKEND_TYPE_BGWORKER) backend_type != B_BG_WORKER)
{ {
if (Shutdown > NoShutdown) if (Shutdown > NoShutdown)
return CAC_SHUTDOWN; /* shutdown is pending */ return CAC_SHUTDOWN; /* shutdown is pending */
@ -1784,7 +1836,7 @@ canAcceptConnections(int backend_type)
* "Smart shutdown" restrictions are applied only to normal connections, * "Smart shutdown" restrictions are applied only to normal connections,
* not to autovac workers or bgworkers. * not to autovac workers or bgworkers.
*/ */
if (!connsAllowed && backend_type == BACKEND_TYPE_NORMAL) if (!connsAllowed && backend_type == B_BACKEND)
return CAC_SHUTDOWN; /* shutdown is pending */ return CAC_SHUTDOWN; /* shutdown is pending */
/* /*
@ -1799,7 +1851,7 @@ canAcceptConnections(int backend_type)
* The limit here must match the sizes of the per-child-process arrays; * The limit here must match the sizes of the per-child-process arrays;
* see comments for MaxLivePostmasterChildren(). * see comments for MaxLivePostmasterChildren().
*/ */
if (CountChildren(BACKEND_TYPE_ALL) >= MaxLivePostmasterChildren()) if (CountChildren(btmask_all_except(B_DEAD_END_BACKEND)) >= MaxLivePostmasterChildren())
result = CAC_TOOMANY; result = CAC_TOOMANY;
return result; return result;
@ -1968,7 +2020,7 @@ process_pm_reload_request(void)
ereport(LOG, ereport(LOG,
(errmsg("received SIGHUP, reloading configuration files"))); (errmsg("received SIGHUP, reloading configuration files")));
ProcessConfigFile(PGC_SIGHUP); ProcessConfigFile(PGC_SIGHUP);
SignalChildren(SIGHUP); SignalChildren(SIGHUP, btmask_all_except(B_DEAD_END_BACKEND));
if (StartupPID != 0) if (StartupPID != 0)
signal_child(StartupPID, SIGHUP); signal_child(StartupPID, SIGHUP);
if (BgWriterPID != 0) if (BgWriterPID != 0)
@ -2386,7 +2438,7 @@ process_pm_child_exit(void)
* Waken walsenders for the last time. No regular backends * Waken walsenders for the last time. No regular backends
* should be around anymore. * should be around anymore.
*/ */
SignalChildren(SIGUSR2); SignalChildren(SIGUSR2, btmask(B_WAL_SENDER));
pmState = PM_SHUTDOWN_2; pmState = PM_SHUTDOWN_2;
} }
@ -2552,23 +2604,19 @@ CleanupBackend(Backend *bp,
int exitstatus) /* child's exit status. */ int exitstatus) /* child's exit status. */
{ {
char namebuf[MAXPGPATH]; char namebuf[MAXPGPATH];
char *procname; const char *procname;
bool crashed = false; bool crashed = false;
bool logged = false; bool logged = false;
/* Construct a process name for log message */ /* Construct a process name for the log message */
if (bp->dead_end) if (bp->bkend_type == B_BG_WORKER)
{
procname = _("dead end backend");
}
else if (bp->bkend_type == BACKEND_TYPE_BGWORKER)
{ {
snprintf(namebuf, MAXPGPATH, _("background worker \"%s\""), snprintf(namebuf, MAXPGPATH, _("background worker \"%s\""),
bp->rw->rw_worker.bgw_type); bp->rw->rw_worker.bgw_type);
procname = namebuf; procname = namebuf;
} }
else else
procname = _("server process"); procname = _(GetBackendTypeDesc(bp->bkend_type));
/* /*
* If a backend dies in an ugly way then we must signal all other backends * If a backend dies in an ugly way then we must signal all other backends
@ -2600,7 +2648,7 @@ CleanupBackend(Backend *bp,
* If the process attached to shared memory, check that it detached * If the process attached to shared memory, check that it detached
* cleanly. * cleanly.
*/ */
if (!bp->dead_end) if (bp->bkend_type != B_DEAD_END_BACKEND)
{ {
if (!ReleasePostmasterChildSlot(bp->child_slot)) if (!ReleasePostmasterChildSlot(bp->child_slot))
{ {
@ -2633,7 +2681,7 @@ CleanupBackend(Backend *bp,
* If it was a background worker, also update its RegisteredBgWorker * If it was a background worker, also update its RegisteredBgWorker
* entry. * entry.
*/ */
if (bp->bkend_type == BACKEND_TYPE_BGWORKER) if (bp->bkend_type == B_BG_WORKER)
{ {
RegisteredBgWorker *rw = bp->rw; RegisteredBgWorker *rw = bp->rw;
@ -2861,7 +2909,7 @@ PostmasterStateMachine(void)
* This state ends when we have no normal client backends running. * This state ends when we have no normal client backends running.
* Then we're ready to stop other children. * Then we're ready to stop other children.
*/ */
if (CountChildren(BACKEND_TYPE_NORMAL) == 0) if (CountChildren(btmask(B_BACKEND)) == 0)
pmState = PM_STOP_BACKENDS; pmState = PM_STOP_BACKENDS;
} }
} }
@ -2880,9 +2928,8 @@ PostmasterStateMachine(void)
*/ */
ForgetUnstartedBackgroundWorkers(); ForgetUnstartedBackgroundWorkers();
/* Signal all backend children except walsenders */ /* Signal all backend children except walsenders and dead-end backends */
SignalSomeChildren(SIGTERM, SignalChildren(SIGTERM, btmask_all_except2(B_WAL_SENDER, B_DEAD_END_BACKEND));
BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND);
/* and the autovac launcher too */ /* and the autovac launcher too */
if (AutoVacPID != 0) if (AutoVacPID != 0)
signal_child(AutoVacPID, SIGTERM); signal_child(AutoVacPID, SIGTERM);
@ -2924,7 +2971,7 @@ PostmasterStateMachine(void)
* here. Walsenders and archiver are also disregarded, they will be * here. Walsenders and archiver are also disregarded, they will be
* terminated later after writing the checkpoint record. * terminated later after writing the checkpoint record.
*/ */
if (CountChildren(BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND) == 0 && if (CountChildren(btmask_all_except2(B_WAL_SENDER, B_DEAD_END_BACKEND)) == 0 &&
StartupPID == 0 && StartupPID == 0 &&
WalReceiverPID == 0 && WalReceiverPID == 0 &&
WalSummarizerPID == 0 && WalSummarizerPID == 0 &&
@ -2982,7 +3029,7 @@ PostmasterStateMachine(void)
pmState = PM_WAIT_DEAD_END; pmState = PM_WAIT_DEAD_END;
/* Kill the walsenders and archiver too */ /* Kill the walsenders and archiver too */
SignalChildren(SIGQUIT); SignalChildren(SIGQUIT, btmask_all_except(B_DEAD_END_BACKEND));
if (PgArchPID != 0) if (PgArchPID != 0)
signal_child(PgArchPID, SIGQUIT); signal_child(PgArchPID, SIGQUIT);
} }
@ -2998,7 +3045,7 @@ PostmasterStateMachine(void)
* left by now anyway; what we're really waiting for is walsenders and * left by now anyway; what we're really waiting for is walsenders and
* archiver. * archiver.
*/ */
if (PgArchPID == 0 && CountChildren(BACKEND_TYPE_ALL) == 0) if (PgArchPID == 0 && CountChildren(btmask_all_except(B_DEAD_END_BACKEND)) == 0)
{ {
pmState = PM_WAIT_DEAD_END; pmState = PM_WAIT_DEAD_END;
} }
@ -3296,11 +3343,10 @@ sigquit_child(pid_t pid)
} }
/* /*
* Send a signal to the targeted children (but NOT special children; * Send a signal to the targeted children (but NOT special children).
* dead_end children are never signaled, either).
*/ */
static bool static bool
SignalSomeChildren(int signal, int target) SignalChildren(int signal, BackendTypeMask targetMask)
{ {
dlist_iter iter; dlist_iter iter;
bool signaled = false; bool signaled = false;
@ -3309,30 +3355,24 @@ SignalSomeChildren(int signal, int target)
{ {
Backend *bp = dlist_container(Backend, elem, iter.cur); Backend *bp = dlist_container(Backend, elem, iter.cur);
if (bp->dead_end)
continue;
/* /*
* Since target == BACKEND_TYPE_ALL is the most common case, we test * If we need to distinguish between B_BACKEND and B_WAL_SENDER, check
* it first and avoid touching shared memory for every child. * if any B_BACKEND backends have recently announced that they are
* actually WAL senders.
*/ */
if (target != BACKEND_TYPE_ALL) if (btmask_contains(targetMask, B_WAL_SENDER) != btmask_contains(targetMask, B_BACKEND) &&
bp->bkend_type == B_BACKEND)
{ {
/* if (IsPostmasterChildWalSender(bp->child_slot))
* Assign bkend_type for any recently announced WAL Sender bp->bkend_type = B_WAL_SENDER;
* processes.
*/
if (bp->bkend_type == BACKEND_TYPE_NORMAL &&
IsPostmasterChildWalSender(bp->child_slot))
bp->bkend_type = BACKEND_TYPE_WALSND;
if (!(target & bp->bkend_type))
continue;
} }
if (!btmask_contains(targetMask, bp->bkend_type))
continue;
ereport(DEBUG4, ereport(DEBUG4,
(errmsg_internal("sending signal %d to process %d", (errmsg_internal("sending signal %d to %s process %d",
signal, (int) bp->pid))); signal, GetBackendTypeDesc(bp->bkend_type), (int) bp->pid)));
signal_child(bp->pid, signal); signal_child(bp->pid, signal);
signaled = true; signaled = true;
} }
@ -3346,7 +3386,7 @@ SignalSomeChildren(int signal, int target)
static void static void
TerminateChildren(int signal) TerminateChildren(int signal)
{ {
SignalChildren(signal); SignalChildren(signal, btmask_all_except(B_DEAD_END_BACKEND));
if (StartupPID != 0) if (StartupPID != 0)
{ {
signal_child(StartupPID, signal); signal_child(StartupPID, signal);
@ -3399,22 +3439,27 @@ BackendStartup(ClientSocket *client_sock)
} }
/* Pass down canAcceptConnections state */ /* Pass down canAcceptConnections state */
startup_data.canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL); startup_data.canAcceptConnections = canAcceptConnections(B_BACKEND);
bn->dead_end = (startup_data.canAcceptConnections != CAC_OK);
bn->rw = NULL; bn->rw = NULL;
/* /*
* Unless it's a dead_end child, assign it a child slot number * Unless it's a dead_end child, assign it a child slot number
*/ */
if (!bn->dead_end) if (startup_data.canAcceptConnections == CAC_OK)
{
bn->bkend_type = B_BACKEND; /* Can change later to B_WAL_SENDER */
bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot(); bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
}
else else
{
bn->bkend_type = B_DEAD_END_BACKEND;
bn->child_slot = 0; bn->child_slot = 0;
}
/* Hasn't asked to be notified about any bgworkers yet */ /* Hasn't asked to be notified about any bgworkers yet */
bn->bgworker_notify = false; bn->bgworker_notify = false;
pid = postmaster_child_launch(B_BACKEND, pid = postmaster_child_launch(bn->bkend_type,
(char *) &startup_data, sizeof(startup_data), (char *) &startup_data, sizeof(startup_data),
client_sock); client_sock);
if (pid < 0) if (pid < 0)
@ -3422,7 +3467,7 @@ BackendStartup(ClientSocket *client_sock)
/* in parent, fork failed */ /* in parent, fork failed */
int save_errno = errno; int save_errno = errno;
if (!bn->dead_end) if (bn->child_slot != 0)
(void) ReleasePostmasterChildSlot(bn->child_slot); (void) ReleasePostmasterChildSlot(bn->child_slot);
pfree(bn); pfree(bn);
errno = save_errno; errno = save_errno;
@ -3434,7 +3479,8 @@ BackendStartup(ClientSocket *client_sock)
/* in parent, successful fork */ /* in parent, successful fork */
ereport(DEBUG2, ereport(DEBUG2,
(errmsg_internal("forked new backend, pid=%d socket=%d", (errmsg_internal("forked new %s, pid=%d socket=%d",
GetBackendTypeDesc(bn->bkend_type),
(int) pid, (int) client_sock->sock))); (int) pid, (int) client_sock->sock)));
/* /*
@ -3442,7 +3488,6 @@ BackendStartup(ClientSocket *client_sock)
* of backends. * of backends.
*/ */
bn->pid = pid; bn->pid = pid;
bn->bkend_type = BACKEND_TYPE_NORMAL; /* Can change later to WALSND */
dlist_push_head(&BackendList, &bn->elem); dlist_push_head(&BackendList, &bn->elem);
return STATUS_OK; return STATUS_OK;
@ -3676,11 +3721,11 @@ dummy_handler(SIGNAL_ARGS)
} }
/* /*
* Count up number of child processes of specified types (dead_end children * Count up number of child processes of specified types (but NOT special
* are always excluded). * children).
*/ */
static int static int
CountChildren(int target) CountChildren(BackendTypeMask targetMask)
{ {
dlist_iter iter; dlist_iter iter;
int cnt = 0; int cnt = 0;
@ -3689,27 +3734,21 @@ CountChildren(int target)
{ {
Backend *bp = dlist_container(Backend, elem, iter.cur); Backend *bp = dlist_container(Backend, elem, iter.cur);
if (bp->dead_end)
continue;
/* /*
* Since target == BACKEND_TYPE_ALL is the most common case, we test * If we need to distinguish between B_BACKEND and B_WAL_SENDER, check
* it first and avoid touching shared memory for every child. * if any B_BACKEND backends have recently announced that they are
* actually WAL senders.
*/ */
if (target != BACKEND_TYPE_ALL) if (btmask_contains(targetMask, B_WAL_SENDER) != btmask_contains(targetMask, B_BACKEND) &&
bp->bkend_type == B_BACKEND)
{ {
/* if (IsPostmasterChildWalSender(bp->child_slot))
* Assign bkend_type for any recently announced WAL Sender bp->bkend_type = B_WAL_SENDER;
* processes.
*/
if (bp->bkend_type == BACKEND_TYPE_NORMAL &&
IsPostmasterChildWalSender(bp->child_slot))
bp->bkend_type = BACKEND_TYPE_WALSND;
if (!(target & bp->bkend_type))
continue;
} }
if (!btmask_contains(targetMask, bp->bkend_type))
continue;
cnt++; cnt++;
} }
return cnt; return cnt;
@ -3773,13 +3812,13 @@ StartAutovacuumWorker(void)
* we have to check to avoid race-condition problems during DB state * we have to check to avoid race-condition problems during DB state
* changes. * changes.
*/ */
if (canAcceptConnections(BACKEND_TYPE_AUTOVAC) == CAC_OK) if (canAcceptConnections(B_AUTOVAC_WORKER) == CAC_OK)
{ {
bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM); bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
if (bn) if (bn)
{ {
/* Autovac workers are not dead_end and need a child slot */ /* Autovac workers need a child slot */
bn->dead_end = false; bn->bkend_type = B_AUTOVAC_WORKER;
bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot(); bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
bn->bgworker_notify = false; bn->bgworker_notify = false;
bn->rw = NULL; bn->rw = NULL;
@ -3787,7 +3826,6 @@ StartAutovacuumWorker(void)
bn->pid = StartChildProcess(B_AUTOVAC_WORKER); bn->pid = StartChildProcess(B_AUTOVAC_WORKER);
if (bn->pid > 0) if (bn->pid > 0)
{ {
bn->bkend_type = BACKEND_TYPE_AUTOVAC;
dlist_push_head(&BackendList, &bn->elem); dlist_push_head(&BackendList, &bn->elem);
/* all OK */ /* all OK */
return; return;
@ -3993,7 +4031,7 @@ assign_backendlist_entry(void)
* only possible failure is CAC_TOOMANY, so we just log an error message * only possible failure is CAC_TOOMANY, so we just log an error message
* based on that rather than checking the error code precisely. * based on that rather than checking the error code precisely.
*/ */
if (canAcceptConnections(BACKEND_TYPE_BGWORKER) != CAC_OK) if (canAcceptConnections(B_BG_WORKER) != CAC_OK)
{ {
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED), (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
@ -4011,8 +4049,7 @@ assign_backendlist_entry(void)
} }
bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot(); bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
bn->bkend_type = BACKEND_TYPE_BGWORKER; bn->bkend_type = B_BG_WORKER;
bn->dead_end = false;
bn->bgworker_notify = false; bn->bgworker_notify = false;
return bn; return bn;

View File

@ -330,6 +330,8 @@ pgstat_io_snapshot_cb(void)
* *
* The following BackendTypes do not participate in the cumulative stats * The following BackendTypes do not participate in the cumulative stats
* subsystem or do not perform IO on which we currently track: * subsystem or do not perform IO on which we currently track:
* - Dead-end backend because it is not connected to shared memory and
* doesn't do any IO
* - Syslogger because it is not connected to shared memory * - Syslogger because it is not connected to shared memory
* - Archiver because most relevant archiving IO is delegated to a * - Archiver because most relevant archiving IO is delegated to a
* specialized command or module * specialized command or module
@ -352,6 +354,7 @@ pgstat_tracks_io_bktype(BackendType bktype)
switch (bktype) switch (bktype)
{ {
case B_INVALID: case B_INVALID:
case B_DEAD_END_BACKEND:
case B_ARCHIVER: case B_ARCHIVER:
case B_LOGGER: case B_LOGGER:
case B_WAL_RECEIVER: case B_WAL_RECEIVER:

View File

@ -260,60 +260,69 @@ SwitchBackToLocalLatch(void)
SetLatch(MyLatch); SetLatch(MyLatch);
} }
/*
* Return a human-readable string representation of a BackendType.
*
* The string is not localized here, but we mark the strings for translation
* so that callers can invoke _() on the result.
*/
const char * const char *
GetBackendTypeDesc(BackendType backendType) GetBackendTypeDesc(BackendType backendType)
{ {
const char *backendDesc = "unknown process type"; const char *backendDesc = gettext_noop("unknown process type");
switch (backendType) switch (backendType)
{ {
case B_INVALID: case B_INVALID:
backendDesc = "not initialized"; backendDesc = gettext_noop("not initialized");
break; break;
case B_ARCHIVER: case B_ARCHIVER:
backendDesc = "archiver"; backendDesc = gettext_noop("archiver");
break; break;
case B_AUTOVAC_LAUNCHER: case B_AUTOVAC_LAUNCHER:
backendDesc = "autovacuum launcher"; backendDesc = gettext_noop("autovacuum launcher");
break; break;
case B_AUTOVAC_WORKER: case B_AUTOVAC_WORKER:
backendDesc = "autovacuum worker"; backendDesc = gettext_noop("autovacuum worker");
break; break;
case B_BACKEND: case B_BACKEND:
backendDesc = "client backend"; backendDesc = gettext_noop("client backend");
break;
case B_DEAD_END_BACKEND:
backendDesc = gettext_noop("dead-end client backend");
break; break;
case B_BG_WORKER: case B_BG_WORKER:
backendDesc = "background worker"; backendDesc = gettext_noop("background worker");
break; break;
case B_BG_WRITER: case B_BG_WRITER:
backendDesc = "background writer"; backendDesc = gettext_noop("background writer");
break; break;
case B_CHECKPOINTER: case B_CHECKPOINTER:
backendDesc = "checkpointer"; backendDesc = gettext_noop("checkpointer");
break; break;
case B_LOGGER: case B_LOGGER:
backendDesc = "logger"; backendDesc = gettext_noop("logger");
break; break;
case B_SLOTSYNC_WORKER: case B_SLOTSYNC_WORKER:
backendDesc = "slotsync worker"; backendDesc = gettext_noop("slotsync worker");
break; break;
case B_STANDALONE_BACKEND: case B_STANDALONE_BACKEND:
backendDesc = "standalone backend"; backendDesc = gettext_noop("standalone backend");
break; break;
case B_STARTUP: case B_STARTUP:
backendDesc = "startup"; backendDesc = gettext_noop("startup");
break; break;
case B_WAL_RECEIVER: case B_WAL_RECEIVER:
backendDesc = "walreceiver"; backendDesc = gettext_noop("walreceiver");
break; break;
case B_WAL_SENDER: case B_WAL_SENDER:
backendDesc = "walsender"; backendDesc = gettext_noop("walsender");
break; break;
case B_WAL_SUMMARIZER: case B_WAL_SUMMARIZER:
backendDesc = "walsummarizer"; backendDesc = gettext_noop("walsummarizer");
break; break;
case B_WAL_WRITER: case B_WAL_WRITER:
backendDesc = "walwriter"; backendDesc = gettext_noop("walwriter");
break; break;
} }

View File

@ -333,6 +333,7 @@ typedef enum BackendType
/* Backends and other backend-like processes */ /* Backends and other backend-like processes */
B_BACKEND, B_BACKEND,
B_DEAD_END_BACKEND,
B_AUTOVAC_LAUNCHER, B_AUTOVAC_LAUNCHER,
B_AUTOVAC_WORKER, B_AUTOVAC_WORKER,
B_BG_WORKER, B_BG_WORKER,

View File

@ -235,6 +235,7 @@ BackendParameters
BackendStartupData BackendStartupData
BackendState BackendState
BackendType BackendType
BackendTypeMask
BackgroundWorker BackgroundWorker
BackgroundWorkerArray BackgroundWorkerArray
BackgroundWorkerHandle BackgroundWorkerHandle