Commit 00e6a16d authored by Tom Lane's avatar Tom Lane

Change the autovacuum launcher to read pg_database directly, rather than

via the "flat files" facility.  This requires making it enough like a backend
to be able to run transactions; it's no longer an "auxiliary process" but
more like the autovacuum worker processes.  Also, its signal handling has
to be brought into line with backends/workers.  In particular, since it
now has to handle procsignal.c processing, the special autovac-launcher-only
signal conditions are moved to SIGUSR2.

Alvaro, with some cleanup from Tom
parent 25ec228e
This diff is collapsed.
......@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.593 2009/08/29 19:26:51 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.594 2009/08/31 19:41:00 tgl Exp $
*
* NOTES
*
......@@ -1442,7 +1442,7 @@ ServerLoop(void)
{
avlauncher_needs_signal = false;
if (AutoVacPID != 0)
kill(AutoVacPID, SIGUSR1);
kill(AutoVacPID, SIGUSR2);
}
/*
......@@ -3865,7 +3865,7 @@ SubPostmasterMain(int argc, char *argv[])
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
InitAuxiliaryProcess();
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.208 2009/08/12 20:53:30 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.209 2009/08/31 19:41:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -102,7 +102,7 @@ ProcGlobalShmemSize(void)
size = add_size(size, sizeof(PROC_HDR));
/* AuxiliaryProcs */
size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGPROC)));
/* MyProcs, including autovacuum */
/* MyProcs, including autovacuum workers and launcher */
size = add_size(size, mul_size(MaxBackends, sizeof(PGPROC)));
/* ProcStructLock */
size = add_size(size, sizeof(slock_t));
......@@ -192,19 +192,27 @@ InitProcGlobal(void)
ProcGlobal->freeProcs = &procs[i];
}
procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers) * sizeof(PGPROC));
/*
* Likewise for the PGPROCs reserved for autovacuum.
*
* Note: the "+1" here accounts for the autovac launcher
*/
procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers + 1) * 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++)
MemSet(procs, 0, (autovacuum_max_workers + 1) * sizeof(PGPROC));
for (i = 0; i < autovacuum_max_workers + 1; i++)
{
PGSemaphoreCreate(&(procs[i].sem));
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
ProcGlobal->autovacFreeProcs = &procs[i];
}
/*
* And auxiliary procs.
*/
MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
for (i = 0; i < NUM_AUXILIARY_PROCS; i++)
{
......@@ -248,14 +256,14 @@ InitProcess(void)
set_spins_per_delay(procglobal->spins_per_delay);
if (IsAutoVacuumWorkerProcess())
if (IsAnyAutoVacuumProcess())
MyProc = procglobal->autovacFreeProcs;
else
MyProc = procglobal->freeProcs;
if (MyProc != NULL)
{
if (IsAutoVacuumWorkerProcess())
if (IsAnyAutoVacuumProcess())
procglobal->autovacFreeProcs = (PGPROC *) MyProc->links.next;
else
procglobal->freeProcs = (PGPROC *) MyProc->links.next;
......@@ -278,9 +286,10 @@ InitProcess(void)
/*
* Now that we have a PGPROC, mark ourselves as an active postmaster
* child; this is so that the postmaster can detect it if we exit without
* cleaning up.
* cleaning up. (XXX autovac launcher currently doesn't participate in
* this; it probably should.)
*/
if (IsUnderPostmaster)
if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess())
MarkPostmasterChildActive();
/*
......@@ -299,6 +308,7 @@ InitProcess(void)
MyProc->roleId = InvalidOid;
MyProc->inCommit = false;
MyProc->vacuumFlags = 0;
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
if (IsAutoVacuumWorkerProcess())
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
MyProc->lwWaiting = false;
......@@ -429,7 +439,6 @@ InitAuxiliaryProcess(void)
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inCommit = false;
/* we don't set the "is autovacuum" flag in the launcher */
MyProc->vacuumFlags = 0;
MyProc->lwWaiting = false;
MyProc->lwExclusive = false;
......@@ -595,8 +604,8 @@ ProcKill(int code, Datum arg)
SpinLockAcquire(ProcStructLock);
/* Return PGPROC structure (and semaphore) to freelist */
if (IsAutoVacuumWorkerProcess())
/* Return PGPROC structure (and semaphore) to appropriate freelist */
if (IsAnyAutoVacuumProcess())
{
MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
procglobal->autovacFreeProcs = MyProc;
......@@ -618,13 +627,14 @@ ProcKill(int code, Datum arg)
/*
* This process is no longer present in shared memory in any meaningful
* way, so tell the postmaster we've cleaned up acceptably well.
* (XXX autovac launcher should be included here someday)
*/
if (IsUnderPostmaster)
if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess())
MarkPostmasterChildInactive();
/* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
if (AutovacuumLauncherPid != 0)
kill(AutovacuumLauncherPid, SIGUSR1);
kill(AutovacuumLauncherPid, SIGUSR2);
}
/*
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.109 2009/08/28 18:23:53 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.110 2009/08/31 19:41:00 tgl Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
......@@ -100,8 +100,8 @@ int maintenance_work_mem = 16384;
/*
* Primary determinants of sizes of shared-memory structures. MaxBackends is
* MaxConnections + autovacuum_max_workers (it is computed by the GUC assign
* hook):
* MaxConnections + autovacuum_max_workers + 1 (it is computed by the GUC
* assign hooks for those variables):
*/
int NBuffers = 1000;
int MaxBackends = 100;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.195 2009/08/29 19:26:51 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.196 2009/08/31 19:41:00 tgl Exp $
*
*
*-------------------------------------------------------------------------
......@@ -460,7 +460,9 @@ BaseInit(void)
* name can be returned to the caller in out_dbname. If out_dbname isn't
* NULL, it must point to a buffer of size NAMEDATALEN.
*
* In bootstrap mode no parameters are used.
* In bootstrap mode no parameters are used. The autovacuum launcher process
* doesn't use any parameters either, because it only goes far enough to be
* able to read pg_database; it doesn't connect to any particular database.
*
* The return value indicates whether the userID is a superuser. (That
* can only be tested inside a transaction, so we want to do it during
......@@ -537,6 +539,12 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
if (!bootstrap)
pgstat_initialize();
/*
* Load relcache entries for the shared system catalogs. This must
* create at least an entry for pg_database.
*/
RelationCacheInitializePhase2();
/*
* Set up process-exit callback to do pre-shutdown cleanup. This has to
* be after we've initialized all the low-level modules like the buffer
......@@ -548,10 +556,17 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
*/
on_shmem_exit(ShutdownPostgres, 0);
/* The autovacuum launcher is done here */
if (IsAutoVacuumLauncherProcess())
return true; /* result doesn't matter */
/*
* Start a new transaction here before first access to db, and get a
* snapshot. We don't have a use for the snapshot itself, but we're
* interested in the secondary effect that it sets RecentGlobalXmin.
* (This is critical for anything that reads heap pages, because HOT
* may decide to prune them even if the process doesn't attempt to
* modify any tuples.)
*/
if (!bootstrap)
{
......@@ -559,12 +574,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
(void) GetTransactionSnapshot();
}
/*
* Load relcache entries for the shared system catalogs. This must
* create at least an entry for pg_database.
*/
RelationCacheInitializePhase2();
/*
* Set up the global variables holding database id and default tablespace.
* But note we won't actually try to touch the database just yet.
......
......@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.513 2009/08/31 02:23:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.514 2009/08/31 19:41:00 tgl Exp $
*
*--------------------------------------------------------------------
*/
......@@ -1335,7 +1335,7 @@ static struct config_int ConfigureNamesInt[] =
* Note: MaxBackends is limited to INT_MAX/4 because some places compute
* 4*MaxBackends without any overflow check. This check is made in
* assign_maxconnections, since MaxBackends is computed as MaxConnections
* plus autovacuum_max_workers.
* plus autovacuum_max_workers plus one (for the autovacuum launcher).
*
* Likewise we have to limit NBuffers to INT_MAX/2.
*/
......@@ -7570,11 +7570,11 @@ show_tcp_keepalives_count(void)
static bool
assign_maxconnections(int newval, bool doit, GucSource source)
{
if (newval + autovacuum_max_workers > INT_MAX / 4)
if (newval + autovacuum_max_workers + 1 > INT_MAX / 4)
return false;
if (doit)
MaxBackends = newval + autovacuum_max_workers;
MaxBackends = newval + autovacuum_max_workers + 1;
return true;
}
......@@ -7582,11 +7582,11 @@ assign_maxconnections(int newval, bool doit, GucSource source)
static bool
assign_autovacuum_max_workers(int newval, bool doit, GucSource source)
{
if (newval + MaxConnections > INT_MAX / 4)
if (MaxConnections + newval + 1 > INT_MAX / 4)
return false;
if (doit)
MaxBackends = newval + MaxConnections;
MaxBackends = MaxConnections + newval + 1;
return true;
}
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.15 2009/01/01 17:24:01 momjian Exp $
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.16 2009/08/31 19:41:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -37,6 +37,8 @@ extern int Log_autovacuum_min_duration;
extern bool AutoVacuumingActive(void);
extern bool IsAutoVacuumLauncherProcess(void);
extern bool IsAutoVacuumWorkerProcess(void);
#define IsAnyAutoVacuumProcess() \
(IsAutoVacuumLauncherProcess() || IsAutoVacuumWorkerProcess())
/* Functions to start autovacuum process, called from postmaster */
extern void autovac_init(void);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.113 2009/08/12 20:53:30 tgl Exp $
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.114 2009/08/31 19:41:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -141,12 +141,11 @@ typedef struct PROC_HDR
* We set aside some extra PGPROC structures for auxiliary processes,
* ie things that aren't full-fledged backends but need shmem access.
*
* Background writer, WAL writer, and autovacuum launcher run during
* normal operation. Startup process also consumes one slot, but WAL
* writer and autovacuum launcher are launched only after it has
* exited.
* Background writer and WAL writer run during normal operation. Startup
* process also consumes one slot, but WAL writer is launched only after
* startup has exited, so we only need 2 slots.
*/
#define NUM_AUXILIARY_PROCS 3
#define NUM_AUXILIARY_PROCS 2
/* configurable options */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment