Commit 18206509 authored by Alvaro Herrera's avatar Alvaro Herrera

Restructure autovacuum in two processes: a dummy process, which runs

continuously, and requests vacuum runs of "autovacuum workers" to postmaster.
The workers do the actual vacuum work.  This allows for future improvements,
like allowing multiple autovacuum jobs running in parallel.

For now, the code keeps the original behavior of having a single autovac
process at any time by sleeping until the previous worker has finished.
parent eecbb332
......@@ -6,7 +6,7 @@
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.77 2007/01/05 22:19:23 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.78 2007/02/15 23:23:22 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -72,7 +72,7 @@ GetNewTransactionId(bool isSubXact)
* still gives plenty of chances before we get into real trouble.
*/
if (IsUnderPostmaster && (xid % 65536) == 0)
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC);
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
if (IsUnderPostmaster &&
TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidStopLimit))
......@@ -286,7 +286,7 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
*/
if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
IsUnderPostmaster)
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC);
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
/* Give an immediate warning if past the wrap warn point */
if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit))
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.230 2007/02/10 14:58:54 petere Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.231 2007/02/15 23:23:22 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -449,7 +449,7 @@ BootstrapMain(int argc, char *argv[])
* Do backend-like initialization for bootstrap mode
*/
InitProcess();
(void) InitPostgres(dbname, NULL);
(void) InitPostgres(dbname, InvalidOid, NULL, NULL);
/*
* In NOP mode, all we really want to do is create shared memory and
......
......@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.345 2007/02/05 04:22:18 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.346 2007/02/15 23:23:22 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -303,7 +303,7 @@ vacuum(VacuumStmt *vacstmt, List *relids)
* Send info about dead objects to the statistics collector, unless we are
* in autovacuum --- autovacuum.c does this for itself.
*/
if (vacstmt->vacuum && !IsAutoVacuumProcess())
if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
pgstat_vacuum_tabstat();
/*
......@@ -472,7 +472,7 @@ vacuum(VacuumStmt *vacstmt, List *relids)
ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
}
if (vacstmt->vacuum && !IsAutoVacuumProcess())
if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
{
/*
* Update pg_database.datfrozenxid, and truncate pg_clog if possible.
......
This diff is collapsed.
......@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.146 2007/02/09 16:12:18 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.147 2007/02/15 23:23:23 alvherre Exp $
* ----------
*/
#include "postgres.h"
......@@ -930,7 +930,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
msg.m_tableoid = tableoid;
msg.m_analyze = analyze;
msg.m_autovacuum = IsAutoVacuumProcess(); /* is this autovacuum? */
msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */
msg.m_vacuumtime = GetCurrentTimestamp();
msg.m_tuples = tuples;
pgstat_send(&msg, sizeof(msg));
......@@ -955,7 +955,7 @@ pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples,
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE);
msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
msg.m_tableoid = tableoid;
msg.m_autovacuum = IsAutoVacuumProcess(); /* is this autovacuum? */
msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */
msg.m_analyzetime = GetCurrentTimestamp();
msg.m_live_tuples = livetuples;
msg.m_dead_tuples = deadtuples;
......@@ -2280,8 +2280,8 @@ backend_read_statsfile(void)
return;
Assert(!pgStatRunningInCollector);
/* Autovacuum wants stats about all databases */
if (IsAutoVacuumProcess())
/* Autovacuum launcher wants stats about all databases */
if (IsAutoVacuumLauncherProcess())
pgStatDBHash = pgstat_read_statsfile(InvalidOid);
else
pgStatDBHash = pgstat_read_statsfile(MyDatabaseId);
......@@ -2319,8 +2319,8 @@ pgstat_setup_memcxt(void)
void
pgstat_clear_snapshot(void)
{
/* In an autovacuum process we keep the stats forever */
if (IsAutoVacuumProcess())
/* In an autovacuum worker process we keep the stats forever */
if (IsAutoVacuumWorkerProcess())
return;
/* Release memory, if any was allocated */
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.90 2007/01/05 22:19:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.91 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,6 +21,7 @@
#include "access/twophase.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/bgwriter.h"
#include "postmaster/postmaster.h"
#include "storage/freespace.h"
......@@ -109,6 +110,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
size = add_size(size, SInvalShmemSize());
size = add_size(size, FreeSpaceShmemSize());
size = add_size(size, BgWriterShmemSize());
size = add_size(size, AutoVacuumShmemSize());
size = add_size(size, BTreeShmemSize());
#ifdef EXEC_BACKEND
size = add_size(size, ShmemBackendArraySize());
......@@ -208,6 +210,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
*/
PMSignalInit();
BgWriterShmemInit();
AutoVacuumShmemInit();
/*
* Set up other modules that need some shared memory space
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.183 2007/01/16 13:28:56 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.184 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -259,7 +259,7 @@ InitProcess(void)
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inVacuum = false;
MyProc->isAutovacuum = IsAutoVacuumProcess();
MyProc->isAutovacuum = IsAutoVacuumWorkerProcess();
MyProc->lwWaiting = false;
MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL;
......@@ -392,7 +392,7 @@ InitDummyProcess(void)
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inVacuum = false;
MyProc->isAutovacuum = false;
MyProc->isAutovacuum = IsAutoVacuumLauncherProcess(); /* is this needed? */
MyProc->lwWaiting = false;
MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.522 2007/02/10 14:58:55 petere Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.523 2007/02/15 23:23:23 alvherre Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
......@@ -3139,7 +3139,7 @@ PostgresMain(int argc, char *argv[], const char *username)
*/
ereport(DEBUG3,
(errmsg_internal("InitPostgres")));
am_superuser = InitPostgres(dbname, username);
am_superuser = InitPostgres(dbname, InvalidOid, username, NULL);
SetProcessingMode(NormalProcessing);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.161 2007/02/01 19:10:28 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.162 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -401,7 +401,7 @@ InitializeSessionUserId(const char *rolename)
*
* We do not enforce them for the autovacuum process either.
*/
if (IsUnderPostmaster && !IsAutoVacuumProcess())
if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
{
/*
* Is role allowed to login at all?
......@@ -462,7 +462,7 @@ void
InitializeSessionUserIdStandalone(void)
{
/* This function should only be called in a single-user backend. */
AssertState(!IsUnderPostmaster || IsAutoVacuumProcess());
AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess());
/* call only once */
AssertState(!OidIsValid(AuthenticatedUserId));
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.173 2007/01/05 22:19:44 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.174 2007/02/15 23:23:23 alvherre Exp $
*
*
*-------------------------------------------------------------------------
......@@ -47,6 +47,7 @@
static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace);
static bool FindMyDatabaseByOid(Oid dbid, char *dbname, Oid *db_tablespace);
static void CheckMyDatabase(const char *name, bool am_superuser);
static void InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg);
......@@ -102,6 +103,48 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace)
return result;
}
/*
* FindMyDatabaseByOid
*
* As above, but the actual database Id is known. Return its name and the
* tablespace OID. Return TRUE if found, FALSE if not. The same restrictions
* as FindMyDatabase apply.
*/
static bool
FindMyDatabaseByOid(Oid dbid, char *dbname, Oid *db_tablespace)
{
bool result = false;
char *filename;
FILE *db_file;
Oid db_id;
char thisname[NAMEDATALEN];
TransactionId db_frozenxid;
filename = database_getflatfilename();
db_file = AllocateFile(filename, "r");
if (db_file == NULL)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not open file \"%s\": %m", filename)));
while (read_pg_database_line(db_file, thisname, &db_id,
db_tablespace, &db_frozenxid))
{
if (dbid == db_id)
{
result = true;
strlcpy(dbname, thisname, NAMEDATALEN);
break;
}
}
FreeFile(db_file);
pfree(filename);
return result;
}
/*
* CheckMyDatabase -- fetch information from the pg_database entry for our DB
*/
......@@ -135,9 +178,9 @@ CheckMyDatabase(const char *name, bool am_superuser)
* a way to recover from disabling all access to all databases, for
* example "UPDATE pg_database SET datallowconn = false;".
*
* We do not enforce them for the autovacuum process either.
* We do not enforce them for the autovacuum worker processes either.
*/
if (IsUnderPostmaster && !IsAutoVacuumProcess())
if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
{
/*
* Check that the database is currently allowing connections.
......@@ -270,8 +313,11 @@ BaseInit(void)
* InitPostgres
* Initialize POSTGRES.
*
* In bootstrap mode neither of the parameters are used. In autovacuum
* mode, the username parameter is not used.
* The database can be specified by name, using the in_dbname parameter, or by
* OID, using the dboid parameter. In the latter case, the computed database
* name is passed out to the caller as a palloc'ed string in out_dbname.
*
* In bootstrap mode no parameters are used.
*
* 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
......@@ -285,12 +331,14 @@ BaseInit(void)
* --------------------------------
*/
bool
InitPostgres(const char *dbname, const char *username)
InitPostgres(const char *in_dbname, Oid dboid, const char *username,
char **out_dbname)
{
bool bootstrap = IsBootstrapProcessingMode();
bool autovacuum = IsAutoVacuumProcess();
bool autovacuum = IsAutoVacuumWorkerProcess();
bool am_superuser;
char *fullpath;
char dbname[NAMEDATALEN];
/*
* Set up the global variables holding database id and path. But note we
......@@ -307,15 +355,32 @@ InitPostgres(const char *dbname, const char *username)
else
{
/*
* Find oid and tablespace of the database we're about to open. Since
* we're not yet up and running we have to use the hackish
* FindMyDatabase, which looks in the flat-file copy of pg_database.
* Find tablespace of the database we're about to open. Since we're not
* yet up and running we have to use one of the hackish FindMyDatabase
* variants, which look in the flat-file copy of pg_database.
*
* If the in_dbname param is NULL, lookup database by OID.
*/
if (!FindMyDatabase(dbname, &MyDatabaseId, &MyDatabaseTableSpace))
if (in_dbname == NULL)
{
if (!FindMyDatabaseByOid(dboid, dbname, &MyDatabaseTableSpace))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database %u does not exist", dboid)));
MyDatabaseId = dboid;
/* pass the database name to the caller */
*out_dbname = pstrdup(dbname);
}
else
{
if (!FindMyDatabase(in_dbname, &MyDatabaseId, &MyDatabaseTableSpace))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist",
dbname)));
in_dbname)));
/* our database name is gotten from the caller */
strlcpy(dbname, in_dbname, NAMEDATALEN);
}
}
fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.191 2007/01/05 22:19:50 momjian Exp $
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.192 2007/02/15 23:23:23 alvherre Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
......@@ -302,7 +302,8 @@ extern ProcessingMode Mode;
*****************************************************************************/
/* in utils/init/postinit.c */
extern bool InitPostgres(const char *dbname, const char *username);
extern bool InitPostgres(const char *in_dbname, Oid dboid, const char *username,
char **out_dbname);
extern void BaseInit(void);
/* in utils/init/miscinit.c */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.7 2007/01/16 13:28:57 alvherre Exp $
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.8 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,16 +27,23 @@ extern int autovacuum_vac_cost_limit;
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
extern bool IsAutoVacuumProcess(void);
extern bool IsAutoVacuumLauncherProcess(void);
extern bool IsAutoVacuumWorkerProcess(void);
/* Functions to start autovacuum process, called from postmaster */
extern void autovac_init(void);
extern int autovac_start(void);
extern void autovac_stopped(void);
extern int StartAutoVacLauncher(void);
extern int StartAutoVacWorker(void);
#ifdef EXEC_BACKEND
extern void AutoVacMain(int argc, char *argv[]);
extern void AutovacuumIAm(void);
extern void AutoVacLauncherMain(int argc, char *argv[]);
extern void AutoVacWorkerMain(int argc, char *argv[]);
extern void AutovacuumWorkerIAm(void);
extern void AutovacuumLauncherIAm(void);
#endif
/* shared memory stuff */
extern Size AutoVacuumShmemSize(void);
extern void AutoVacuumShmemInit(void);
#endif /* AUTOVACUUM_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.33 2007/01/05 22:19:58 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.34 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -61,6 +61,8 @@ typedef enum LWLockId
TablespaceCreateLock,
BtreeVacuumLock,
AddinShmemInitLock,
AutovacuumLock,
/* Individual lock IDs end here */
FirstBufMappingLock,
FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS,
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/pmsignal.h,v 1.16 2007/01/05 22:19:58 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/pmsignal.h,v 1.17 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -26,7 +26,8 @@ typedef enum
PMSIGNAL_WAKEN_CHILDREN, /* send a SIGUSR1 signal to all backends */
PMSIGNAL_WAKEN_ARCHIVER, /* send a NOTIFY signal to xlog archiver */
PMSIGNAL_ROTATE_LOGFILE, /* send SIGUSR1 to syslogger to rotate logfile */
PMSIGNAL_START_AUTOVAC, /* start an autovacuum iteration */
PMSIGNAL_START_AUTOVAC_LAUNCHER, /* start an autovacuum launcher */
PMSIGNAL_START_AUTOVAC_WORKER, /* start an autovacuum worker */
NUM_PMSIGNALS /* Must be last value of enum! */
} PMSignalReason;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.93 2007/01/16 13:28:57 alvherre Exp $
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.94 2007/02/15 23:23:23 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -121,7 +121,7 @@ typedef struct PROC_HDR
* We set aside some extra PGPROC structures for "dummy" processes,
* ie things that aren't full-fledged backends but need shmem access.
*/
#define NUM_DUMMY_PROCS 2
#define NUM_DUMMY_PROCS 3
/* 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