Index: doc/src/sgml/catalogs.sgml =================================================================== RCS file: /home/alvherre/cvs/pgsql/doc/src/sgml/catalogs.sgml,v retrieving revision 2.110 diff -c -r2.110 catalogs.sgml *** doc/src/sgml/catalogs.sgml 31 Jul 2005 17:19:16 -0000 2.110 --- doc/src/sgml/catalogs.sgml 7 Aug 2005 19:03:22 -0000 *************** *** 1197,1202 **** --- 1197,1216 ---- Multiplier for reltuples to add to anl_base_thresh + + + vac_cost_delay + integer + + Custom vacuum_cost_delay parameter + + + + vac_cost_limit + integer + + Custom vacuum_cost_limit parameter + *************** *** 1217,1223 **** Any of the numerical fields can contain -1 (or indeed any negative value) to indicate that the system-wide default should ! be used for this particular value. --- 1231,1241 ---- Any of the numerical fields can contain -1 (or indeed any negative value) to indicate that the system-wide default should ! be used for this particular value. Observe that the ! vac_cost_delay variable inherits its default value from the ! autovacuum_vacuum_cost_delay configuration parameter, ! or from vacuum_cost_delay if the former is set to a negative ! value. The same applies to vac_cost_limit. Index: doc/src/sgml/runtime.sgml =================================================================== RCS file: /home/alvherre/cvs/pgsql/doc/src/sgml/runtime.sgml,v retrieving revision 1.341 diff -c -r1.341 runtime.sgml *** doc/src/sgml/runtime.sgml 30 Jul 2005 17:15:35 -0000 1.341 --- doc/src/sgml/runtime.sgml 31 Jul 2005 23:22:11 -0000 *************** *** 3399,3404 **** --- 3399,3436 ---- + + autovacuum_vacuum_cost_delay (integer) + + autovacuum_vacuum_cost_delay configuration parameter + + + + Specifies the default value that will be applied to each + VACUUM operation, for tables that do not have + a default value set in pg_autovacuum. If a + negative value is specified (like the default value of -1), + the vacuum_cost_delay value will be applied instead. + + + + + + autovacuum_vacuum_cost_limit (integer) + + autovacuum_vacuum_cost_limit configuration parameter + + + + Specifies the default value that will be applied to each + VACUUM operation, for tables that do not have + a default value set in pg_autovacuum. If a + negative value is specified (like the default value of -1), + the vacuum_cost_limit value will be applied instead. + + + + Index: src/backend/access/transam/xlog.c =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/access/transam/xlog.c,v retrieving revision 1.214 diff -c -r1.214 xlog.c *** src/backend/access/transam/xlog.c 30 Jul 2005 14:15:44 -0000 1.214 --- src/backend/access/transam/xlog.c 31 Jul 2005 21:36:45 -0000 *************** *** 33,38 **** --- 33,39 ---- #include "catalog/catversion.h" #include "catalog/pg_control.h" #include "miscadmin.h" + #include "pgstat.h" #include "postmaster/bgwriter.h" #include "storage/bufpage.h" #include "storage/fd.h" *************** *** 48,54 **** /* ! * Becauase O_DIRECT bypasses the kernel buffers, and because we never * read those buffers except during crash recovery, it is a win to use * it in all cases where we sync on each write(). We could allow O_DIRECT * with fsync(), but because skipping the kernel buffer forces writes out --- 49,55 ---- /* ! * Because O_DIRECT bypasses the kernel buffers, and because we never * read those buffers except during crash recovery, it is a win to use * it in all cases where we sync on each write(). We could allow O_DIRECT * with fsync(), but because skipping the kernel buffer forces writes out *************** *** 4544,4549 **** --- 4545,4555 ---- } while (record != NULL && recoveryContinue); /* + * Reset pgstat data, because it may be invalid after recovery. + */ + pgstat_reset_all(); + + /* * end of main redo apply loop */ Index: src/backend/postmaster/autovacuum.c =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/postmaster/autovacuum.c,v retrieving revision 1.2 diff -c -r1.2 autovacuum.c *** src/backend/postmaster/autovacuum.c 29 Jul 2005 19:30:04 -0000 1.2 --- src/backend/postmaster/autovacuum.c 8 Aug 2005 16:57:46 -0000 *************** *** 27,32 **** --- 27,33 ---- #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_autovacuum.h" + #include "catalog/pg_database.h" #include "commands/vacuum.h" #include "libpq/hba.h" #include "libpq/pqsignal.h" *************** *** 57,62 **** --- 58,66 ---- int autovacuum_anl_thresh; double autovacuum_anl_scale; + int autovacuum_vac_cost_delay; + int autovacuum_vac_cost_limit; + /* Flag to tell if we are in the autovacuum daemon process */ static bool am_autovacuum = false; *************** *** 64,69 **** --- 68,76 ---- static time_t last_autovac_start_time = 0; static time_t last_autovac_stop_time = 0; + /* Memory context for long-lived data */ + static MemoryContext AutovacMemCxt; + /* struct to keep list of candidate databases for vacuum */ typedef struct autovac_dbase { *************** *** 74,90 **** int32 age; } autovac_dbase; #ifdef EXEC_BACKEND static pid_t autovac_forkexec(void); #endif NON_EXEC_STATIC void AutoVacMain(int argc, char *argv[]); ! static void do_autovacuum(bool whole_db, 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, Form_pg_autovacuum avForm, List **vacuum_tables, List **analyze_tables); ! static void autovacuum_do_vac_analyze(List *relids, bool dovacuum); /* --- 81,107 ---- int32 age; } autovac_dbase; + /* struct to keep track of tables to vacuum */ + typedef struct autovac_table + { + Oid relid; + int vacuum_cost_delay; + int vacuum_cost_limit; + } autovac_table; + #ifdef EXEC_BACKEND static pid_t autovac_forkexec(void); #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, Form_pg_autovacuum avForm, List **vacuum_tables, List **analyze_tables); ! static void autovacuum_do_vac_analyze(List *relids, bool doanalyze, ! bool dovacuum, bool freeze); /* *************** *** 363,372 **** set_ps_display(db->name); ereport(LOG, (errmsg("autovacuum: processing database \"%s\"", db->name))); /* ! * And do an appropriate amount of work on it */ ! do_autovacuum(whole_db, db->entry); } /* One iteration done, go away */ --- 380,400 ---- set_ps_display(db->name); ereport(LOG, (errmsg("autovacuum: processing database \"%s\"", db->name))); + + /* Create the memory context where cross-transaction state is stored */ + AutovacMemCxt = AllocSetContextCreate(TopMemoryContext, + "Autovacuum context", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + /* ! * And do an appropriate amount of work */ ! if (whole_db) ! process_whole_db(); ! else ! do_autovacuum(db->entry); } /* One iteration done, go away */ *************** *** 421,433 **** } /* ! * Process a database. * ! * If whole_db is true, the database is processed as a whole, and the ! * dbentry parameter is ignored. If it's false, 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 test_rel_for_autovac generates two separate lists, one for * vacuum and other for analyze. This is to facilitate processing all --- 449,511 ---- } /* ! * Process a whole database. If it's a template database or is disallowing ! * connection by means of datallowconn=false, then issue a VACUUM FREEZE. ! * Else use a plain VACUUM. ! */ ! static void ! process_whole_db(void) ! { ! Relation dbRel; ! ScanKeyData entry[1]; ! HeapScanDesc scan; ! HeapTuple tup; ! Form_pg_database dbForm; ! bool freeze; ! ! /* Start a transaction so our commands have one to play into. */ ! StartTransactionCommand(); ! ! dbRel = heap_open(DatabaseRelationId, AccessShareLock); ! ! /* Must use a heap scan, since there's no syscache for pg_database */ ! ScanKeyInit(&entry[0], ! ObjectIdAttributeNumber, ! BTEqualStrategyNumber, F_OIDEQ, ! ObjectIdGetDatum(MyDatabaseId)); ! ! scan = heap_beginscan(dbRel, SnapshotNow, 1, entry); ! ! tup = heap_getnext(scan, ForwardScanDirection); ! ! if (!HeapTupleIsValid(tup)) ! elog(ERROR, "could not find tuple for database %u", MyDatabaseId); ! ! dbForm = (Form_pg_database) GETSTRUCT(tup); ! ! if (!dbForm->datallowconn || dbForm->datistemplate) ! freeze = true; ! else ! freeze = false; ! ! heap_endscan(scan); ! heap_close(dbRel, AccessShareLock); ! ! elog(DEBUG2, "autovacuum: VACUUM%s whole database", ! (freeze) ? " FREEZE" : ""); ! ! autovacuum_do_vac_analyze(NIL, false, true, freeze); ! ! /* Finally close out the last transaction. */ ! CommitTransactionCommand(); ! } ! ! /* ! * Process a database table per table * ! * 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 test_rel_for_autovac generates two separate lists, one for * vacuum and other for analyze. This is to facilitate processing all *************** *** 437,443 **** * order not to ignore shutdown commands for too long. */ static void ! do_autovacuum(bool whole_db, PgStat_StatDBEntry *dbentry) { Relation classRel, avRel; --- 515,521 ---- * order not to ignore shutdown commands for too long. */ static void ! do_autovacuum(PgStat_StatDBEntry *dbentry) { Relation classRel, avRel; *************** *** 445,460 **** HeapScanDesc relScan; List *vacuum_tables = NIL, *analyze_tables = NIL; ! MemoryContext AutovacMemCxt; ! ! Assert(whole_db || PointerIsValid(dbentry)); ! ! /* Memory context where cross-transaction state is stored */ ! AutovacMemCxt = AllocSetContextCreate(TopMemoryContext, ! "Autovacuum context", ! ALLOCSET_DEFAULT_MINSIZE, ! ALLOCSET_DEFAULT_INITSIZE, ! ALLOCSET_DEFAULT_MAXSIZE); /* Start a transaction so our commands have one to play into. */ StartTransactionCommand(); --- 523,529 ---- HeapScanDesc relScan; List *vacuum_tables = NIL, *analyze_tables = NIL; ! PgStat_StatDBEntry *shared; /* Start a transaction so our commands have one to play into. */ StartTransactionCommand(); *************** *** 467,559 **** */ MemoryContextSwitchTo(AutovacMemCxt); ! if (whole_db) ! { ! elog(DEBUG2, "autovacuum: VACUUM ANALYZE whole database"); ! autovacuum_do_vac_analyze(NIL, true); ! } ! else ! { ! /* the hash entry where pgstat stores shared relations */ ! PgStat_StatDBEntry *shared = pgstat_fetch_stat_dbentry(InvalidOid); ! classRel = heap_open(RelationRelationId, AccessShareLock); ! avRel = heap_open(AutovacuumRelationId, AccessShareLock); ! relScan = heap_beginscan(classRel, SnapshotNow, 0, NULL); ! /* Scan pg_class looking for tables to vacuum */ ! while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) ! { ! Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); ! Form_pg_autovacuum avForm = NULL; ! PgStat_StatTabEntry *tabentry; ! SysScanDesc avScan; ! HeapTuple avTup; ! ScanKeyData entry[1]; ! Oid relid; ! ! /* Skip non-table entries. */ ! /* XXX possibly allow RELKIND_TOASTVALUE entries here too? */ ! if (classForm->relkind != RELKIND_RELATION) ! continue; ! /* ! * Skip temp tables (i.e. those in temp namespaces). We cannot ! * safely process other backends' temp tables. ! */ ! if (isTempNamespace(classForm->relnamespace)) ! continue; ! relid = HeapTupleGetOid(tuple); ! /* See if we have a pg_autovacuum entry for this relation. */ ! ScanKeyInit(&entry[0], ! Anum_pg_autovacuum_vacrelid, ! BTEqualStrategyNumber, F_OIDEQ, ! ObjectIdGetDatum(relid)); ! avScan = systable_beginscan(avRel, AutovacuumRelidIndexId, true, ! SnapshotNow, 1, entry); ! avTup = systable_getnext(avScan); ! if (HeapTupleIsValid(avTup)) ! avForm = (Form_pg_autovacuum) GETSTRUCT(avTup); ! if (classForm->relisshared && PointerIsValid(shared)) ! tabentry = hash_search(shared->tables, &relid, ! HASH_FIND, NULL); ! else ! tabentry = hash_search(dbentry->tables, &relid, ! HASH_FIND, NULL); ! test_rel_for_autovac(relid, tabentry, classForm, avForm, ! &vacuum_tables, &analyze_tables); ! systable_endscan(avScan); ! } ! heap_endscan(relScan); ! heap_close(avRel, AccessShareLock); ! heap_close(classRel, AccessShareLock); ! CHECK_FOR_INTERRUPTS(); ! /* ! * Perform operations on collected tables. ! */ ! if (analyze_tables) ! autovacuum_do_vac_analyze(analyze_tables, false); ! CHECK_FOR_INTERRUPTS(); ! /* get back to proper context */ ! MemoryContextSwitchTo(AutovacMemCxt); ! if (vacuum_tables) ! autovacuum_do_vac_analyze(vacuum_tables, true); } /* Finally close out the last transaction. */ --- 536,632 ---- */ MemoryContextSwitchTo(AutovacMemCxt); ! /* The database hash where pgstat keeps shared relations */ ! shared = pgstat_fetch_stat_dbentry(InvalidOid); ! classRel = heap_open(RelationRelationId, AccessShareLock); ! avRel = heap_open(AutovacuumRelationId, AccessShareLock); ! relScan = heap_beginscan(classRel, SnapshotNow, 0, NULL); ! /* Scan pg_class looking for tables to vacuum */ ! while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) ! { ! Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); ! Form_pg_autovacuum avForm = NULL; ! PgStat_StatTabEntry *tabentry; ! SysScanDesc avScan; ! HeapTuple avTup; ! ScanKeyData entry[1]; ! Oid relid; ! ! /* Skip non-table entries. */ ! /* XXX possibly allow RELKIND_TOASTVALUE entries here too? */ ! if (classForm->relkind != RELKIND_RELATION) ! continue; ! /* ! * Skip temp tables (i.e. those in temp namespaces). We cannot ! * safely process other backends' temp tables. ! */ ! if (isTempNamespace(classForm->relnamespace)) ! continue; ! relid = HeapTupleGetOid(tuple); ! /* See if we have a pg_autovacuum entry for this relation. */ ! ScanKeyInit(&entry[0], ! Anum_pg_autovacuum_vacrelid, ! BTEqualStrategyNumber, F_OIDEQ, ! ObjectIdGetDatum(relid)); ! avScan = systable_beginscan(avRel, AutovacuumRelidIndexId, true, ! SnapshotNow, 1, entry); ! avTup = systable_getnext(avScan); ! if (HeapTupleIsValid(avTup)) ! avForm = (Form_pg_autovacuum) GETSTRUCT(avTup); ! if (classForm->relisshared && PointerIsValid(shared)) ! tabentry = hash_search(shared->tables, &relid, ! HASH_FIND, NULL); ! else ! tabentry = hash_search(dbentry->tables, &relid, ! HASH_FIND, NULL); ! test_rel_for_autovac(relid, tabentry, classForm, avForm, ! &vacuum_tables, &analyze_tables); ! systable_endscan(avScan); ! } ! heap_endscan(relScan); ! heap_close(avRel, AccessShareLock); ! heap_close(classRel, AccessShareLock); ! CHECK_FOR_INTERRUPTS(); ! /* ! * Perform operations on collected tables. ! */ ! if (analyze_tables) ! autovacuum_do_vac_analyze(analyze_tables, true, false, false); ! CHECK_FOR_INTERRUPTS(); ! if (vacuum_tables) ! { ! ListCell *cell; ! ! ! foreach(cell, vacuum_tables) ! { ! autovac_table *tab = lfirst(cell); ! /* Set the cost vacuum parameters for this table */ ! VacuumCostDelay = tab->vacuum_cost_delay; ! VacuumCostLimit = tab->vacuum_cost_limit; ! ! autovacuum_do_vac_analyze(list_make1_oid(tab->relid), true, ! true, true); ! } } /* Finally close out the last transaction. */ *************** *** 606,611 **** --- 679,687 ---- /* number of vacuum (resp. analyze) tuples at this time */ float4 vactuples, anltuples; + /* cost-based vacuum delay parameters */ + int vac_cost_limit; + int vac_cost_delay; /* User disabled it in pg_autovacuum? */ if (avForm && !avForm->enabled) *************** *** 645,650 **** --- 721,734 ---- autovacuum_anl_scale : avForm->anl_scale_factor; anl_base_thresh = (avForm->anl_base_thresh < 0) ? autovacuum_anl_thresh : avForm->anl_base_thresh; + + vac_cost_limit = (avForm->vac_cost_limit < 0) ? + (autovacuum_vac_cost_limit < 0) ? VacuumCostLimit : + autovacuum_vac_cost_limit : avForm->vac_cost_limit; + + vac_cost_delay = (avForm->vac_cost_delay < 0) ? + (autovacuum_vac_cost_delay < 0) ? VacuumCostDelay : + autovacuum_vac_cost_delay : avForm->vac_cost_delay; } else { *************** *** 653,658 **** --- 737,748 ---- anl_scale_factor = autovacuum_anl_scale; anl_base_thresh = autovacuum_anl_thresh; + + vac_cost_limit = (autovacuum_vac_cost_limit < 0) ? + VacuumCostLimit : autovacuum_vac_cost_limit; + + vac_cost_delay = (autovacuum_vac_cost_delay < 0) ? + VacuumCostDelay : autovacuum_vac_cost_delay; } vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples; *************** *** 668,679 **** RelationGetRelationName(rel), vactuples, vacthresh, anltuples, anlthresh); /* Determine if this table needs vacuum or analyze. */ if (vactuples > vacthresh) { elog(DEBUG2, "will VACUUM ANALYZE %s", RelationGetRelationName(rel)); ! *vacuum_tables = lappend_oid(*vacuum_tables, relid); } else if (anltuples > anlthresh) { --- 758,779 ---- RelationGetRelationName(rel), vactuples, vacthresh, anltuples, anlthresh); + Assert(CurrentMemoryContext == AutovacMemCxt); + /* Determine if this table needs vacuum or analyze. */ if (vactuples > vacthresh) { + autovac_table *tab = (autovac_table *) + palloc(sizeof(autovac_table)); + elog(DEBUG2, "will VACUUM ANALYZE %s", RelationGetRelationName(rel)); ! ! tab->relid = relid; ! tab->vacuum_cost_limit = vac_cost_limit; ! tab->vacuum_cost_delay = vac_cost_delay; ! ! *vacuum_tables = lappend(*vacuum_tables, tab); } else if (anltuples > anlthresh) { *************** *** 691,704 **** /* * autovacuum_do_vac_analyze ! * Vacuum or analyze a list of tables; or all tables if relids = NIL ! * ! * We must be in AutovacMemCxt when this routine is called. */ static void ! autovacuum_do_vac_analyze(List *relids, bool dovacuum) { ! VacuumStmt *vacstmt = makeNode(VacuumStmt); /* * Point QueryContext to the autovac memory context to fake out the --- 791,812 ---- /* * autovacuum_do_vac_analyze ! * Vacuum and/or analyze a list of tables; or all tables if relids = NIL */ static void ! autovacuum_do_vac_analyze(List *relids, bool doanalyze, bool dovacuum, ! bool freeze) { ! VacuumStmt *vacstmt; ! MemoryContext old_cxt; ! ! /* ! * The node must survive transaction boundaries, so make sure we create it ! * in a long-lived context ! */ ! old_cxt = MemoryContextSwitchTo(AutovacMemCxt); ! ! vacstmt = makeNode(VacuumStmt); /* * Point QueryContext to the autovac memory context to fake out the *************** *** 710,722 **** /* Set up command parameters */ vacstmt->vacuum = dovacuum; vacstmt->full = false; ! vacstmt->analyze = true; ! vacstmt->freeze = false; vacstmt->verbose = false; vacstmt->relation = NULL; /* all tables, or not used if relids != NIL */ vacstmt->va_cols = NIL; vacuum(vacstmt, relids); } /* --- 818,833 ---- /* Set up command parameters */ vacstmt->vacuum = dovacuum; vacstmt->full = false; ! vacstmt->analyze = doanalyze; ! vacstmt->freeze = freeze; vacstmt->verbose = false; vacstmt->relation = NULL; /* all tables, or not used if relids != NIL */ vacstmt->va_cols = NIL; vacuum(vacstmt, relids); + + pfree(vacstmt); + MemoryContextSwitchTo(old_cxt); } /* Index: src/backend/postmaster/pgstat.c =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/postmaster/pgstat.c,v retrieving revision 1.102 diff -c -r1.102 pgstat.c *** src/backend/postmaster/pgstat.c 29 Jul 2005 19:30:04 -0000 1.102 --- src/backend/postmaster/pgstat.c 31 Jul 2005 21:36:07 -0000 *************** *** 99,105 **** * ---------- */ bool pgstat_collect_startcollector = true; ! bool pgstat_collect_resetonpmstart = true; bool pgstat_collect_querystring = false; bool pgstat_collect_tuplelevel = false; bool pgstat_collect_blocklevel = false; --- 99,105 ---- * ---------- */ bool pgstat_collect_startcollector = true; ! bool pgstat_collect_resetonpmstart = false; bool pgstat_collect_querystring = false; bool pgstat_collect_tuplelevel = false; bool pgstat_collect_blocklevel = false; *************** *** 236,242 **** * statistics on postmaster start, simply remove the stats file. */ if (!pgstat_collect_startcollector || pgstat_collect_resetonpmstart) ! unlink(PGSTAT_STAT_FILENAME); /* * Nothing else required if collector will not get started --- 236,242 ---- * statistics on postmaster start, simply remove the stats file. */ if (!pgstat_collect_startcollector || pgstat_collect_resetonpmstart) ! pgstat_reset_all(); /* * Nothing else required if collector will not get started *************** *** 455,460 **** --- 455,472 ---- pgstat_collect_blocklevel = false; } + /* + * pgstat_reset_all() - + * + * Remove the stats file. This is used on server start if the + * stats_reset_on_server_start feature is enabled, or if WAL + * recovery is needed after a crash. + */ + void + pgstat_reset_all(void) + { + unlink(PGSTAT_STAT_FILENAME); + } #ifdef EXEC_BACKEND Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/utils/misc/guc.c,v retrieving revision 1.280 diff -c -r1.280 guc.c *** src/backend/utils/misc/guc.c 30 Jul 2005 15:17:20 -0000 1.280 --- src/backend/utils/misc/guc.c 31 Jul 2005 21:15:36 -0000 *************** *** 672,678 **** NULL }, &pgstat_collect_resetonpmstart, ! true, NULL, NULL }, { {"stats_command_string", PGC_SUSET, STATS_COLLECTOR, --- 672,678 ---- NULL }, &pgstat_collect_resetonpmstart, ! false, NULL, NULL }, { {"stats_command_string", PGC_SUSET, STATS_COLLECTOR, *************** *** 1161,1166 **** --- 1161,1184 ---- }, { + {"autovacuum_vacuum_cost_delay", PGC_USERSET, AUTOVACUUM, + gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."), + NULL + }, + &autovacuum_vac_cost_delay, + -1, -1, 1000, NULL, NULL + }, + + { + {"autovacuum_vacuum_cost_limit", PGC_USERSET, AUTOVACUUM, + gettext_noop("Vacuum cost amount available before napping, for autovacuum."), + NULL + }, + &autovacuum_vac_cost_limit, + -1, -1, 10000, NULL, NULL + }, + + { {"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL, gettext_noop("Sets the maximum number of simultaneously open files for each server process."), NULL Index: src/backend/utils/misc/postgresql.conf.sample =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/utils/misc/postgresql.conf.sample,v retrieving revision 1.155 diff -c -r1.155 postgresql.conf.sample *** src/backend/utils/misc/postgresql.conf.sample 30 Jul 2005 15:17:20 -0000 1.155 --- src/backend/utils/misc/postgresql.conf.sample 31 Jul 2005 21:16:43 -0000 *************** *** 287,293 **** #stats_command_string = off #stats_block_level = off #stats_row_level = off ! #stats_reset_on_server_start = on #--------------------------------------------------------------------------- --- 287,293 ---- #stats_command_string = off #stats_block_level = off #stats_row_level = off ! #stats_reset_on_server_start = off #--------------------------------------------------------------------------- *************** *** 300,305 **** --- 300,309 ---- #autovacuum_analyze_threshold = 500 # min # of tuple updates before analyze #autovacuum_vacuum_scale_factor = 0.4 # fraction of rel size before vacuum #autovacuum_analyze_scale_factor = 0.2 # fraction of rel size before analyze + #autovacuum_vacuum_cost_delay = -1 # default vacuum cost delay for autovac + # negative means use vacuum_cost_delay + #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for autovac + # negative means use vacuum_cost_limit #--------------------------------------------------------------------------- Index: src/include/pgstat.h =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/include/pgstat.h,v retrieving revision 1.34 diff -c -r1.34 pgstat.h *** src/include/pgstat.h 29 Jul 2005 19:30:09 -0000 1.34 --- src/include/pgstat.h 31 Jul 2005 21:32:59 -0000 *************** *** 367,372 **** --- 367,373 ---- extern void pgstat_init(void); extern int pgstat_start(void); extern void pgstat_beterm(int pid); + extern void pgstat_reset_all(void); #ifdef EXEC_BACKEND extern void PgstatBufferMain(int argc, char *argv[]); Index: src/include/catalog/pg_autovacuum.h =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/include/catalog/pg_autovacuum.h,v retrieving revision 1.1 diff -c -r1.1 pg_autovacuum.h *** src/include/catalog/pg_autovacuum.h 14 Jul 2005 05:13:42 -0000 1.1 --- src/include/catalog/pg_autovacuum.h 31 Jul 2005 23:26:27 -0000 *************** *** 34,39 **** --- 34,41 ---- float4 vac_scale_factor; /* reltuples scaling factor */ int4 anl_base_thresh; /* base threshold value */ float4 anl_scale_factor; /* reltuples scaling factor */ + int4 vac_cost_delay; /* vacuum cost-based delay */ + int4 vac_cost_limit; /* vacuum cost limit */ } FormData_pg_autovacuum; /* ---------------- *************** *** 47,59 **** * compiler constants for pg_autovacuum * ---------------- */ ! #define Natts_pg_autovacuum 6 #define Anum_pg_autovacuum_vacrelid 1 #define Anum_pg_autovacuum_enabled 2 #define Anum_pg_autovacuum_vac_base_thresh 3 #define Anum_pg_autovacuum_vac_scale_factor 4 #define Anum_pg_autovacuum_anl_base_thresh 5 #define Anum_pg_autovacuum_anl_scale_factor 6 /* There are no preloaded tuples in pg_autovacuum.h */ --- 49,63 ---- * compiler constants for pg_autovacuum * ---------------- */ ! #define Natts_pg_autovacuum 8 #define Anum_pg_autovacuum_vacrelid 1 #define Anum_pg_autovacuum_enabled 2 #define Anum_pg_autovacuum_vac_base_thresh 3 #define Anum_pg_autovacuum_vac_scale_factor 4 #define Anum_pg_autovacuum_anl_base_thresh 5 #define Anum_pg_autovacuum_anl_scale_factor 6 + #define Anum_pg_autovacuum_vac_cost_delay 7 + #define Anum_pg_autovacuum_vac_cost_limit 8 /* There are no preloaded tuples in pg_autovacuum.h */ Index: src/include/postmaster/autovacuum.h =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/include/postmaster/autovacuum.h,v retrieving revision 1.1 diff -c -r1.1 autovacuum.h *** src/include/postmaster/autovacuum.h 14 Jul 2005 05:13:43 -0000 1.1 --- src/include/postmaster/autovacuum.h 31 Jul 2005 17:32:12 -0000 *************** *** 21,26 **** --- 21,28 ---- extern double autovacuum_vac_scale; extern int autovacuum_anl_thresh; extern double autovacuum_anl_scale; + extern int autovacuum_vac_cost_delay; + extern int autovacuum_vac_cost_limit; /* Status inquiry functions */ extern bool AutoVacuumingActive(void);