mirror of
https://github.com/postgres/postgres.git
synced 2025-05-28 05:21:27 +03:00
Reserve a PGPROC slot and semaphore for the slotsync worker process.
The need for this was missed in commit 93db6cbda, with the result being that if we launch a slotsync worker it would consume one of the PGPROCs in the max_connections pool. That could lead to inability to launch the worker, or to subsequent failures of connection requests that should have succeeded according to the configured settings. Rather than create some one-off infrastructure to support this, let's group the slotsync worker with the existing autovac launcher in a new category of "special worker" processes. These are kind of like auxiliary processes, but they cannot use that infrastructure because they need to be able to run transactions. For the moment, make these processes share the PGPROC freelist used for autovac workers (which previously supplied the autovac launcher too). This is partly to avoid an ABI change in v17, and partly because it seems silly to have a freelist with at most two members. This might be worth revisiting if we grow enough workers in this category. Tom Lane and Hou Zhijie. Back-patch to v17. Discussion: https://postgr.es/m/1808397.1735156190@sss.pgh.pa.us
This commit is contained in:
parent
a46311ed72
commit
14141bbbc1
@ -183,11 +183,12 @@ InitProcGlobal(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Create and initialize all the PGPROC structures we'll need. There are
|
* Create and initialize all the PGPROC structures we'll need. There are
|
||||||
* five separate consumers: (1) normal backends, (2) autovacuum workers
|
* six separate consumers: (1) normal backends, (2) autovacuum workers and
|
||||||
* and the autovacuum launcher, (3) background workers, (4) auxiliary
|
* special workers, (3) background workers, (4) walsenders, (5) auxiliary
|
||||||
* processes, and (5) prepared transactions. Each PGPROC structure is
|
* processes, and (6) prepared transactions. (For largely-historical
|
||||||
* dedicated to exactly one of these purposes, and they do not move
|
* reasons, we combine autovacuum and special workers into one category
|
||||||
* between groups.
|
* with a single freelist.) Each PGPROC structure is dedicated to exactly
|
||||||
|
* one of these purposes, and they do not move between groups.
|
||||||
*/
|
*/
|
||||||
procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
|
procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
|
||||||
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
|
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
|
||||||
@ -229,12 +230,13 @@ InitProcGlobal(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Newly created PGPROCs for normal backends, autovacuum and bgworkers
|
* Newly created PGPROCs for normal backends, autovacuum workers,
|
||||||
* must be queued up on the appropriate free list. Because there can
|
* special workers, bgworkers, and walsenders must be queued up on the
|
||||||
* only ever be a small, fixed number of auxiliary processes, no free
|
* appropriate free list. Because there can only ever be a small,
|
||||||
* list is used in that case; InitAuxiliaryProcess() instead uses a
|
* fixed number of auxiliary processes, no free list is used in that
|
||||||
* linear search. PGPROCs for prepared transactions are added to a
|
* case; InitAuxiliaryProcess() instead uses a linear search. PGPROCs
|
||||||
* free list by TwoPhaseShmemInit().
|
* for prepared transactions are added to a free list by
|
||||||
|
* TwoPhaseShmemInit().
|
||||||
*/
|
*/
|
||||||
if (i < MaxConnections)
|
if (i < MaxConnections)
|
||||||
{
|
{
|
||||||
@ -242,13 +244,13 @@ InitProcGlobal(void)
|
|||||||
dlist_push_tail(&ProcGlobal->freeProcs, &proc->links);
|
dlist_push_tail(&ProcGlobal->freeProcs, &proc->links);
|
||||||
proc->procgloballist = &ProcGlobal->freeProcs;
|
proc->procgloballist = &ProcGlobal->freeProcs;
|
||||||
}
|
}
|
||||||
else if (i < MaxConnections + autovacuum_max_workers + 1)
|
else if (i < MaxConnections + autovacuum_max_workers + NUM_SPECIAL_WORKER_PROCS)
|
||||||
{
|
{
|
||||||
/* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
|
/* PGPROC for AV or special worker, add to autovacFreeProcs list */
|
||||||
dlist_push_tail(&ProcGlobal->autovacFreeProcs, &proc->links);
|
dlist_push_tail(&ProcGlobal->autovacFreeProcs, &proc->links);
|
||||||
proc->procgloballist = &ProcGlobal->autovacFreeProcs;
|
proc->procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||||
}
|
}
|
||||||
else if (i < MaxConnections + autovacuum_max_workers + 1 + max_worker_processes)
|
else if (i < MaxConnections + autovacuum_max_workers + NUM_SPECIAL_WORKER_PROCS + max_worker_processes)
|
||||||
{
|
{
|
||||||
/* PGPROC for bgworker, add to bgworkerFreeProcs list */
|
/* PGPROC for bgworker, add to bgworkerFreeProcs list */
|
||||||
dlist_push_tail(&ProcGlobal->bgworkerFreeProcs, &proc->links);
|
dlist_push_tail(&ProcGlobal->bgworkerFreeProcs, &proc->links);
|
||||||
@ -307,8 +309,11 @@ InitProcess(void)
|
|||||||
if (MyProc != NULL)
|
if (MyProc != NULL)
|
||||||
elog(ERROR, "you already exist");
|
elog(ERROR, "you already exist");
|
||||||
|
|
||||||
/* Decide which list should supply our PGPROC. */
|
/*
|
||||||
if (AmAutoVacuumLauncherProcess() || AmAutoVacuumWorkerProcess())
|
* Decide which list should supply our PGPROC. This logic must match the
|
||||||
|
* way the freelists were constructed in InitProcGlobal().
|
||||||
|
*/
|
||||||
|
if (AmAutoVacuumWorkerProcess() || AmSpecialWorkerProcess())
|
||||||
procgloballist = &ProcGlobal->autovacFreeProcs;
|
procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||||
else if (AmBackgroundWorkerProcess())
|
else if (AmBackgroundWorkerProcess())
|
||||||
procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
||||||
|
@ -576,9 +576,9 @@ InitializeMaxBackends(void)
|
|||||||
{
|
{
|
||||||
Assert(MaxBackends == 0);
|
Assert(MaxBackends == 0);
|
||||||
|
|
||||||
/* the extra unit accounts for the autovacuum launcher */
|
/* Note that this does not include "auxiliary" processes */
|
||||||
MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
|
MaxBackends = MaxConnections + autovacuum_max_workers +
|
||||||
max_worker_processes + max_wal_senders;
|
max_worker_processes + max_wal_senders + NUM_SPECIAL_WORKER_PROCS;
|
||||||
|
|
||||||
/* internal error because the values were all checked previously */
|
/* internal error because the values were all checked previously */
|
||||||
if (MaxBackends > MAX_BACKENDS)
|
if (MaxBackends > MAX_BACKENDS)
|
||||||
|
@ -346,8 +346,9 @@ typedef enum BackendType
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Auxiliary processes. These have PGPROC entries, but they are not
|
* Auxiliary processes. These have PGPROC entries, but they are not
|
||||||
* attached to any particular database. There can be only one of each of
|
* attached to any particular database, and cannot run transactions or
|
||||||
* these running at a time.
|
* even take heavyweight locks. There can be only one of each of these
|
||||||
|
* running at a time.
|
||||||
*
|
*
|
||||||
* If you modify these, make sure to update NUM_AUXILIARY_PROCS and the
|
* If you modify these, make sure to update NUM_AUXILIARY_PROCS and the
|
||||||
* glossary in the docs.
|
* glossary in the docs.
|
||||||
@ -384,6 +385,10 @@ extern PGDLLIMPORT BackendType MyBackendType;
|
|||||||
#define AmWalSummarizerProcess() (MyBackendType == B_WAL_SUMMARIZER)
|
#define AmWalSummarizerProcess() (MyBackendType == B_WAL_SUMMARIZER)
|
||||||
#define AmWalWriterProcess() (MyBackendType == B_WAL_WRITER)
|
#define AmWalWriterProcess() (MyBackendType == B_WAL_WRITER)
|
||||||
|
|
||||||
|
#define AmSpecialWorkerProcess() \
|
||||||
|
(AmAutoVacuumLauncherProcess() || \
|
||||||
|
AmLogicalSlotSyncWorkerProcess())
|
||||||
|
|
||||||
extern const char *GetBackendTypeDesc(BackendType backendType);
|
extern const char *GetBackendTypeDesc(BackendType backendType);
|
||||||
|
|
||||||
extern void SetDatabasePath(const char *path);
|
extern void SetDatabasePath(const char *path);
|
||||||
|
@ -404,7 +404,7 @@ typedef struct PROC_HDR
|
|||||||
uint32 allProcCount;
|
uint32 allProcCount;
|
||||||
/* Head of list of free PGPROC structures */
|
/* Head of list of free PGPROC structures */
|
||||||
dlist_head freeProcs;
|
dlist_head freeProcs;
|
||||||
/* Head of list of autovacuum's free PGPROC structures */
|
/* Head of list of autovacuum & special worker free PGPROC structures */
|
||||||
dlist_head autovacFreeProcs;
|
dlist_head autovacFreeProcs;
|
||||||
/* Head of list of bgworker free PGPROC structures */
|
/* Head of list of bgworker free PGPROC structures */
|
||||||
dlist_head bgworkerFreeProcs;
|
dlist_head bgworkerFreeProcs;
|
||||||
@ -434,9 +434,19 @@ extern PGDLLIMPORT PGPROC *PreparedXactProcs;
|
|||||||
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
|
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
|
||||||
#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
|
#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We set aside some extra PGPROC structures for "special worker" processes,
|
||||||
|
* which are full-fledged backends (they can run transactions)
|
||||||
|
* but are unique animals that there's never more than one of.
|
||||||
|
* Currently there are two such processes: the autovacuum launcher
|
||||||
|
* and the slotsync worker.
|
||||||
|
*/
|
||||||
|
#define NUM_SPECIAL_WORKER_PROCS 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We set aside some extra PGPROC structures for auxiliary processes,
|
* We set aside some extra PGPROC structures for auxiliary processes,
|
||||||
* ie things that aren't full-fledged backends but need shmem access.
|
* ie things that aren't full-fledged backends (they cannot run transactions
|
||||||
|
* or take heavyweight locks) but need shmem access.
|
||||||
*
|
*
|
||||||
* Background writer, checkpointer, WAL writer, WAL summarizer, and archiver
|
* Background writer, checkpointer, WAL writer, WAL summarizer, and archiver
|
||||||
* run during normal operation. Startup process and WAL receiver also consume
|
* run during normal operation. Startup process and WAL receiver also consume
|
||||||
|
Loading…
x
Reference in New Issue
Block a user