mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
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.
This commit is contained in:
@ -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))
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
||||
errmsg("database \"%s\" does not exist",
|
||||
dbname)));
|
||||
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",
|
||||
in_dbname)));
|
||||
/* our database name is gotten from the caller */
|
||||
strlcpy(dbname, in_dbname, NAMEDATALEN);
|
||||
}
|
||||
}
|
||||
|
||||
fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
|
||||
|
Reference in New Issue
Block a user