Index: src/backend/access/transam/twophase.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/transam/twophase.c,v
retrieving revision 1.26
diff -c -p -r1.26 twophase.c
*** src/backend/access/transam/twophase.c	5 Jan 2007 22:19:23 -0000	1.26
--- src/backend/access/transam/twophase.c	15 Jan 2007 19:11:15 -0000
*************** MarkAsPreparing(TransactionId xid, const
*** 280,285 ****
--- 280,286 ----
  	gxact->proc.databaseId = databaseid;
  	gxact->proc.roleId = owner;
  	gxact->proc.inVacuum = false;
+ 	gxact->proc.isAutovacuum = false;
  	gxact->proc.lwWaiting = false;
  	gxact->proc.lwExclusive = false;
  	gxact->proc.lwWaitLink = NULL;
Index: src/backend/bootstrap/bootstrap.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.228
diff -c -p -r1.228 bootstrap.c
*** src/backend/bootstrap/bootstrap.c	5 Jan 2007 22:19:24 -0000	1.228
--- src/backend/bootstrap/bootstrap.c	15 Jan 2007 19:08:47 -0000
*************** BootstrapMain(int argc, char *argv[])
*** 446,452 ****
  	/*
  	 * Do backend-like initialization for bootstrap mode
  	 */
! 	InitProcess();
  	(void) InitPostgres(dbname, NULL);
  
  	/*
--- 446,452 ----
  	/*
  	 * Do backend-like initialization for bootstrap mode
  	 */
! 	InitProcess(false);
  	(void) InitPostgres(dbname, NULL);
  
  	/*
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.30
diff -c -p -r1.30 autovacuum.c
*** src/backend/postmaster/autovacuum.c	5 Jan 2007 22:19:36 -0000	1.30
--- src/backend/postmaster/autovacuum.c	15 Jan 2007 20:20:28 -0000
*************** AutoVacMain(int argc, char *argv[])
*** 290,296 ****
  	 * had to do some stuff with LWLocks).
  	 */
  #ifndef EXEC_BACKEND
! 	InitProcess();
  #endif
  
  	/*
--- 290,296 ----
  	 * had to do some stuff with LWLocks).
  	 */
  #ifndef EXEC_BACKEND
! 	InitProcess(true);
  #endif
  
  	/*
*************** AutoVacMain(int argc, char *argv[])
*** 307,313 ****
  		EmitErrorReport();
  
  		/*
! 		 * We can now go away.	Note that because we'll call InitProcess, a
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
--- 307,313 ----
  		EmitErrorReport();
  
  		/*
! 		 * We can now go away.	Note that because we called InitProcess, a
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.507
diff -c -p -r1.507 postmaster.c
*** src/backend/postmaster/postmaster.c	5 Jan 2007 22:19:36 -0000	1.507
--- src/backend/postmaster/postmaster.c	15 Jan 2007 19:09:29 -0000
*************** SubPostmasterMain(int argc, char *argv[]
*** 3347,3353 ****
  		InitShmemAccess(UsedShmemSegAddr);
  
  		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! 		InitProcess();
  
  		/*
  		 * Attach process to shared data structures.  If testing EXEC_BACKEND
--- 3347,3353 ----
  		InitShmemAccess(UsedShmemSegAddr);
  
  		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! 		InitProcess(false);
  
  		/*
  		 * Attach process to shared data structures.  If testing EXEC_BACKEND
*************** SubPostmasterMain(int argc, char *argv[]
*** 3391,3397 ****
  		InitShmemAccess(UsedShmemSegAddr);
  
  		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! 		InitProcess();
  
  		/* Attach process to shared data structures */
  		CreateSharedMemoryAndSemaphores(false, 0);
--- 3391,3397 ----
  		InitShmemAccess(UsedShmemSegAddr);
  
  		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! 		InitProcess(true);
  
  		/* Attach process to shared data structures */
  		CreateSharedMemoryAndSemaphores(false, 0);
Index: src/backend/storage/ipc/procarray.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/ipc/procarray.c,v
retrieving revision 1.20
diff -c -p -r1.20 procarray.c
*** src/backend/storage/ipc/procarray.c	5 Jan 2007 22:19:38 -0000	1.20
--- src/backend/storage/ipc/procarray.c	15 Jan 2007 20:21:41 -0000
***************
*** 29,34 ****
--- 29,36 ----
   */
  #include "postgres.h"
  
+ #include <signal.h>
+ 
  #include "access/subtrans.h"
  #include "access/transam.h"
  #include "access/xact.h"
*************** GetSnapshotData(Snapshot snapshot, bool 
*** 679,684 ****
--- 681,687 ----
  
  /*
   * DatabaseHasActiveBackends -- are there any backends running in the given DB
+  * If the only process running on the database is autovacuum, try to kill it.
   *
   * If 'ignoreMyself' is TRUE, ignore this particular backend while checking
   * for backends in the target database.
*************** GetSnapshotData(Snapshot snapshot, bool 
*** 693,701 ****
  bool
  DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
  {
! 	bool		result = false;
  	ProcArrayStruct *arrayP = procArray;
  	int			index;
  
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
--- 696,711 ----
  bool
  DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
  {
! 	bool		result;
  	ProcArrayStruct *arrayP = procArray;
  	int			index;
+ 	int			num;
+ 	pid_t		autovacPid;
+ 
+ restart:
+ 	num = 0;
+ 	autovacPid = 0;
+ 	result = false;
  
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
*************** DatabaseHasActiveBackends(Oid databaseId
*** 708,718 ****
  			if (ignoreMyself && proc == MyProc)
  				continue;
  
! 			result = true;
! 			break;
  		}
  	}
  
  	LWLockRelease(ProcArrayLock);
  
  	return result;
--- 718,755 ----
  			if (ignoreMyself && proc == MyProc)
  				continue;
  
! 			/*
! 			 * We can't hope that only autovacuum is running if there's more than
! 			 * one process.
! 			 */
! 			if (++num > 1)
! 				break;
! 
! 			if (proc->isAutovacuum)
! 			{
! 				Assert(autovacPid == 0);
! 				autovacPid = proc->pid;
! 			}
  		}
  	}
  
+ 	if (num == 0)
+ 	{
+ 		/* yipee, there's nobody here */
+ 		result = false;
+ 	}
+ 	else if (num == 1 && autovacPid != 0)
+ 	{
+ 		/* good, there's only an autovacuum -- kill it */
+ 		kill(autovacPid, SIGINT);
+ 		LWLockRelease(ProcArrayLock);
+ 		pg_usleep(100 * 1000);		/* 100ms */
+ 		goto restart;
+ 	}
+ 	else
+ 		/* no luck; there's a different backend */
+ 		result = true;
+ 
  	LWLockRelease(ProcArrayLock);
  
  	return result;
Index: src/backend/storage/lmgr/proc.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/lmgr/proc.c,v
retrieving revision 1.182
diff -c -p -r1.182 proc.c
*** src/backend/storage/lmgr/proc.c	5 Jan 2007 22:19:38 -0000	1.182
--- src/backend/storage/lmgr/proc.c	15 Jan 2007 19:59:44 -0000
*************** InitProcGlobal(void)
*** 194,202 ****
  
  /*
   * InitProcess -- initialize a per-process data structure for this backend
   */
  void
! InitProcess(void)
  {
  	/* use volatile pointer to prevent code rearrangement */
  	volatile PROC_HDR *procglobal = ProcGlobal;
--- 194,204 ----
  
  /*
   * InitProcess -- initialize a per-process data structure for this backend
+  *
+  * "autovac" is used to initialize the "isAutovacuum" PGPROC member.
   */
  void
! InitProcess(bool autovac)
  {
  	/* use volatile pointer to prevent code rearrangement */
  	volatile PROC_HDR *procglobal = ProcGlobal;
*************** InitProcess(void)
*** 258,263 ****
--- 260,266 ----
  	MyProc->databaseId = InvalidOid;
  	MyProc->roleId = InvalidOid;
  	MyProc->inVacuum = false;
+ 	MyProc->isAutovacuum = autovac;
  	MyProc->lwWaiting = false;
  	MyProc->lwExclusive = false;
  	MyProc->lwWaitLink = NULL;
*************** InitDummyProcess(void)
*** 390,395 ****
--- 393,399 ----
  	MyProc->databaseId = InvalidOid;
  	MyProc->roleId = InvalidOid;
  	MyProc->inVacuum = false;
+ 	MyProc->isAutovacuum = false;
  	MyProc->lwWaiting = false;
  	MyProc->lwExclusive = false;
  	MyProc->lwWaitLink = NULL;
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/tcop/postgres.c,v
retrieving revision 1.521
diff -c -p -r1.521 postgres.c
*** src/backend/tcop/postgres.c	5 Jan 2007 22:19:39 -0000	1.521
--- src/backend/tcop/postgres.c	15 Jan 2007 19:10:28 -0000
*************** PostgresMain(int argc, char *argv[], con
*** 3125,3133 ****
  	 */
  #ifdef EXEC_BACKEND
  	if (!IsUnderPostmaster)
! 		InitProcess();
  #else
! 	InitProcess();
  #endif
  
  	/*
--- 3125,3133 ----
  	 */
  #ifdef EXEC_BACKEND
  	if (!IsUnderPostmaster)
! 		InitProcess(false);
  #else
! 	InitProcess(false);
  #endif
  
  	/*
Index: src/include/storage/proc.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/storage/proc.h,v
retrieving revision 1.92
diff -c -p -r1.92 proc.h
*** src/include/storage/proc.h	5 Jan 2007 22:19:58 -0000	1.92
--- src/include/storage/proc.h	15 Jan 2007 19:12:12 -0000
*************** struct PGPROC
*** 75,80 ****
--- 75,81 ----
  	Oid			roleId;			/* OID of role using this backend */
  
  	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. */
  	bool		lwWaiting;		/* true if waiting for an LW lock */
*************** extern volatile bool cancel_from_timeout
*** 136,142 ****
  extern int	ProcGlobalSemas(void);
  extern Size ProcGlobalShmemSize(void);
  extern void InitProcGlobal(void);
! extern void InitProcess(void);
  extern void InitProcessPhase2(void);
  extern void InitDummyProcess(void);
  extern bool HaveNFreeProcs(int n);
--- 137,143 ----
  extern int	ProcGlobalSemas(void);
  extern Size ProcGlobalShmemSize(void);
  extern void InitProcGlobal(void);
! extern void InitProcess(bool autovac);
  extern void InitProcessPhase2(void);
  extern void InitDummyProcess(void);
  extern bool HaveNFreeProcs(int n);
