Commit eb63cc3d authored by Alvaro Herrera's avatar Alvaro Herrera

Arrange for autovacuum to be killed when another operation wants to be alone

accessing it, like DROP DATABASE.  This allows the regression tests to pass
with autovacuum enabled, which open the gates for finally enabling autovacuum
by default.
parent 02609893
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.26 2007/01/05 22:19:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.27 2007/01/16 13:28:56 alvherre Exp $
* *
* NOTES * NOTES
* Each global transaction is associated with a global transaction * Each global transaction is associated with a global transaction
...@@ -280,6 +280,7 @@ MarkAsPreparing(TransactionId xid, const char *gid, ...@@ -280,6 +280,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
gxact->proc.databaseId = databaseid; gxact->proc.databaseId = databaseid;
gxact->proc.roleId = owner; gxact->proc.roleId = owner;
gxact->proc.inVacuum = false; gxact->proc.inVacuum = false;
gxact->proc.isAutovacuum = false;
gxact->proc.lwWaiting = false; gxact->proc.lwWaiting = false;
gxact->proc.lwExclusive = false; gxact->proc.lwExclusive = false;
gxact->proc.lwWaitLink = NULL; gxact->proc.lwWaitLink = NULL;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.188 2007/01/05 22:19:25 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.189 2007/01/16 13:28:56 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -250,7 +250,7 @@ createdb(const CreatedbStmt *stmt) ...@@ -250,7 +250,7 @@ createdb(const CreatedbStmt *stmt)
* (exception is to allow CREATE DB while connected to template1). * (exception is to allow CREATE DB while connected to template1).
* Otherwise we might copy inconsistent data. * Otherwise we might copy inconsistent data.
*/ */
if (DatabaseHasActiveBackends(src_dboid, true)) if (DatabaseCancelAutovacuumActivity(src_dboid, true))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE), (errcode(ERRCODE_OBJECT_IN_USE),
errmsg("source database \"%s\" is being accessed by other users", errmsg("source database \"%s\" is being accessed by other users",
...@@ -602,7 +602,7 @@ dropdb(const char *dbname, bool missing_ok) ...@@ -602,7 +602,7 @@ dropdb(const char *dbname, bool missing_ok)
* Check for active backends in the target database. (Because we hold the * Check for active backends in the target database. (Because we hold the
* database lock, no new ones can start after this.) * database lock, no new ones can start after this.)
*/ */
if (DatabaseHasActiveBackends(db_id, false)) if (DatabaseCancelAutovacuumActivity(db_id, false))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE), (errcode(ERRCODE_OBJECT_IN_USE),
errmsg("database \"%s\" is being accessed by other users", errmsg("database \"%s\" is being accessed by other users",
...@@ -706,7 +706,7 @@ RenameDatabase(const char *oldname, const char *newname) ...@@ -706,7 +706,7 @@ RenameDatabase(const char *oldname, const char *newname)
* Make sure the database does not have active sessions. This is the same * Make sure the database does not have active sessions. This is the same
* concern as above, but applied to other sessions. * concern as above, but applied to other sessions.
*/ */
if (DatabaseHasActiveBackends(db_id, false)) if (DatabaseCancelAutovacuumActivity(db_id, false))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE), (errcode(ERRCODE_OBJECT_IN_USE),
errmsg("database \"%s\" is being accessed by other users", errmsg("database \"%s\" is being accessed by other users",
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.30 2007/01/05 22:19:36 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.31 2007/01/16 13:28:56 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -216,6 +216,15 @@ autovac_forkexec(void) ...@@ -216,6 +216,15 @@ autovac_forkexec(void)
return postmaster_forkexec(ac, av); return postmaster_forkexec(ac, av);
} }
/*
* We need this set from the outside, before InitProcess is called
*/
void
AutovacuumIAm(void)
{
am_autovacuum = true;
}
#endif /* EXEC_BACKEND */ #endif /* EXEC_BACKEND */
/* /*
...@@ -307,8 +316,8 @@ AutoVacMain(int argc, char *argv[]) ...@@ -307,8 +316,8 @@ AutoVacMain(int argc, char *argv[])
EmitErrorReport(); EmitErrorReport();
/* /*
* We can now go away. Note that because we'll call InitProcess, a * We can now go away. Note that because we called InitProcess, a
* callback will be registered to do ProcKill, which will clean up * callback was registered to do ProcKill, which will clean up
* necessary state. * necessary state.
*/ */
proc_exit(0); proc_exit(0);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.507 2007/01/05 22:19:36 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.508 2007/01/16 13:28:56 alvherre Exp $
* *
* NOTES * NOTES
* *
...@@ -3298,6 +3298,10 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3298,6 +3298,10 @@ SubPostmasterMain(int argc, char *argv[])
strcmp(argv[1], "--forkboot") == 0) strcmp(argv[1], "--forkboot") == 0)
PGSharedMemoryReAttach(); PGSharedMemoryReAttach();
/* autovacuum needs this set before calling InitProcess */
if (strcmp(argv[1], "--forkautovac") == 0)
AutovacuumIAm();
/* /*
* Start our win32 signal implementation. This has to be done after we * Start our win32 signal implementation. This has to be done after we
* read the backend variables, because we need to pick up the signal pipe * read the backend variables, because we need to pick up the signal pipe
......
...@@ -23,12 +23,14 @@ ...@@ -23,12 +23,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.20 2007/01/05 22:19:38 momjian Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.21 2007/01/16 13:28:56 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <signal.h>
#include "access/subtrans.h" #include "access/subtrans.h"
#include "access/transam.h" #include "access/transam.h"
#include "access/xact.h" #include "access/xact.h"
...@@ -678,7 +680,9 @@ GetSnapshotData(Snapshot snapshot, bool serializable) ...@@ -678,7 +680,9 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
} }
/* /*
* DatabaseHasActiveBackends -- are there any backends running in the given DB * DatabaseCancelAutovacuumActivity -- are there any backends running in the
* given DB, apart from autovacuum? If an autovacuum process is running on the
* database, kill it and restart the counting.
* *
* If 'ignoreMyself' is TRUE, ignore this particular backend while checking * If 'ignoreMyself' is TRUE, ignore this particular backend while checking
* for backends in the target database. * for backends in the target database.
...@@ -691,11 +695,16 @@ GetSnapshotData(Snapshot snapshot, bool serializable) ...@@ -691,11 +695,16 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
* backend startup. * backend startup.
*/ */
bool bool
DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself) DatabaseCancelAutovacuumActivity(Oid databaseId, bool ignoreMyself)
{ {
bool result = false;
ProcArrayStruct *arrayP = procArray; ProcArrayStruct *arrayP = procArray;
int index; int index;
int num;
restart:
num = 0;
CHECK_FOR_INTERRUPTS();
LWLockAcquire(ProcArrayLock, LW_SHARED); LWLockAcquire(ProcArrayLock, LW_SHARED);
...@@ -708,14 +717,22 @@ DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself) ...@@ -708,14 +717,22 @@ DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
if (ignoreMyself && proc == MyProc) if (ignoreMyself && proc == MyProc)
continue; continue;
result = true; num++;
break;
if (proc->isAutovacuum)
{
/* an autovacuum -- kill it and restart */
LWLockRelease(ProcArrayLock);
kill(proc->pid, SIGINT);
pg_usleep(100 * 1000); /* 100ms */
goto restart;
}
} }
} }
LWLockRelease(ProcArrayLock); LWLockRelease(ProcArrayLock);
return result; return (num != 0);
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.182 2007/01/05 22:19:38 momjian Exp $ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.183 2007/01/16 13:28:56 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "access/transam.h" #include "access/transam.h"
#include "access/xact.h" #include "access/xact.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/autovacuum.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/proc.h" #include "storage/proc.h"
#include "storage/procarray.h" #include "storage/procarray.h"
...@@ -258,6 +259,7 @@ InitProcess(void) ...@@ -258,6 +259,7 @@ InitProcess(void)
MyProc->databaseId = InvalidOid; MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid; MyProc->roleId = InvalidOid;
MyProc->inVacuum = false; MyProc->inVacuum = false;
MyProc->isAutovacuum = IsAutoVacuumProcess();
MyProc->lwWaiting = false; MyProc->lwWaiting = false;
MyProc->lwExclusive = false; MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL; MyProc->lwWaitLink = NULL;
...@@ -390,6 +392,7 @@ InitDummyProcess(void) ...@@ -390,6 +392,7 @@ InitDummyProcess(void)
MyProc->databaseId = InvalidOid; MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid; MyProc->roleId = InvalidOid;
MyProc->inVacuum = false; MyProc->inVacuum = false;
MyProc->isAutovacuum = false;
MyProc->lwWaiting = false; MyProc->lwWaiting = false;
MyProc->lwExclusive = false; MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL; MyProc->lwWaitLink = NULL;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.6 2007/01/05 22:19:57 momjian Exp $ * $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.7 2007/01/16 13:28:57 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -36,6 +36,7 @@ extern void autovac_stopped(void); ...@@ -36,6 +36,7 @@ extern void autovac_stopped(void);
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
extern void AutoVacMain(int argc, char *argv[]); extern void AutoVacMain(int argc, char *argv[]);
extern void AutovacuumIAm(void);
#endif #endif
#endif /* AUTOVACUUM_H */ #endif /* AUTOVACUUM_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.92 2007/01/05 22:19:58 momjian Exp $ * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.93 2007/01/16 13:28:57 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -75,6 +75,7 @@ struct PGPROC ...@@ -75,6 +75,7 @@ struct PGPROC
Oid roleId; /* OID of role using this backend */ Oid roleId; /* OID of role using this backend */
bool inVacuum; /* true if current xact is a LAZY VACUUM */ bool inVacuum; /* true if current xact is a LAZY VACUUM */
bool isAutovacuum; /* true if it's autovacuum */
/* Info about LWLock the process is currently waiting for, if any. */ /* Info about LWLock the process is currently waiting for, if any. */
bool lwWaiting; /* true if waiting for an LW lock */ bool lwWaiting; /* true if waiting for an LW lock */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.11 2007/01/05 22:19:58 momjian Exp $ * $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.12 2007/01/16 13:28:57 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,7 +29,7 @@ extern TransactionId GetOldestXmin(bool allDbs, bool ignoreVacuum); ...@@ -29,7 +29,7 @@ extern TransactionId GetOldestXmin(bool allDbs, bool ignoreVacuum);
extern PGPROC *BackendPidGetProc(int pid); extern PGPROC *BackendPidGetProc(int pid);
extern int BackendXidGetPid(TransactionId xid); extern int BackendXidGetPid(TransactionId xid);
extern bool IsBackendPid(int pid); extern bool IsBackendPid(int pid);
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself); extern bool DatabaseCancelAutovacuumActivity(Oid databaseId, bool ignoreMyself);
extern int CountActiveBackends(void); extern int CountActiveBackends(void);
extern int CountDBBackends(Oid databaseid); extern int CountDBBackends(Oid databaseid);
......
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