Ok, here is a new patch for to integrate pg_autovacuum into the backend.

This patch adds the following to that last patch:
* updated to latest CVS
* changed GUC vars from autovac_* to autovacuum_*
* changed autovac_enabled GUC variable to autovacuum
* changed autovacuum GUC variable default to false
* improved autovacuum failure when row level stats aren't enabled

As before, this patch requires pg_autovacuum.c and .h get moved
from contrib to src/backend/postmaster and src/include/postmaster
respectively. In addition, the attached pg_autovacuum.h file must be put
in src/include/catelog/ for the new pg_autovacuum system
table.

Please apply to CVS or tell me what I need to change to get it applied.


Matthew


/*-------------------------------------------------------------------------
 *
 * pg_autovacuum.h
 *	  definition of the system "autovacuum" relation (pg_autovacuum)
 *
 * NOTE: an object is identified by the OID of the row that primarily
 * defines the object, plus the OID of the table that that row appears in.
 * For example, a function is identified by the OID of its pg_proc row
 * plus the pg_class OID of table pg_proc.	This allows unique identification
 * of objects without assuming that OIDs are unique across tables.
 *
 * Since attributes don't have OIDs of their own, we identify an attribute
 * comment by the objoid+classoid of its parent table, plus an "objsubid"
 * giving the attribute column number.	"objsubid" must be zero in a comment
 * for a table itself, so that it is distinct from any column comment.
 * Currently, objsubid is unused and zero for all other kinds of objects,
 * but perhaps it might be useful someday to associate comments with
 * constituent elements of other kinds of objects (arguments of a function,
 * for example).
 *
 *
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql-server/src/include/catalog/pg_autovacuum.h,v 1.20 2003/11/29 22:40:58 pgsql Exp $
 *
 * NOTES
 *		the genbki.sh script reads this file and generates .bki
 *		information from the DATA() statements.
 *
 *		XXX do NOT break up DATA() statements into multiple lines!
 *			the scripts are not as smart as you might think...
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_AUTOVACUUM_H
#define PG_AUTOVACUUM_H

/* ----------------
 *		postgres.h contains the system type definitions and the
 *		CATALOG(), BOOTSTRAP and DATA() sugar words so this file
 *		can be read by both genbki.sh and the C compiler.
 * ----------------
 */

/* ----------------
 *		pg_autovacuum definition.	cpp turns this into
 *		typedef struct FormData_pg_autovacuum
 * ----------------
 */
CATALOG(pg_autovacuum) BKI_WITHOUT_OIDS
{
	Oid			table_oid;		/* OID of table */
	int4		analyze_base_threshold; /* Base Threshold value */
	float4		vacuum_base_threshold;  /* Base Threshold value */
	int4		analyze_scaling_factor; /* Threshold of ins/upd/del's before analyze */
	float4		vacuum_scaling_factor;  /* Threshold of ins/upd/del's before vacuuum */
	int8		analyze_threshold; /* Threshold of ins/upd/del's before analyze */
	int8		vacuum_threshold;  /* Threshold of ins/upd/del's before vacuuum */
	int8		cnt_at_last_analyze;		/* equal to: inserts + updates as
										 * of the last analyze or initial
										 * values at startup */
	int8		cnt_at_last_vacuum;		/* equal to: deletes + updates as
										 * of the last vacuum or initial
										 * values at startup */
} FormData_pg_autovacuum;

/* ----------------
 *		Form_pg_autovacuum corresponds to a pointer to a tuple with
 *		the format of pg_autovacuum relation.
 * ----------------
 */
typedef FormData_pg_autovacuum *Form_pg_autovacuum;

/* ----------------
 *		compiler constants for pg_autovacuum
 * ----------------
 */
#define Natts_pg_autovacuum				9
#define Anum_pg_autovacuum_table_oid	1
#define Anum_pg_autovacuum_analyze_base_threshold		2
#define Anum_pg_autovacuum_vacuum_base_threshold		3
#define Anum_pg_autovacuum_analyze_scaling_factor		4
#define Anum_pg_autovacuum_vacuum_scaling_factor	5
#define Anum_pg_autovacuum_analyze_threshold		6
#define Anum_pg_autovacuum_vacuum_threshold		7
#define Anum_pg_autovacuum_cnt_at_last_analyze 	8
#define Anum_pg_autovacuum_cnt_at_last_vacuum 	9

/* ----------------
 *		initial contents of pg_autovacuum
 * ----------------
 */

/*
 *	Because the contents of this table are taken from the other *.h files,
 *	there is no initialization here.  The initial contents are extracted
 *	by genbki.sh and loaded during initdb.
 */

#endif   /* PG_AUTOVACUUM_H */
? 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
  };
  
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Reply via email to