aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/lmgr/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/lmgr/proc.c')
-rw-r--r--src/backend/storage/lmgr/proc.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 2691a505826..e2b8f22d352 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.187 2007/04/03 16:34:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.188 2007/04/16 18:29:53 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -96,7 +96,7 @@ ProcGlobalShmemSize(void)
size = add_size(size, sizeof(PROC_HDR));
/* AuxiliaryProcs */
size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGPROC)));
- /* MyProcs */
+ /* MyProcs, including autovacuum */
size = add_size(size, mul_size(MaxBackends, sizeof(PGPROC)));
/* ProcStructLock */
size = add_size(size, sizeof(slock_t));
@@ -110,7 +110,10 @@ ProcGlobalShmemSize(void)
int
ProcGlobalSemas(void)
{
- /* We need a sema per backend, plus one for each auxiliary process. */
+ /*
+ * We need a sema per backend (including autovacuum), plus one for each
+ * auxiliary process.
+ */
return MaxBackends + NUM_AUXILIARY_PROCS;
}
@@ -127,8 +130,8 @@ ProcGlobalSemas(void)
* running out when trying to start another backend is a common failure.
* So, now we grab enough semaphores to support the desired max number
* of backends immediately at initialization --- if the sysadmin has set
- * MaxBackends higher than his kernel will support, he'll find out sooner
- * rather than later.
+ * MaxConnections or autovacuum_max_workers higher than his kernel will
+ * support, he'll find out sooner rather than later.
*
* Another reason for creating semaphores here is that the semaphore
* implementation typically requires us to create semaphores in the
@@ -163,25 +166,39 @@ InitProcGlobal(void)
* Initialize the data structures.
*/
ProcGlobal->freeProcs = INVALID_OFFSET;
+ ProcGlobal->autovacFreeProcs = INVALID_OFFSET;
ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
/*
* Pre-create the PGPROC structures and create a semaphore for each.
*/
- procs = (PGPROC *) ShmemAlloc(MaxBackends * sizeof(PGPROC));
+ procs = (PGPROC *) ShmemAlloc((MaxConnections) * sizeof(PGPROC));
if (!procs)
ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
- MemSet(procs, 0, MaxBackends * sizeof(PGPROC));
- for (i = 0; i < MaxBackends; i++)
+ MemSet(procs, 0, MaxConnections * sizeof(PGPROC));
+ for (i = 0; i < MaxConnections; i++)
{
PGSemaphoreCreate(&(procs[i].sem));
procs[i].links.next = ProcGlobal->freeProcs;
ProcGlobal->freeProcs = MAKE_OFFSET(&procs[i]);
}
+ procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers) * sizeof(PGPROC));
+ if (!procs)
+ ereport(FATAL,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of shared memory")));
+ MemSet(procs, 0, autovacuum_max_workers * sizeof(PGPROC));
+ for (i = 0; i < autovacuum_max_workers; i++)
+ {
+ PGSemaphoreCreate(&(procs[i].sem));
+ procs[i].links.next = ProcGlobal->autovacFreeProcs;
+ ProcGlobal->autovacFreeProcs = MAKE_OFFSET(&procs[i]);
+ }
+
MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
for (i = 0; i < NUM_AUXILIARY_PROCS; i++)
{
@@ -226,12 +243,18 @@ InitProcess(void)
set_spins_per_delay(procglobal->spins_per_delay);
- myOffset = procglobal->freeProcs;
+ if (IsAutoVacuumWorkerProcess())
+ myOffset = procglobal->autovacFreeProcs;
+ else
+ myOffset = procglobal->freeProcs;
if (myOffset != INVALID_OFFSET)
{
MyProc = (PGPROC *) MAKE_PTR(myOffset);
- procglobal->freeProcs = MyProc->links.next;
+ if (IsAutoVacuumWorkerProcess())
+ procglobal->autovacFreeProcs = MyProc->links.next;
+ else
+ procglobal->freeProcs = MyProc->links.next;
SpinLockRelease(ProcStructLock);
}
else
@@ -239,7 +262,8 @@ InitProcess(void)
/*
* If we reach here, all the PGPROCs are in use. This is one of the
* possible places to detect "too many backends", so give the standard
- * error message.
+ * error message. XXX do we need to give a different failure message
+ * in the autovacuum case?
*/
SpinLockRelease(ProcStructLock);
ereport(FATAL,
@@ -571,8 +595,16 @@ ProcKill(int code, Datum arg)
SpinLockAcquire(ProcStructLock);
/* Return PGPROC structure (and semaphore) to freelist */
- MyProc->links.next = procglobal->freeProcs;
- procglobal->freeProcs = MAKE_OFFSET(MyProc);
+ if (IsAutoVacuumWorkerProcess())
+ {
+ MyProc->links.next = procglobal->autovacFreeProcs;
+ procglobal->autovacFreeProcs = MAKE_OFFSET(MyProc);
+ }
+ else
+ {
+ MyProc->links.next = procglobal->freeProcs;
+ procglobal->freeProcs = MAKE_OFFSET(MyProc);
+ }
/* PGPROC struct isn't mine anymore */
MyProc = NULL;
@@ -581,6 +613,10 @@ ProcKill(int code, Datum arg)
procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay);
SpinLockRelease(ProcStructLock);
+
+ /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
+ if (AutovacuumLauncherPid != 0)
+ kill(AutovacuumLauncherPid, SIGUSR1);
}
/*