? GNUmakefile
? config.log
? config.status
? cp.origs
? src/Makefile.global
? src/pg_autovacuum_devel.kdevelop
? src/pg_autovacuum_devel.kdevelop.filelist
? src/pg_autovacuum_devel.kdevelop.pcs
? src/pg_autovacuum_devel.kdevses
? src/pgsql_cs.kdevelop
? src/backend/postgres
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/postmaster/pg_autovacuum.c
? src/backend/postmaster/pg_autovacuum.todo
? src/backend/utils/resowner
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/backend/utils/mb/conversion_procs/ascii_and_mic/libascii_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/libcyrillic_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/libeuc_cn_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/libeuc_jp_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/libeuc_kr_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/libeuc_tw_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/latin2_and_win1250/liblatin2_and_win1250.so.0.0
? src/backend/utils/mb/conversion_procs/latin_and_mic/liblatin_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_ascii/libutf8_and_ascii.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_big5/libutf8_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/libutf8_and_cyrillic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/libutf8_and_euc_cn.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/libutf8_and_euc_jp.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/libutf8_and_euc_kr.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/libutf8_and_euc_tw.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/libutf8_and_gb18030.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gbk/libutf8_and_gbk.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/libutf8_and_iso8859.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/libutf8_and_iso8859_1.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_johab/libutf8_and_johab.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_sjis/libutf8_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_tcvn/libutf8_and_tcvn.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_uhc/libutf8_and_uhc.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_win1250/libutf8_and_win1250.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_win1256/libutf8_and_win1256.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_win874/libutf8_and_win874.so.0.0
? src/bin/initdb/initdb
? src/bin/initlocation/initlocation
? src/bin/ipcclean/ipcclean
? src/bin/pg_config/pg_config
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/psql/psql
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/vacuumdb
? src/include/pg_config.h
? src/include/stamp-h
? src/include/catalog/pg_autovacuum.h
? src/include/postmaster/pg_autovacuum.h
? src/interfaces/ecpg/compatlib/libecpg_compat.so.1.1
? src/interfaces/ecpg/ecpglib/libecpg.so.4.2
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.1.2
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpq/libpq.so.3.2
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/port/pg_config_paths.h
? src/timezone/zic
Index: src/backend/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/Makefile,v
retrieving revision 1.100
diff -c -r1.100 Makefile
*** src/backend/Makefile	21 May 2004 05:07:55 -0000	1.100
--- src/backend/Makefile	18 Jul 2004 01:45:07 -0000
***************
*** 29,41 ****
  
  ##########################################################################
  
! all: submake-libpgport postgres $(POSTGRES_IMP)
  
  ifneq ($(PORTNAME), cygwin)
  ifneq ($(PORTNAME), win32)
  
  postgres: $(OBJS)
! 	$(CC) $(CFLAGS) $(LDFLAGS) $(export_dynamic) $^ $(LIBS) -o $@
  
  endif
  endif
--- 29,41 ----
  
  ##########################################################################
  
! all: submake-libpgport submake-libpq postgres $(POSTGRES_IMP)
  
  ifneq ($(PORTNAME), cygwin)
  ifneq ($(PORTNAME), win32)
  
  postgres: $(OBJS)
! 	$(CC) $(CFLAGS) $(LDFLAGS) -I $(libpq_srcdir) $(export_dynamic) $^ $(LIBS)  $(libpq) -o $@
  
  endif
  endif
Index: src/backend/bootstrap/bootstrap.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.187
diff -c -r1.187 bootstrap.c
*** src/backend/bootstrap/bootstrap.c	17 Jul 2004 03:28:37 -0000	1.187
--- src/backend/bootstrap/bootstrap.c	18 Jul 2004 01:45:08 -0000
***************
*** 34,39 ****
--- 34,40 ----
  #include "libpq/pqsignal.h"
  #include "miscadmin.h"
  #include "postmaster/bgwriter.h"
+ #include "postmaster/pg_autovacuum.h"
  #include "storage/freespace.h"
  #include "storage/ipc.h"
  #include "storage/pg_shmem.h"
***************
*** 355,360 ****
--- 356,364 ----
  			case BS_XLOG_BGWRITER:
  				statmsg = "writer process";
  				break;
+ 			case BS_XLOG_AUTOVAC:
+ 				statmsg = "auto vacuum process";
+ 				break;
  			default:
  				statmsg = "??? process";
  				break;
***************
*** 391,396 ****
--- 395,403 ----
  			case BS_XLOG_BGWRITER:
  				InitDummyProcess(DUMMY_PROC_BGWRITER);
  				break;
+ 			case BS_XLOG_AUTOVAC:
+ 				InitDummyProcess(DUMMY_PROC_AUTOVAC);
+ 				break;
  
  			default:
  				InitDummyProcess(DUMMY_PROC_DEFAULT);
***************
*** 427,432 ****
--- 434,445 ----
  			BackgroundWriterMain();
  			proc_exit(1);		/* should never return */
  
+ 		case BS_XLOG_AUTOVAC:
+ 			/* don't set signals, autovac has its own agenda */
+ 			InitXLOGAccess();
+ 			AutoVacMain();
+ 			proc_exit(1);		/* should never return */
+ 		
  		default:
  			elog(PANIC, "unrecognized XLOG op: %d", xlogop);
  			proc_exit(1);
Index: src/backend/catalog/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/catalog/Makefile,v
retrieving revision 1.51
diff -c -r1.51 Makefile
*** src/backend/catalog/Makefile	18 Jun 2004 06:13:19 -0000	1.51
--- src/backend/catalog/Makefile	18 Jul 2004 01:45:08 -0000
***************
*** 32,38 ****
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
  	pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
! 	pg_tablespace.h pg_depend.h indexing.h \
      )
  
  pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
--- 32,38 ----
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
  	pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
! 	pg_tablespace.h pg_depend.h pg_autovacuum.h indexing.h \
      )
  
  pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
Index: src/backend/postmaster/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/Makefile,v
retrieving revision 1.15
diff -c -r1.15 Makefile
*** src/backend/postmaster/Makefile	29 May 2004 22:48:19 -0000	1.15
--- src/backend/postmaster/Makefile	18 Jul 2004 01:45:10 -0000
***************
*** 12,18 ****
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = postmaster.o bgwriter.o pgstat.o
  
  all: SUBSYS.o
  
--- 12,18 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = postmaster.o bgwriter.o pgstat.o pg_autovacuum.o
  
  all: SUBSYS.o
  
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.411
diff -c -r1.411 postmaster.c
*** src/backend/postmaster/postmaster.c	12 Jul 2004 19:14:56 -0000	1.411
--- src/backend/postmaster/postmaster.c	18 Jul 2004 01:45:12 -0000
***************
*** 55,66 ****
   *		The Postmaster cleans up after backends if they have an emergency
   *		exit and/or core dump.
   *
-  * Error Reporting:
-  *		Use write_stderr() only for reporting "interactive" errors
-  *		(essentially, bogus arguments on the command line).  Once the
-  *		postmaster is launched, use ereport().  In particular, don't use
-  *		write_stderr() for anything that occurs after pmdaemonize.
-  *
   *-------------------------------------------------------------------------
   */
  
--- 55,60 ----
***************
*** 198,203 ****
--- 192,198 ----
  /* PIDs of special child processes; 0 when not running */
  static pid_t StartupPID = 0,
  			BgWriterPID = 0,
+ 			AutoVacPID = 0,
  			PgStatPID = 0;
  
  /* Startup/shutdown state */
***************
*** 267,272 ****
--- 262,271 ----
  static int	CountChildren(void);
  static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
  static pid_t StartChildProcess(int xlop);
+ static void
+ postmaster_error(const char *fmt,...)
+ /* This lets gcc check the format string for consistency. */
+ __attribute__((format(printf, 1, 2)));
  
  #ifdef EXEC_BACKEND
  
***************
*** 297,302 ****
--- 296,302 ----
  
  #define StartupDataBase()		StartChildProcess(BS_XLOG_STARTUP)
  #define StartBackgroundWriter() StartChildProcess(BS_XLOG_BGWRITER)
+ #define StartAutoVac() StartChildProcess(BS_XLOG_AUTOVAC)
  
  
  /*
***************
*** 383,389 ****
  #ifdef USE_ASSERT_CHECKING
  				SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
  #else
! 				write_stderr("%s: assert checking is not compiled in\n", progname);
  #endif
  				break;
  			case 'a':
--- 383,389 ----
  #ifdef USE_ASSERT_CHECKING
  				SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
  #else
! 				postmaster_error("assert checking is not compiled in");
  #endif
  				break;
  			case 'a':
***************
*** 507,514 ****
  				}
  
  			default:
! 				write_stderr("Try \"%s --help\" for more information.\n",
! 							 progname);
  				ExitPostmaster(1);
  		}
  	}
--- 507,515 ----
  				}
  
  			default:
! 				fprintf(stderr,
! 					gettext("Try \"%s --help\" for more information.\n"),
! 						progname);
  				ExitPostmaster(1);
  		}
  	}
***************
*** 518,527 ****
  	 */
  	if (optind < argc)
  	{
! 		write_stderr("%s: invalid argument: \"%s\"\n",
! 					 progname, argv[optind]);
! 		write_stderr("Try \"%s --help\" for more information.\n",
! 					 progname);
  		ExitPostmaster(1);
  	}
  
--- 519,528 ----
  	 */
  	if (optind < argc)
  	{
! 		postmaster_error("invalid argument: \"%s\"", argv[optind]);
! 		fprintf(stderr,
! 				gettext("Try \"%s --help\" for more information.\n"),
! 				progname);
  		ExitPostmaster(1);
  	}
  
***************
*** 592,604 ****
  		 * for lack of buffers.  The specific choices here are somewhat
  		 * arbitrary.
  		 */
! 		write_stderr("%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n", progname);
  		ExitPostmaster(1);
  	}
  
  	if (ReservedBackends >= MaxBackends)
  	{
! 		write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
  		ExitPostmaster(1);
  	}
  
--- 593,605 ----
  		 * for lack of buffers.  The specific choices here are somewhat
  		 * arbitrary.
  		 */
! 		postmaster_error("the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16");
  		ExitPostmaster(1);
  	}
  
  	if (ReservedBackends >= MaxBackends)
  	{
! 		postmaster_error("superuser_reserved_connections must be less than max_connections");
  		ExitPostmaster(1);
  	}
  
***************
*** 607,613 ****
  	 */
  	if (!CheckDateTokenTables())
  	{
! 		write_stderr("%s: invalid datetoken tables, please fix\n", progname);
  		ExitPostmaster(1);
  	}
  
--- 608,614 ----
  	 */
  	if (!CheckDateTokenTables())
  	{
! 		postmaster_error("invalid datetoken tables, please fix");
  		ExitPostmaster(1);
  	}
  
***************
*** 826,832 ****
  	 *
  	 * CAUTION: when changing this list, check for side-effects on the signal
  	 * handling setup of child processes.  See tcop/postgres.c,
! 	 * bootstrap/bootstrap.c, postmaster/bgwriter.c, and postmaster/pgstat.c.
  	 */
  	pqinitmask();
  	PG_SETMASK(&BlockSig);
--- 827,834 ----
  	 *
  	 * CAUTION: when changing this list, check for side-effects on the signal
  	 * handling setup of child processes.  See tcop/postgres.c,
! 	 * bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/pgstat.c,
! 	 * and postmaster/pg_autovacuum.c.
  	 */
  	pqinitmask();
  	PG_SETMASK(&BlockSig);
***************
*** 975,984 ****
  	fp = AllocateFile(path, PG_BINARY_R);
  	if (fp == NULL)
  	{
! 		write_stderr("%s: could not find the database system\n"
! 					 "Expected to find it in the directory \"%s\",\n"
! 					 "but could not open file \"%s\": %s\n",
! 					 progname, checkdir, path, strerror(errno));
  		ExitPostmaster(2);
  	}
  	FreeFile(fp);
--- 977,987 ----
  	fp = AllocateFile(path, PG_BINARY_R);
  	if (fp == NULL)
  	{
! 		fprintf(stderr,
! 				gettext("%s: could not find the database system\n"
! 						"Expected to find it in the directory \"%s\",\n"
! 						"but could not open file \"%s\": %s\n"),
! 				progname, checkdir, path, strerror(errno));
  		ExitPostmaster(2);
  	}
  	FreeFile(fp);
***************
*** 1021,1028 ****
  	pid = fork();
  	if (pid == (pid_t) -1)
  	{
! 		write_stderr("%s: could not fork background process: %s\n",
! 					 progname, strerror(errno));
  		ExitPostmaster(1);
  	}
  	else if (pid)
--- 1024,1031 ----
  	pid = fork();
  	if (pid == (pid_t) -1)
  	{
! 		postmaster_error("could not fork background process: %s",
! 						 strerror(errno));
  		ExitPostmaster(1);
  	}
  	else if (pid)
***************
*** 1043,1050 ****
  #ifdef HAVE_SETSID
  	if (setsid() < 0)
  	{
! 		write_stderr("%s: could not dissociate from controlling TTY: %s\n",
! 					 progname, strerror(errno));
  		ExitPostmaster(1);
  	}
  #endif
--- 1046,1053 ----
  #ifdef HAVE_SETSID
  	if (setsid() < 0)
  	{
! 		postmaster_error("could not dissociate from controlling TTY: %s",
! 						 strerror(errno));
  		ExitPostmaster(1);
  	}
  #endif
***************
*** 1111,1119 ****
  	int			nSockets;
  	time_t		now,
  				last_touch_time;
! 	struct timeval earlier,
  				later;
! 	struct timezone tz;
  
  	gettimeofday(&earlier, &tz);
  	last_touch_time = time(NULL);
--- 1114,1122 ----
  	int			nSockets;
  	time_t		now,
  				last_touch_time;
! 	struct 		timeval earlier,
  				later;
! 	struct 		timezone tz;
  
  	gettimeofday(&earlier, &tz);
  	last_touch_time = time(NULL);
***************
*** 1217,1222 ****
--- 1220,1254 ----
  				kill(BgWriterPID, SIGUSR2);
  		}
  
+ 		/*
+ 		 * If no AutoVacuum process is running, and we are not in
+ 		 * a state that prevents it, start one.  It doesn't matter if this
+ 		 * fails, we'll just try again later.
+ 		 */
+ 		if (autovacuum_start_daemon)
+ 		{
+ 			if (pgstat_collect_tuplelevel)
+ 			{
+ 				if (AutoVacPID == 0 && StartupPID == 0 && !FatalError)
+ 				{
+ 					AutoVacPID = StartAutoVac();
+ 					if(pgstat_collect_resetonpmstart)
+ 						elog(WARNING,"pg_autovacuum: stats_reset_on_server_start should be disabled for optimal performance");
+ 					
+ 					/* If shutdown is pending, set it going */
+ 					if (Shutdown > NoShutdown && AutoVacPID != 0)
+ 						kill(AutoVacPID, SIGUSR2);
+ 				}
+ 			}
+ 			else
+ 				elog(WARNING, "pg_autovacuum: autovac is enabled, but requires stats_row_level which is not enabled");
+ 		}	
+ 		else if(AutoVacPID > 0)
+ 			kill(AutoVacPID, SIGUSR2);
+ 			
+ 		if (!autovacuum_start_daemon)
+ 			elog(DEBUG1, "pg_autovacuum: not enabled");
+ 			
  		/* If we have lost the stats collector, try to start a new one */
  		if (PgStatPID == 0 &&
  			StartupPID == 0 && !FatalError && Shutdown == NoShutdown)
***************
*** 1579,1584 ****
--- 1611,1631 ----
  	backendPID = (int) ntohl(canc->backendPID);
  	cancelAuthCode = (long) ntohl(canc->cancelAuthCode);
  
+ 	if (backendPID == BgWriterPID)
+ 	{
+ 		ereport(DEBUG2,
+ 				(errmsg_internal("ignoring cancel request for bgwriter process %d",
+ 								 backendPID)));
+ 		return;
+ 	}
+ 	if (backendPID == AutoVacPID)
+ 	{
+ 		ereport(DEBUG2,
+ 				(errmsg_internal("ignoring cancel request for autovacuum process %d",
+ 								 backendPID)));
+ 		return;
+ 	}
+ 
  	/*
  	 * See if we have a matching backend.  In the EXEC_BACKEND case, we
  	 * can no longer access the postmaster's own backend list, and must
***************
*** 1760,1765 ****
--- 1807,1814 ----
  		SignalChildren(SIGHUP);
  		if (BgWriterPID != 0)
  			kill(BgWriterPID, SIGHUP);
+ 		if (AutoVacPID != 0)
+ 			kill(AutoVacPID, SIGHUP);
  		/* PgStatPID does not currently need SIGHUP */
  		load_hba();
  		load_ident();
***************
*** 1818,1823 ****
--- 1867,1876 ----
  			/* And tell it to shut down */
  			if (BgWriterPID != 0)
  				kill(BgWriterPID, SIGUSR2);
+ 			/* I don't think we need to Start the autovac process if not running */
+ 			/* And tell it to shut down */
+ 			if (AutoVacPID != 0)
+ 				kill(AutoVacPID, SIGUSR2);
  			/* Tell pgstat to shut down too; nothing left for it to do */
  			if (PgStatPID != 0)
  				kill(PgStatPID, SIGQUIT);
***************
*** 1862,1867 ****
--- 1915,1923 ----
  			/* And tell it to shut down */
  			if (BgWriterPID != 0)
  				kill(BgWriterPID, SIGUSR2);
+ 			/* And tell it to shut down */
+ 			if (AutoVacPID != 0)
+ 				kill(AutoVacPID, SIGUSR2);
  			/* Tell pgstat to shut down too; nothing left for it to do */
  			if (PgStatPID != 0)
  				kill(PgStatPID, SIGQUIT);
***************
*** 1880,1885 ****
--- 1936,1943 ----
  				kill(StartupPID, SIGQUIT);
  			if (BgWriterPID != 0)
  				kill(BgWriterPID, SIGQUIT);
+ 			if (AutoVacPID != 0)
+ 				kill(AutoVacPID, SIGQUIT);
  			if (PgStatPID != 0)
  				kill(PgStatPID, SIGQUIT);
  			if (DLGetHead(BackendList))
***************
*** 1974,1979 ****
--- 2032,2043 ----
  			else if (PgStatPID == 0 && Shutdown == NoShutdown)
  				PgStatPID = pgstat_start();
  
+ 			/*
+ 			 * Shutdown autovac if a shutdown request was pending.
+ 			 */
+ 			if (Shutdown > NoShutdown && AutoVacPID != 0)
+ 				kill(AutoVacPID, SIGUSR2);
+ 			
  			continue;
  		}
  
***************
*** 2005,2010 ****
--- 2069,2094 ----
  		}
  
  		/*
+ 		 * Was it the autovac?
+ 		 */
+ 		if (AutoVacPID != 0 && pid == AutoVacPID)
+ 		{
+ 			AutoVacPID = 0;
+ 			if (exitstatus != 0)
+ 			{
+ 				/*
+ 				* Any unexpected exit of the autovacuum is treated as a crash.
+ 				* FIXME: This is useful for debugging autovac, but I think it should be 
+ 				* ripped out before final patch, autovac shouldn't crash the postmaster
+ 				*/
+ 				LogChildExit(LOG, gettext("pg_autovacuum process"),
+ 							pid, exitstatus);
+ 				HandleChildCrash(pid, exitstatus);
+ 				continue;
+ 			}
+ 		}
+ 		
+ 		/*
  		 * Was it the statistics collector?  If so, just try to start a new
  		 * one; no need to force reset of the rest of the system.  (If fail,
  		 * we'll try again in future cycles of the main loop.)
***************
*** 2032,2038 ****
  		 * Wait for all children exit, then reset shmem and
  		 * StartupDataBase.
  		 */
! 		if (DLGetHead(BackendList) || StartupPID != 0 || BgWriterPID != 0)
  			goto reaper_done;
  		ereport(LOG,
  			(errmsg("all server processes terminated; reinitializing")));
--- 2116,2122 ----
  		 * Wait for all children exit, then reset shmem and
  		 * StartupDataBase.
  		 */
! 		if (DLGetHead(BackendList) || StartupPID != 0 || BgWriterPID != 0 || AutoVacPID != 0)
  			goto reaper_done;
  		ereport(LOG,
  			(errmsg("all server processes terminated; reinitializing")));
***************
*** 2055,2060 ****
--- 2139,2147 ----
  		/* And tell it to shut down */
  		if (BgWriterPID != 0)
  			kill(BgWriterPID, SIGUSR2);
+ 		/* Tell AutoVac to shut down */
+ 		if (AutoVacPID != 0)
+ 			kill(AutoVacPID, SIGUSR2);
  	}
  
  reaper_done:
***************
*** 2203,2208 ****
--- 2290,2309 ----
  	}
  
  	FatalError = true;
+ 
+ 	/* Take care of the autovacuum too */
+ 	if (pid == AutoVacPID)
+ 		AutoVacPID = 0;
+ 	else if (AutoVacPID != 0 && !FatalError)
+ 	{
+ 		ereport(DEBUG2,
+ 				(errmsg_internal("sending %s to process %d",
+ 								 (SendStop ? "SIGSTOP" : "SIGQUIT"),
+ 								 (int) AutoVacPID)));
+ 		kill(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT));
+ 	}
+ 
+ 	FatalError = true;
  }
  
  /*
***************
*** 3167,3172 ****
--- 3268,3277 ----
  				ereport(LOG,
  						(errmsg("could not fork background writer process: %m")));
  				break;
+ 			case BS_XLOG_AUTOVAC:
+ 				ereport(LOG,
+ 						(errmsg("could not fork auto vacuum process: %m")));
+ 				break;
  			default:
  				ereport(LOG,
  						(errmsg("could not fork process: %m")));
***************
*** 3221,3226 ****
--- 3326,3349 ----
  	return true;
  }
  
+ /*
+  * This should be used only for reporting "interactive" errors (essentially,
+  * bogus arguments on the command line).  Once the postmaster is launched,
+  * use ereport.  In particular, don't use this for anything that occurs
+  * after pmdaemonize.
+  */
+ static void
+ postmaster_error(const char *fmt,...)
+ {
+ 	va_list		ap;
+ 
+ 	fprintf(stderr, "%s: ", progname);
+ 	va_start(ap, fmt);
+ 	vfprintf(stderr, gettext(fmt), ap);
+ 	va_end(ap);
+ 	fprintf(stderr, "\n");
+ }
+ 
  
  #ifdef EXEC_BACKEND
  
***************
*** 3660,3666 ****
  	if (r == WAIT_OBJECT_0)
  		pg_queue_signal(SIGCHLD);
  	else
! 		write_stderr("ERROR: failed to wait on child process handle: %d\n",
  				(int) GetLastError());
  	CloseHandle(procHandle);
  	return 0;
--- 3783,3789 ----
  	if (r == WAIT_OBJECT_0)
  		pg_queue_signal(SIGCHLD);
  	else
! 		fprintf(stderr, "ERROR: failed to wait on child process handle: %d\n",
  				(int) GetLastError());
  	CloseHandle(procHandle);
  	return 0;
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v
retrieving revision 1.219
diff -c -r1.219 guc.c
*** src/backend/utils/misc/guc.c	12 Jul 2004 02:22:51 -0000	1.219
--- src/backend/utils/misc/guc.c	18 Jul 2004 01:45:14 -0000
***************
*** 43,49 ****
--- 43,51 ----
  #include "optimizer/prep.h"
  #include "parser/parse_expr.h"
  #include "parser/parse_relation.h"
+ #include "pgstat.h"
  #include "postmaster/bgwriter.h"
+ #include "postmaster/pg_autovacuum.h"
  #include "postmaster/postmaster.h"
  #include "storage/bufmgr.h"
  #include "storage/fd.h"
***************
*** 55,61 ****
  #include "utils/builtins.h"
  #include "utils/memutils.h"
  #include "utils/pg_locale.h"
- #include "pgstat.h"
  
  char *guc_pgdata;
  char *guc_hbafile;
--- 57,62 ----
***************
*** 639,644 ****
--- 640,653 ----
  		&pgstat_collect_blocklevel,
  		false, NULL, NULL
  	},
+ 	{
+ 		{"autovacuum", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Starts the auto vacuum subprocess."),
+ 			NULL
+ 		},
+ 		&autovacuum_start_daemon,
+ 		false, NULL, NULL	 
+ 	},
  
  	{
  		{"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS,
***************
*** 1281,1286 ****
--- 1290,1319 ----
  		&block_size,
  		BLCKSZ, BLCKSZ, BLCKSZ, NULL, NULL
  	},
+ 	{
+ 		{"autovacuum_vacuum_threshold_base", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
+ 			NULL
+ 		},
+ 		&autovacuum_vacuum_base,
+ 		1000, 0, INT_MAX, NULL, NULL
+ 	},
+ 	{
+ 		{"autovacuum_analyze_threshold_base", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Minimum number of tuple updates or deletes prior to analyze."),
+ 			NULL
+ 		},
+ 		&autovacuum_analyze_base,
+ 		500, 0, INT_MAX, NULL, NULL
+ 	},
+ 	{
+ 		{"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Minimum number of tuple updates or deletes prior to analyze."),
+ 			NULL
+ 		},
+ 		&autovacuum_analyze_base,
+ 		500, 0, INT_MAX, NULL, NULL
+ 	},
  
  	/* End-of-list marker */
  	{
***************
*** 1361,1366 ****
--- 1394,1415 ----
  		&phony_random_seed,
  		0.5, 0.0, 1.0, assign_random_seed, show_random_seed
  	},
+ 	{
+ 		{"autovacuum_vacuum_threshold_sf", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Numer of tuple updates or deletes prior to vacuum as a factor of reltuples."),
+ 			NULL
+ 		},
+ 		&autovacuum_vacuum_scaling_factor,
+ 		2, 0, 100, NULL, NULL
+ 	},
+ 	{
+ 		{"autovacuum_analyze_threshold_sf", PGC_SIGHUP, AUTOVACUUM,
+ 			gettext_noop("Numer of tuple updates or deletes prior to analyze as a factor of reltuples."),
+ 			NULL
+ 		},
+ 		&autovacuum_analyze_scaling_factor,
+ 		1, 0, 100, NULL, NULL
+ 	},
  
  	/* End-of-list marker */
  	{
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.115
diff -c -r1.115 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample	11 Jul 2004 21:48:25 -0000	1.115
--- src/backend/utils/misc/postgresql.conf.sample	18 Jul 2004 01:45:14 -0000
***************
*** 228,233 ****
--- 228,243 ----
  
  
  #---------------------------------------------------------------------------
+ # VACUUM DAEMON
+ #---------------------------------------------------------------------------
+ 
+ #autovacuum = false  # requires stats_row_level = true
+ #autovacuum_vacuum_threshold_base = 1000
+ #autovacuum_vacuum_threshold_sf = 2
+ #autovacuum_analyze_threshold_base = 500
+ #autovacuum_analyze_threshold_sf = 1
+ 
+ #---------------------------------------------------------------------------
  # CLIENT CONNECTION DEFAULTS
  #---------------------------------------------------------------------------
  
Index: src/include/bootstrap/bootstrap.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/bootstrap/bootstrap.h,v
retrieving revision 1.35
diff -c -r1.35 bootstrap.h
*** src/include/bootstrap/bootstrap.h	29 May 2004 22:48:22 -0000	1.35
--- src/include/bootstrap/bootstrap.h	18 Jul 2004 01:45:15 -0000
***************
*** 59,63 ****
--- 59,64 ----
  #define BS_XLOG_BOOTSTRAP	1
  #define BS_XLOG_STARTUP		2
  #define BS_XLOG_BGWRITER	3
+ #define BS_XLOG_AUTOVAC		4
  
  #endif   /* BOOTSTRAP_H */
Index: src/include/postmaster/postmaster.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/postmaster/postmaster.h,v
retrieving revision 1.2
diff -c -r1.2 postmaster.h
*** src/include/postmaster/postmaster.h	30 May 2004 03:50:15 -0000	1.2
--- src/include/postmaster/postmaster.h	18 Jul 2004 01:45:15 -0000
***************
*** 29,34 ****
--- 29,35 ----
  extern bool Log_connections;
  extern bool log_hostname;
  extern char *rendezvous_name;
+ extern bool autovacuum_start_daemon; 
  
  #ifdef WIN32
  extern HANDLE PostmasterHandle;
Index: src/include/storage/proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/storage/proc.h,v
retrieving revision 1.69
diff -c -r1.69 proc.h
*** src/include/storage/proc.h	17 Jul 2004 03:31:26 -0000	1.69
--- src/include/storage/proc.h	18 Jul 2004 01:45:15 -0000
***************
*** 88,94 ****
  
  #define	DUMMY_PROC_DEFAULT	0
  #define	DUMMY_PROC_BGWRITER	1
! #define	NUM_DUMMY_PROCS		2
  
  
  /* configurable options */
--- 88,95 ----
  
  #define	DUMMY_PROC_DEFAULT	0
  #define	DUMMY_PROC_BGWRITER	1
! #define	DUMMY_PROC_AUTOVAC	2
! #define	NUM_DUMMY_PROCS		3
  
  
  /* configurable options */
Index: src/include/utils/guc_tables.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/utils/guc_tables.h,v
retrieving revision 1.12
diff -c -r1.12 guc_tables.h
*** src/include/utils/guc_tables.h	1 Jul 2004 00:51:44 -0000	1.12
--- src/include/utils/guc_tables.h	18 Jul 2004 01:45:15 -0000
***************
*** 71,76 ****
--- 71,77 ----
  	COMPAT_OPTIONS_CLIENT,
  	DEVELOPER_OPTIONS,
  	COMPILE_OPTIONS,
+ 	AUTOVACUUM,
  	CUSTOM_OPTIONS
  };
  
