diff -cpr pgsql-orig/src/backend/postmaster/autovacuum.c pgsql/src/backend/postmaster/autovacuum.c
*** pgsql-orig/src/backend/postmaster/autovacuum.c	Thu Aug 17 10:06:50 2006
--- pgsql/src/backend/postmaster/autovacuum.c	Thu Aug 17 10:42:10 2006
***************
*** 54,60 ****
   * GUC parameters
   */
  bool		autovacuum_start_daemon = false;
- int			autovacuum_naptime;
  int			autovacuum_vac_thresh;
  double		autovacuum_vac_scale;
  int			autovacuum_anl_thresh;
--- 54,59 ----
*************** int			autovacuum_vac_cost_limit;
*** 66,71 ****
--- 65,82 ----
  /* Flag to tell if we are in the autovacuum daemon process */
  static bool am_autovacuum = false;
  
+ /* Autovac daemon exitcode */
+ #define AUTOVACUUM_ACCELERATE	0
+ #define AUTOVACUUM_DECELERATE	1
+ 
+ /* Nap time of autovac daemon (only valid in postmaster) */
+ #define AUTOVACUUM_NAPTIME_MIN		1
+ #define AUTOVACUUM_NAPTIME_MAX		300
+ #define AUTOVACUUM_NAPTIME_DEFAULT	60
+ #define AUTOVACUUM_ACCEL_SCALE	0.5
+ #define AUTOVACUUM_DECEL_SCALE	1.2
+ int	autovacuum_naptime = AUTOVACUUM_NAPTIME_DEFAULT;
+ 
  /* Last time autovac daemon started/stopped (only valid in postmaster) */
  static time_t last_autovac_start_time = 0;
  static time_t last_autovac_stop_time = 0;
*************** static pid_t autovac_forkexec(void);
*** 101,107 ****
  #endif
  NON_EXEC_STATIC void AutoVacMain(int argc, char *argv[]);
  static void process_whole_db(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,
  					 Form_pg_class classForm,
--- 112,118 ----
  #endif
  NON_EXEC_STATIC void AutoVacMain(int argc, char *argv[]);
  static void process_whole_db(void);
! static int	do_autovacuum(PgStat_StatDBEntry *dbentry);
  static List *autovac_get_database_list(void);
  static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
  					 Form_pg_class classForm,
*************** autovac_start(void)
*** 136,143 ****
  	 *
  	 * Note that since we will be re-called from the postmaster main loop, we
  	 * will get another chance later if we do nothing now.
- 	 *
- 	 * XXX todo: implement sleep scale factor that existed in contrib code.
  	 */
  
  	curtime = time(NULL);
--- 147,152 ----
*************** autovac_start(void)
*** 186,194 ****
   * autovac_stopped --- called by postmaster when subprocess exit is detected
   */
  void
! autovac_stopped(void)
  {
  	last_autovac_stop_time = time(NULL);
  }
  
  #ifdef EXEC_BACKEND
--- 195,224 ----
   * autovac_stopped --- called by postmaster when subprocess exit is detected
   */
  void
! autovac_stopped(int exitcode)
  {
  	last_autovac_stop_time = time(NULL);
+ 
+ 	switch (exitcode)
+ 	{
+ 		case AUTOVACUUM_ACCELERATE:
+ 			autovacuum_naptime = (int)
+ 				floor(autovacuum_naptime * AUTOVACUUM_ACCEL_SCALE);
+ 			break;
+ 		case AUTOVACUUM_DECELERATE:
+ 			autovacuum_naptime = (int)
+ 				ceil(autovacuum_naptime * AUTOVACUUM_DECEL_SCALE);
+ 			break;
+ 		default: /* should not happen */
+ 			elog(WARNING, "autovacuum invalid exitcode %d", exitcode);
+ 			break;
+ 	}
+ 	if (autovacuum_naptime < AUTOVACUUM_NAPTIME_MIN)
+ 		autovacuum_naptime = AUTOVACUUM_NAPTIME_MIN;
+ 	if (autovacuum_naptime > AUTOVACUUM_NAPTIME_MAX)
+ 		autovacuum_naptime = AUTOVACUUM_NAPTIME_MAX;
+ 
+ 	elog(DEBUG1, "autovacuum: adjust naptime to %d", autovacuum_naptime);
  }
  
  #ifdef EXEC_BACKEND
*************** AutoVacMain(int argc, char *argv[])
*** 225,230 ****
--- 255,261 ----
  	TransactionId nextXid;
  	autovac_dbase *db;
  	bool		whole_db;
+ 	bool		vacuumed = false;
  	sigjmp_buf	local_sigjmp_buf;
  
  	/* we are a postmaster subprocess now */
*************** AutoVacMain(int argc, char *argv[])
*** 296,302 ****
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
! 		proc_exit(0);
  	}
  
  	/* We can now handle ereport(ERROR) */
--- 327,333 ----
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
! 		proc_exit(AUTOVACUUM_ACCELERATE);
  	}
  
  	/* We can now handle ereport(ERROR) */
*************** AutoVacMain(int argc, char *argv[])
*** 461,473 ****
  		 * And do an appropriate amount of work
  		 */
  		if (whole_db)
  			process_whole_db();
  		else
! 			do_autovacuum(db->entry);
  	}
  
  	/* One iteration done, go away */
! 	proc_exit(0);
  }
  
  /*
--- 492,507 ----
  		 * And do an appropriate amount of work
  		 */
  		if (whole_db)
+ 		{
  			process_whole_db();
+ 			vacuumed = true;
+ 		}
  		else
! 			vacuumed = (do_autovacuum(db->entry) > 0);
  	}
  
  	/* One iteration done, go away */
! 	proc_exit(vacuumed ? AUTOVACUUM_ACCELERATE : AUTOVACUUM_DECELERATE);
  }
  
  /*
*************** process_whole_db(void)
*** 574,584 ****
   * dbentry must be a valid pointer to the database entry in the stats
   * databases' hash table, and it will be used to determine whether vacuum or
   * analyze is needed on a per-table basis.
   *
   * Note that CHECK_FOR_INTERRUPTS is supposed to be used in certain spots in
   * order not to ignore shutdown commands for too long.
   */
! static void
  do_autovacuum(PgStat_StatDBEntry *dbentry)
  {
  	Relation	classRel,
--- 608,619 ----
   * dbentry must be a valid pointer to the database entry in the stats
   * databases' hash table, and it will be used to determine whether vacuum or
   * analyze is needed on a per-table basis.
+  * Returns the number of vacuumed tables.
   *
   * Note that CHECK_FOR_INTERRUPTS is supposed to be used in certain spots in
   * order not to ignore shutdown commands for too long.
   */
! static int
  do_autovacuum(PgStat_StatDBEntry *dbentry)
  {
  	Relation	classRel,
*************** do_autovacuum(PgStat_StatDBEntry *dbentr
*** 589,594 ****
--- 624,630 ----
  	List	   *toast_table_ids = NIL;
  	ListCell   *cell;
  	PgStat_StatDBEntry *shared;
+ 	int			numVacuumed = 0;
  
  	/* Start a transaction so our commands have one to play into. */
  	StartTransactionCommand();
*************** do_autovacuum(PgStat_StatDBEntry *dbentr
*** 723,732 ****
--- 759,771 ----
  								  tab->dovacuum,
  								  tab->doanalyze,
  								  false);
+ 		numVacuumed++;
  	}
  
  	/* Finally close out the last transaction. */
  	CommitTransactionCommand();
+ 
+ 	return numVacuumed;
  }
  
  /*
diff -cpr pgsql-orig/src/backend/postmaster/postmaster.c pgsql/src/backend/postmaster/postmaster.c
*** pgsql-orig/src/backend/postmaster/postmaster.c	Thu Aug 17 10:06:50 2006
--- pgsql/src/backend/postmaster/postmaster.c	Thu Aug 17 10:14:03 2006
*************** reaper(SIGNAL_ARGS)
*** 2106,2113 ****
  		if (AutoVacPID != 0 && pid == AutoVacPID)
  		{
  			AutoVacPID = 0;
! 			autovac_stopped();
! 			if (exitstatus != 0)
  				HandleChildCrash(pid, exitstatus,
  								 _("autovacuum process"));
  			continue;
--- 2106,2114 ----
  		if (AutoVacPID != 0 && pid == AutoVacPID)
  		{
  			AutoVacPID = 0;
! 			if (WIFEXITED(exitstatus))
! 				autovac_stopped(WEXITSTATUS(exitstatus));
! 			else
  				HandleChildCrash(pid, exitstatus,
  								 _("autovacuum process"));
  			continue;
diff -cpr pgsql-orig/src/backend/utils/misc/guc.c pgsql/src/backend/utils/misc/guc.c
*** pgsql-orig/src/backend/utils/misc/guc.c	Thu Aug 17 10:06:52 2006
--- pgsql/src/backend/utils/misc/guc.c	Thu Aug 17 10:14:03 2006
*************** static struct config_int ConfigureNamesI
*** 1539,1553 ****
  	},
  
  	{
- 		{"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
- 			gettext_noop("Time to sleep between autovacuum runs, in seconds."),
- 			NULL,
- 			GUC_UNIT_S
- 		},
- 		&autovacuum_naptime,
- 		60, 1, INT_MAX, NULL, NULL
- 	},
- 	{
  		{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
  			gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
  			NULL
--- 1539,1544 ----
diff -cpr pgsql-orig/src/backend/utils/misc/postgresql.conf.sample pgsql/src/backend/utils/misc/postgresql.conf.sample
*** pgsql-orig/src/backend/utils/misc/postgresql.conf.sample	Thu Aug 17 10:06:52 2006
--- pgsql/src/backend/utils/misc/postgresql.conf.sample	Thu Aug 17 10:14:03 2006
***************
*** 361,367 ****
  #---------------------------------------------------------------------------
  
  #autovacuum = off			# enable autovacuum subprocess?
- #autovacuum_naptime = 60		# time between autovacuum runs, in secs
  #autovacuum_vacuum_threshold = 1000	# min # of tuple updates before
  					# vacuum
  #autovacuum_analyze_threshold = 500	# min # of tuple updates before 
--- 361,366 ----
diff -cpr pgsql-orig/src/include/postmaster/autovacuum.h pgsql/src/include/postmaster/autovacuum.h
*** pgsql-orig/src/include/postmaster/autovacuum.h	Thu Aug 17 10:06:55 2006
--- pgsql/src/include/postmaster/autovacuum.h	Thu Aug 17 10:14:03 2006
*************** extern bool IsAutoVacuumProcess(void);
*** 31,37 ****
  /* Functions to start autovacuum process, called from postmaster */
  extern void autovac_init(void);
  extern int	autovac_start(void);
! extern void autovac_stopped(void);
  
  #ifdef EXEC_BACKEND
  extern void AutoVacMain(int argc, char *argv[]);
--- 31,37 ----
  /* Functions to start autovacuum process, called from postmaster */
  extern void autovac_init(void);
  extern int	autovac_start(void);
! extern void autovac_stopped(int exitcode);
  
  #ifdef EXEC_BACKEND
  extern void AutoVacMain(int argc, char *argv[]);