]> granicus.if.org Git - postgresql/commitdiff
Separate the code to start a new worker into its own function. The code is
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 23 Mar 2007 21:45:17 +0000 (21:45 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 23 Mar 2007 21:45:17 +0000 (21:45 +0000)
exactly the same, modulo whitespace.

src/backend/postmaster/autovacuum.c

index e0b633057686a7d221ac83db27e2fed62cc0d1ab..fb2de6f57a2b9b3a253a367374bf90a607f92f94 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.36 2007/03/23 21:23:13 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.37 2007/03/23 21:45:17 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -118,6 +118,7 @@ static pid_t avworker_forkexec(void);
 NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]);
 NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]);
 
+static void do_start_worker(void);
 static void do_autovacuum(PgStat_StatDBEntry *dbentry);
 static List *autovac_get_database_list(void);
 static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
@@ -218,9 +219,6 @@ NON_EXEC_STATIC void
 AutoVacLauncherMain(int argc, char *argv[])
 {
        sigjmp_buf      local_sigjmp_buf;
-       List       *dblist;
-       bool            for_xid_wrap;
-       autovac_dbase *db;
        MemoryContext   avlauncher_cxt;
 
        /* we are a postmaster subprocess now */
@@ -358,8 +356,6 @@ AutoVacLauncherMain(int argc, char *argv[])
 
        for (;;)
        {
-               TransactionId xidForceLimit;
-               ListCell *cell;
                int             worker_pid;
 
                /*
@@ -407,86 +403,8 @@ AutoVacLauncherMain(int argc, char *argv[])
                        }
                }
 
-               /* Get a list of databases */
-               dblist = autovac_get_database_list();
+               do_start_worker();
 
-               /*
-                * Determine the oldest datfrozenxid/relfrozenxid that we will allow
-                * to pass without forcing a vacuum.  (This limit can be tightened for
-                * particular tables, but not loosened.)
-                */
-               recentXid = ReadNewTransactionId();
-               xidForceLimit = recentXid - autovacuum_freeze_max_age;
-               /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
-               if (xidForceLimit < FirstNormalTransactionId)
-                       xidForceLimit -= FirstNormalTransactionId;
-
-               /*
-                * Choose a database to connect to.  We pick the database that was least
-                * recently auto-vacuumed, or one that needs vacuuming to prevent Xid
-                * wraparound-related data loss.  If any db at risk of wraparound is
-                * found, we pick the one with oldest datfrozenxid, independently of
-                * autovacuum times.
-                *
-                * Note that a database with no stats entry is not considered, except for
-                * Xid wraparound purposes.  The theory is that if no one has ever
-                * connected to it since the stats were last initialized, it doesn't need
-                * vacuuming.
-                *
-                * XXX This could be improved if we had more info about whether it needs
-                * vacuuming before connecting to it.  Perhaps look through the pgstats
-                * data for the database's tables?  One idea is to keep track of the
-                * number of new and dead tuples per database in pgstats.  However it
-                * isn't clear how to construct a metric that measures that and not cause
-                * starvation for less busy databases.
-                */
-               db = NULL;
-               for_xid_wrap = false;
-               foreach(cell, dblist)
-               {
-                       autovac_dbase *tmp = lfirst(cell);
-
-                       /* Find pgstat entry if any */
-                       tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);
-
-                       /* Check to see if this one is at risk of wraparound */
-                       if (TransactionIdPrecedes(tmp->frozenxid, xidForceLimit))
-                       {
-                               if (db == NULL ||
-                                       TransactionIdPrecedes(tmp->frozenxid, db->frozenxid))
-                                       db = tmp;
-                               for_xid_wrap = true;
-                               continue;
-                       }
-                       else if (for_xid_wrap)
-                               continue;                       /* ignore not-at-risk DBs */
-
-                       /*
-                        * Otherwise, skip a database with no pgstat entry; it means it
-                        * hasn't seen any activity.
-                        */
-                       if (!tmp->entry)
-                               continue;
-
-                       /*
-                        * Remember the db with oldest autovac time.  (If we are here,
-                        * both tmp->entry and db->entry must be non-null.)
-                        */
-                       if (db == NULL ||
-                               tmp->entry->last_autovac_time < db->entry->last_autovac_time)
-                               db = tmp;
-               }
-
-               /* Found a database -- process it */
-               if (db != NULL)
-               {
-                       LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
-                       AutoVacuumShmem->process_db = db->oid;
-                       LWLockRelease(AutovacuumLock);
-
-                       SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
-               }
-               
 sleep:
                /*
                 * in emergency mode, exit immediately so that the postmaster can
@@ -512,6 +430,103 @@ sleep:
        proc_exit(0);           /* done */
 }
 
+/*
+ * do_start_worker
+ *
+ * Bare-bones procedure for starting an autovacuum worker from the launcher.
+ * It determines what database to work on, sets up shared memory stuff and
+ * signals postmaster to start the worker.
+ */
+static void
+do_start_worker(void)
+{
+       List       *dblist;
+       bool            for_xid_wrap;
+       autovac_dbase *db;
+       ListCell *cell;
+       TransactionId xidForceLimit;
+
+       /* Get a list of databases */
+       dblist = autovac_get_database_list();
+
+       /*
+        * Determine the oldest datfrozenxid/relfrozenxid that we will allow
+        * to pass without forcing a vacuum.  (This limit can be tightened for
+        * particular tables, but not loosened.)
+        */
+       recentXid = ReadNewTransactionId();
+       xidForceLimit = recentXid - autovacuum_freeze_max_age;
+       /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
+       if (xidForceLimit < FirstNormalTransactionId)
+               xidForceLimit -= FirstNormalTransactionId;
+
+       /*
+        * Choose a database to connect to.  We pick the database that was least
+        * recently auto-vacuumed, or one that needs vacuuming to prevent Xid
+        * wraparound-related data loss.  If any db at risk of wraparound is
+        * found, we pick the one with oldest datfrozenxid, independently of
+        * autovacuum times.
+        *
+        * Note that a database with no stats entry is not considered, except for
+        * Xid wraparound purposes.  The theory is that if no one has ever
+        * connected to it since the stats were last initialized, it doesn't need
+        * vacuuming.
+        *
+        * XXX This could be improved if we had more info about whether it needs
+        * vacuuming before connecting to it.  Perhaps look through the pgstats
+        * data for the database's tables?  One idea is to keep track of the
+        * number of new and dead tuples per database in pgstats.  However it
+        * isn't clear how to construct a metric that measures that and not cause
+        * starvation for less busy databases.
+        */
+       db = NULL;
+       for_xid_wrap = false;
+       foreach(cell, dblist)
+       {
+               autovac_dbase *tmp = lfirst(cell);
+
+               /* Find pgstat entry if any */
+               tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);
+
+               /* Check to see if this one is at risk of wraparound */
+               if (TransactionIdPrecedes(tmp->frozenxid, xidForceLimit))
+               {
+                       if (db == NULL ||
+                               TransactionIdPrecedes(tmp->frozenxid, db->frozenxid))
+                               db = tmp;
+                       for_xid_wrap = true;
+                       continue;
+               }
+               else if (for_xid_wrap)
+                       continue;                       /* ignore not-at-risk DBs */
+
+               /*
+                * Otherwise, skip a database with no pgstat entry; it means it
+                * hasn't seen any activity.
+                */
+               if (!tmp->entry)
+                       continue;
+
+               /*
+                * Remember the db with oldest autovac time.  (If we are here,
+                * both tmp->entry and db->entry must be non-null.)
+                */
+               if (db == NULL ||
+                       tmp->entry->last_autovac_time < db->entry->last_autovac_time)
+                       db = tmp;
+       }
+
+       /* Found a database -- process it */
+       if (db != NULL)
+       {
+               LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
+               AutoVacuumShmem->process_db = db->oid;
+               LWLockRelease(AutovacuumLock);
+
+               SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
+       }
+}
+
 /* SIGHUP: set flag to re-read config file at next convenient time */
 static void
 avl_sighup_handler(SIGNAL_ARGS)