Arrange for autovacuum to be killed when another operation wants to be alone
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 16 Jan 2007 13:28:57 +0000 (13:28 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 16 Jan 2007 13:28:57 +0000 (13:28 +0000)
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.

src/backend/access/transam/twophase.c
src/backend/commands/dbcommands.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/postmaster.c
src/backend/storage/ipc/procarray.c
src/backend/storage/lmgr/proc.c
src/include/postmaster/autovacuum.h
src/include/storage/proc.h
src/include/storage/procarray.h

index 4026daa54a278f73cf4a9346d6c278606ee6eb7d..45220d119642c033e9c56f8ed017577ba1ffd66f 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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
  *     Each global transaction is associated with a global transaction
@@ -280,6 +280,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
    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 ef0aff99ac8b00c4844024861a106cbfea551aa0..18340481d238175d8294641e7d08323aa2ccb1f9 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * 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,11 +250,11 @@ createdb(const CreatedbStmt *stmt)
     * (exception is to allow CREATE DB while connected to template1).
     * Otherwise we might copy inconsistent data.
     */
-   if (DatabaseHasActiveBackends(src_dboid, true))
+   if (DatabaseCancelAutovacuumActivity(src_dboid, true))
        ereport(ERROR,
                (errcode(ERRCODE_OBJECT_IN_USE),
-           errmsg("source database \"%s\" is being accessed by other users",
-                  dbtemplate)));
+                errmsg("source database \"%s\" is being accessed by other users",
+                       dbtemplate)));
 
    /* If encoding is defaulted, use source's encoding */
    if (encoding < 0)
@@ -602,7 +602,7 @@ dropdb(const char *dbname, bool missing_ok)
     * Check for active backends in the target database.  (Because we hold the
     * database lock, no new ones can start after this.)
     */
-   if (DatabaseHasActiveBackends(db_id, false))
+   if (DatabaseCancelAutovacuumActivity(db_id, false))
        ereport(ERROR,
                (errcode(ERRCODE_OBJECT_IN_USE),
                 errmsg("database \"%s\" is being accessed by other users",
@@ -706,7 +706,7 @@ RenameDatabase(const char *oldname, const char *newname)
     * Make sure the database does not have active sessions.  This is the same
     * concern as above, but applied to other sessions.
     */
-   if (DatabaseHasActiveBackends(db_id, false))
+   if (DatabaseCancelAutovacuumActivity(db_id, false))
        ereport(ERROR,
                (errcode(ERRCODE_OBJECT_IN_USE),
                 errmsg("database \"%s\" is being accessed by other users",
index 8caf7ce9199e441885e7cd8827148b8bade8e3de..130ad45fd8be984bc564c018e2dc1dc6745bf109 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * 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)
 
    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 */
 
 /*
@@ -307,8 +316,8 @@ AutoVacMain(int argc, char *argv[])
        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
+        * We can now go away.  Note that because we called InitProcess, a
+        * callback was registered to do ProcKill, which will clean up
         * necessary state.
         */
        proc_exit(0);
index 14ccf5dc1ccc91a0b1b73c1f0050c5f1e2e35222..f4c424c9680b1370e8551452a69a7c28e728aac3 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * 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
  *
@@ -3298,6 +3298,10 @@ SubPostmasterMain(int argc, char *argv[])
        strcmp(argv[1], "--forkboot") == 0)
        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
     * read the backend variables, because we need to pick up the signal pipe
index b31bdf9b7d37551d8d7ac10510b9d7f28c733548..19e5efa683a5071f3b0f8cb62d9fca9ff8952c62 100644 (file)
  *
  *
  * 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 <signal.h>
+
 #include "access/subtrans.h"
 #include "access/transam.h"
 #include "access/xact.h"
@@ -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
  * for backends in the target database.
@@ -691,11 +695,16 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
  * backend startup.
  */
 bool
-DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
+DatabaseCancelAutovacuumActivity(Oid databaseId, bool ignoreMyself)
 {
-   bool        result = false;
    ProcArrayStruct *arrayP = procArray;
    int         index;
+   int         num;
+
+restart:
+   num = 0;
+
+   CHECK_FOR_INTERRUPTS();
 
    LWLockAcquire(ProcArrayLock, LW_SHARED);
 
@@ -708,14 +717,22 @@ DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
            if (ignoreMyself && proc == MyProc)
                continue;
 
-           result = true;
-           break;
+           num++;
+
+           if (proc->isAutovacuum)
+           {
+               /* an autovacuum -- kill it and restart */
+               LWLockRelease(ProcArrayLock);
+               kill(proc->pid, SIGINT);
+               pg_usleep(100 * 1000);      /* 100ms */
+               goto restart;
+           }
        }
    }
 
    LWLockRelease(ProcArrayLock);
 
-   return result;
+   return (num != 0);
 }
 
 /*
index d4500b5c350bc0f186933484b40403813f5dbb91..6e2a0ce81c4297fd56fddd0ea88ec8be80941647 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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 @@
 #include "access/transam.h"
 #include "access/xact.h"
 #include "miscadmin.h"
+#include "postmaster/autovacuum.h"
 #include "storage/ipc.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
@@ -258,6 +259,7 @@ InitProcess(void)
    MyProc->databaseId = InvalidOid;
    MyProc->roleId = InvalidOid;
    MyProc->inVacuum = false;
+   MyProc->isAutovacuum = IsAutoVacuumProcess();
    MyProc->lwWaiting = false;
    MyProc->lwExclusive = false;
    MyProc->lwWaitLink = NULL;
@@ -390,6 +392,7 @@ InitDummyProcess(void)
    MyProc->databaseId = InvalidOid;
    MyProc->roleId = InvalidOid;
    MyProc->inVacuum = false;
+   MyProc->isAutovacuum = false;
    MyProc->lwWaiting = false;
    MyProc->lwExclusive = false;
    MyProc->lwWaitLink = NULL;
index c232ae3b488df60d5dba6ace223b8ef98f20df85..7b3ad7e55098d5da33381021ec2c8c34aafec8d5 100644 (file)
@@ -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.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);
 
 #ifdef EXEC_BACKEND
 extern void AutoVacMain(int argc, char *argv[]);
+extern void AutovacuumIAm(void);
 #endif
 
 #endif   /* AUTOVACUUM_H */
index a52850fb2190ff9c20583e696d49058fd6f2c862..b86f210fbe850fdf0e8a94d2d481e61fc60d5737 100644 (file)
@@ -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.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
    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 */
index 265f4eb0b7c43b6f9c2eb10100bf4bf6bcfe67f6..93e82e436805687c3abc08c7bbc890810ec0182d 100644 (file)
@@ -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/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);
 extern PGPROC *BackendPidGetProc(int pid);
 extern int BackendXidGetPid(TransactionId xid);
 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 CountDBBackends(Oid databaseid);