Commit 29094193 authored by Tom Lane's avatar Tom Lane

Integrate autovacuum functionality into the backend. There's still a

few loose ends to be dealt with, but it seems to work.  Alvaro Herrera,
based on the contrib code by Matthew O'Connor.
parent f2bf2d2d
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.107 2005/07/07 20:39:56 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.108 2005/07/14 05:13:38 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
...@@ -88,6 +88,11 @@ ...@@ -88,6 +88,11 @@
<entry>authorization identifier membership relationships</entry> <entry>authorization identifier membership relationships</entry>
</row> </row>
<row>
<entry><link linkend="catalog-pg-autovacuum"><structname>pg_autovacuum</structname></link></entry>
<entry>per-relation autovacuum configuration parameters</entry>
</row>
<row> <row>
<entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry> <entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry>
<entry>casts (data type conversions)</entry> <entry>casts (data type conversions)</entry>
...@@ -1102,6 +1107,104 @@ ...@@ -1102,6 +1107,104 @@
</sect1> </sect1>
<sect1 id="catalog-pg-autovacuum">
<title><structname>pg_autovacuum</structname></title>
<indexterm zone="catalog-pg-autovacuum">
<primary>pg_autovacuum</primary>
</indexterm>
<para>
The catalog <structname>pg_autovacuum</structname> stores optional
per-relation configuration parameters for <quote>autovacuum</>.
If there is an entry here for a particular relation, the given
parameters will be used for autovacuuming that table. If no entry
is present, the system-wide defaults will be used.
</para>
<table>
<title><structname>pg_autovacuum</> Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>vacrelid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
<entry>The table this entry is for</entry>
</row>
<row>
<entry><structfield>enabled</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If false, this table is never autovacuumed</entry>
</row>
<row>
<entry><structfield>vac_base_thresh</structfield></entry>
<entry><type>integer</type></entry>
<entry></entry>
<entry>Minimum number of modified tuples before vacuum</entry>
</row>
<row>
<entry><structfield>vac_scale_factor</structfield></entry>
<entry><type>float4</type></entry>
<entry></entry>
<entry>Multiplier for reltuples to add to
<structfield>vac_base_thresh</></entry>
</row>
<row>
<entry><structfield>anl_base_thresh</structfield></entry>
<entry><type>integer</type></entry>
<entry></entry>
<entry>Minimum number of modified tuples before analyze</entry>
</row>
<row>
<entry><structfield>anl_scale_factor</structfield></entry>
<entry><type>float4</type></entry>
<entry></entry>
<entry>Multiplier for reltuples to add to
<structfield>anl_base_thresh</></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The autovacuum daemon will initiate a <command>VACUUM</> operation
on a particular table when the number of updated or deleted tuples
exceeds <structfield>vac_base_thresh</structfield> plus
<structfield>vac_scale_factor</structfield> times the number of
live tuples currently estimated to be in the relation.
Similarly, it will initiate an <command>ANALYZE</> operation
when the number of inserted, updated or deleted tuples
exceeds <structfield>anl_base_thresh</structfield> plus
<structfield>anl_scale_factor</structfield> times the number of
live tuples currently estimated to be in the relation.
</para>
<para>
Any of the numerical fields can contain <literal>-1</> (or indeed
any negative value) to indicate that the system-wide default should
be used for this particular value.
</para>
</sect1>
<sect1 id="catalog-pg-cast"> <sect1 id="catalog-pg-cast">
<title><structname>pg_cast</structname></title> <title><structname>pg_cast</structname></title>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.337 2005/07/06 14:45:12 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.338 2005/07/14 05:13:38 tgl Exp $
--> -->
<chapter Id="runtime"> <chapter Id="runtime">
...@@ -3173,7 +3173,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows ...@@ -3173,7 +3173,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows
If on, collected statistics are zeroed out whenever the server If on, collected statistics are zeroed out whenever the server
is restarted. If off, statistics are accumulated across server is restarted. If off, statistics are accumulated across server
restarts. The default is <literal>on</>. This option can only restarts. The default is <literal>on</>. This option can only
be set at server start. be set at server start.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -3182,6 +3182,127 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows ...@@ -3182,6 +3182,127 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows
</sect3> </sect3>
</sect2> </sect2>
<sect2 id="runtime-config-autovacuum">
<title>Automatic Vacuuming</title>
<para>
Beginning in <productname>PostgreSQL</> 8.1, there is an optional server
process called the <firstterm>autovacuum daemon</>, whose purpose is
to automate the issuance of periodic <command>VACUUM</> and
<command>ANALYZE</> commands. When enabled, the autovacuum daemon
runs periodically and checks for tables that have had a large number
of updated or deleted tuples. This check uses the row-level statistics
collection facility; therefore, the autovacuum daemon cannot be used
unless <xref linkend="guc-stats-start-collector"> and
<xref linkend="guc-stats-row-level"> are set TRUE. Also, it's
important to allow a slot for the autovacuum process when choosing
the value of <xref linkend="guc-superuser-reserved-connections">.
</para>
<variablelist>
<varlistentry id="guc-autovacuum" xreflabel="autovacuum">
<term><varname>autovacuum</varname> (<type>boolean</type>)</term>
<indexterm>
<primary><varname>autovacuum</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Controls whether the server should start the
autovacuum subprocess. This is off by default.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-naptime" xreflabel="autovacuum_naptime">
<term><varname>autovacuum_naptime</varname> (<type>integer</type>)</term>
<indexterm>
<primary><varname>autovacuum_naptime</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies the delay between activity rounds for the autovacuum
subprocess. In each round the subprocess examines one database
and issues <command>VACUUM</> and <command>ANALYZE</> commands
as needed for tables in that database. The delay is measured
in seconds, and the default is 60.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold">
<term><varname>autovacuum_vacuum_threshold</varname> (<type>integer</type>)</term>
<indexterm>
<primary><varname>autovacuum_vacuum_threshold</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies the minimum number of updated or deleted tuples needed
to trigger a <command>VACUUM</> in any one table.
The default is 1000.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-analyze-threshold" xreflabel="autovacuum_analyze_threshold">
<term><varname>autovacuum_analyze_threshold</varname> (<type>integer</type>)</term>
<indexterm>
<primary><varname>autovacuum_analyze_threshold</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies the minimum number of inserted, updated or deleted tuples
needed to trigger an <command>ANALYZE</> in any one table.
The default is 500.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor">
<term><varname>autovacuum_vacuum_scale_factor</varname> (<type>floating point</type>)</term>
<indexterm>
<primary><varname>autovacuum_vacuum_scale_factor</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies a fraction of the table size to add to
<varname>autovacuum_vacuum_threshold</varname>
when deciding whether to trigger a <command>VACUUM</>.
The default is 0.4.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-analyze-scale-factor" xreflabel="autovacuum_analyze_scale_factor">
<term><varname>autovacuum_analyze_scale_factor</varname> (<type>floating point</type>)</term>
<indexterm>
<primary><varname>autovacuum_analyze_scale_factor</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies a fraction of the table size to add to
<varname>autovacuum_analyze_threshold</varname>
when deciding whether to trigger an <command>ANALYZE</>.
The default is 0.2.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 id="runtime-config-client"> <sect2 id="runtime-config-client">
<title>Client Connection Defaults</title> <title>Client Connection Defaults</title>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# #
# Makefile for backend/catalog # Makefile for backend/catalog
# #
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.55 2005/07/07 20:39:57 tgl Exp $ # $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.56 2005/07/14 05:13:39 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -27,7 +27,7 @@ SUBSYS.o: $(OBJS) ...@@ -27,7 +27,7 @@ SUBSYS.o: $(OBJS)
# indexing.h had better be last. # indexing.h had better be last.
POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_proc.h pg_type.h pg_attribute.h pg_class.h \ pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \ pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.86 2005/05/06 17:24:53 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.87 2005/07/14 05:13:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "pgstat.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/datum.h" #include "utils/datum.h"
...@@ -77,7 +78,7 @@ static void compute_index_stats(Relation onerel, double totalrows, ...@@ -77,7 +78,7 @@ static void compute_index_stats(Relation onerel, double totalrows,
MemoryContext col_context); MemoryContext col_context);
static VacAttrStats *examine_attribute(Relation onerel, int attnum); static VacAttrStats *examine_attribute(Relation onerel, int attnum);
static int acquire_sample_rows(Relation onerel, HeapTuple *rows, static int acquire_sample_rows(Relation onerel, HeapTuple *rows,
int targrows, double *totalrows); int targrows, double *totalrows, double *totaldeadrows);
static double random_fract(void); static double random_fract(void);
static double init_selection_state(int n); static double init_selection_state(int n);
static double get_next_S(double t, int n, double *stateptr); static double get_next_S(double t, int n, double *stateptr);
...@@ -108,7 +109,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) ...@@ -108,7 +109,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
AnlIndexData *indexdata; AnlIndexData *indexdata;
int targrows, int targrows,
numrows; numrows;
double totalrows; double totalrows,
totaldeadrows;
HeapTuple *rows; HeapTuple *rows;
if (vacstmt->verbose) if (vacstmt->verbose)
...@@ -309,6 +311,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) ...@@ -309,6 +311,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
*/ */
if (attr_cnt <= 0 && !analyzableindex) if (attr_cnt <= 0 && !analyzableindex)
{ {
/*
* We report that the table is empty; this is just so that the
* autovacuum code doesn't go nuts trying to get stats about
* a zero-column table.
*/
if (!vacstmt->vacuum)
pgstat_report_analyze(RelationGetRelid(onerel), 0, 0);
vac_close_indexes(nindexes, Irel, AccessShareLock); vac_close_indexes(nindexes, Irel, AccessShareLock);
relation_close(onerel, AccessShareLock); relation_close(onerel, AccessShareLock);
return; return;
...@@ -340,7 +350,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) ...@@ -340,7 +350,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
* Acquire the sample rows * Acquire the sample rows
*/ */
rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple)); rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
numrows = acquire_sample_rows(onerel, rows, targrows, &totalrows); numrows = acquire_sample_rows(onerel, rows, targrows,
&totalrows, &totaldeadrows);
/* /*
* Compute the statistics. Temporary results during the calculations * Compute the statistics. Temporary results during the calculations
...@@ -423,6 +434,10 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) ...@@ -423,6 +434,10 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
totalindexrows, totalindexrows,
false); false);
} }
/* report results to the stats collector, too */
pgstat_report_analyze(RelationGetRelid(onerel), totalrows,
totaldeadrows);
} }
/* Done with indexes */ /* Done with indexes */
...@@ -752,23 +767,25 @@ BlockSampler_Next(BlockSampler bs) ...@@ -752,23 +767,25 @@ BlockSampler_Next(BlockSampler bs)
* the number of different blocks represented by the sample tends to be * the number of different blocks represented by the sample tends to be
* too small. We can live with that for now. Improvements are welcome. * too small. We can live with that for now. Improvements are welcome.
* *
* We also estimate the total number of rows in the table, and return that * We also estimate the total numbers of live and dead rows in the table,
* into *totalrows. An important property of this sampling method is that * and return them into *totalrows and *totaldeadrows, respectively.
* because we do look at a statistically unbiased set of blocks, we should *
* get an unbiased estimate of the average number of live rows per block. * An important property of this sampling method is that because we do
* The previous sampling method put too much credence in the row density near * look at a statistically unbiased set of blocks, we should get
* the start of the table. * unbiased estimates of the average numbers of live and dead rows per
* block. The previous sampling method put too much credence in the row
* density near the start of the table.
* *
* The returned list of tuples is in order by physical position in the table. * The returned list of tuples is in order by physical position in the table.
* (We will rely on this later to derive correlation estimates.) * (We will rely on this later to derive correlation estimates.)
*/ */
static int static int
acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows, acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
double *totalrows) double *totalrows, double *totaldeadrows)
{ {
int numrows = 0; /* # rows collected */ int numrows = 0; /* # rows collected */
double liverows = 0; /* # rows seen */ double liverows = 0; /* # rows seen */
double deadrows = 0; double deadrows = 0; /* # dead rows seen */
double rowstoskip = -1; /* -1 means not set yet */ double rowstoskip = -1; /* -1 means not set yet */
BlockNumber totalblocks; BlockNumber totalblocks;
BlockSamplerData bs; BlockSamplerData bs;
...@@ -864,11 +881,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows, ...@@ -864,11 +881,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
} }
else else
{ {
/* /* Count dead rows, but not empty slots */
* Count dead rows, but not empty slots. This information
* is currently not used, but it seems likely we'll want
* it someday.
*/
if (targtuple.t_data != NULL) if (targtuple.t_data != NULL)
deadrows += 1; deadrows += 1;
} }
...@@ -890,12 +903,18 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows, ...@@ -890,12 +903,18 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
qsort((void *) rows, numrows, sizeof(HeapTuple), compare_rows); qsort((void *) rows, numrows, sizeof(HeapTuple), compare_rows);
/* /*
* Estimate total number of live rows in relation. * Estimate total numbers of rows in relation.
*/ */
if (bs.m > 0) if (bs.m > 0)
{
*totalrows = floor((liverows * totalblocks) / bs.m + 0.5); *totalrows = floor((liverows * totalblocks) / bs.m + 0.5);
*totaldeadrows = floor((deadrows * totalblocks) / bs.m + 0.5);
}
else else
{
*totalrows = 0.0; *totalrows = 0.0;
*totaldeadrows = 0.0;
}
/* /*
* Emit some interesting relation info * Emit some interesting relation info
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.310 2005/06/14 22:15:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.311 2005/07/14 05:13:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -166,7 +166,8 @@ static TransactionId FreezeLimit; ...@@ -166,7 +166,8 @@ static TransactionId FreezeLimit;
/* non-export function prototypes */ /* non-export function prototypes */
static List *get_rel_oids(const RangeVar *vacrel, const char *stmttype); static List *get_rel_oids(List *relids, const RangeVar *vacrel,
const char *stmttype);
static void vac_update_dbstats(Oid dbid, static void vac_update_dbstats(Oid dbid,
TransactionId vacuumXID, TransactionId vacuumXID,
TransactionId frozenXID); TransactionId frozenXID);
...@@ -221,9 +222,18 @@ static bool enough_space(VacPage vacpage, Size len); ...@@ -221,9 +222,18 @@ static bool enough_space(VacPage vacpage, Size len);
/* /*
* Primary entry point for VACUUM and ANALYZE commands. * Primary entry point for VACUUM and ANALYZE commands.
*
* relids is normally NIL; if it is not, then it provides the list of
* relation OIDs to be processed, and vacstmt->relation is ignored.
* (The non-NIL case is currently only used by autovacuum.)
*
* It is the caller's responsibility that both vacstmt and relids
* (if given) be allocated in a memory context that won't disappear
* at transaction commit. In fact this context must be QueryContext
* to avoid complaints from PreventTransactionChain.
*/ */
void void
vacuum(VacuumStmt *vacstmt) vacuum(VacuumStmt *vacstmt, List *relids)
{ {
const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE"; const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE";
TransactionId initialOldestXmin = InvalidTransactionId; TransactionId initialOldestXmin = InvalidTransactionId;
...@@ -302,11 +312,14 @@ vacuum(VacuumStmt *vacstmt) ...@@ -302,11 +312,14 @@ vacuum(VacuumStmt *vacstmt)
ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE); ALLOCSET_DEFAULT_MAXSIZE);
/* Assume we are processing everything unless one table is mentioned */ /* Remember whether we are processing everything in the DB */
all_rels = (vacstmt->relation == NULL); all_rels = (relids == NIL && vacstmt->relation == NULL);
/* Build list of relations to process (note this lives in vac_context) */ /*
relations = get_rel_oids(vacstmt->relation, stmttype); * Build list of relations to process, unless caller gave us one.
* (If we build one, we put it in vac_context for safekeeping.)
*/
relations = get_rel_oids(relids, vacstmt->relation, stmttype);
if (vacstmt->vacuum && all_rels) if (vacstmt->vacuum && all_rels)
{ {
...@@ -512,11 +525,15 @@ vacuum(VacuumStmt *vacstmt) ...@@ -512,11 +525,15 @@ vacuum(VacuumStmt *vacstmt)
* per-relation transactions. * per-relation transactions.
*/ */
static List * static List *
get_rel_oids(const RangeVar *vacrel, const char *stmttype) get_rel_oids(List *relids, const RangeVar *vacrel, const char *stmttype)
{ {
List *oid_list = NIL; List *oid_list = NIL;
MemoryContext oldcontext; MemoryContext oldcontext;
/* List supplied by VACUUM's caller? */
if (relids)
return relids;
if (vacrel) if (vacrel)
{ {
/* Process a specific relation */ /* Process a specific relation */
...@@ -1146,6 +1163,10 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) ...@@ -1146,6 +1163,10 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
/* update statistics in pg_class */ /* update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages, vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages,
vacrelstats->rel_tuples, vacrelstats->hasindex); vacrelstats->rel_tuples, vacrelstats->hasindex);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), vacstmt->analyze,
vacrelstats->rel_tuples);
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.54 2005/05/19 21:35:46 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.55 2005/07/14 05:13:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "access/xlog.h" #include "access/xlog.h"
#include "commands/vacuum.h" #include "commands/vacuum.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "pgstat.h"
#include "storage/freespace.h" #include "storage/freespace.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
...@@ -179,6 +180,10 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) ...@@ -179,6 +180,10 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
vacrelstats->rel_pages, vacrelstats->rel_pages,
vacrelstats->rel_tuples, vacrelstats->rel_tuples,
hasindex); hasindex);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), vacstmt->analyze,
vacrelstats->rel_tuples);
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for src/backend/postmaster # Makefile for src/backend/postmaster
# #
# IDENTIFICATION # IDENTIFICATION
# $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.20 2005/03/10 07:14:03 neilc Exp $ # $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.21 2005/07/14 05:13:40 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -12,7 +12,8 @@ subdir = src/backend/postmaster ...@@ -12,7 +12,8 @@ subdir = src/backend/postmaster
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
OBJS = bgwriter.o fork_process.o pgarch.o pgstat.o postmaster.o syslogger.o OBJS = bgwriter.o autovacuum.o pgarch.o pgstat.o postmaster.o syslogger.o \
fork_process.o
all: SUBSYS.o all: SUBSYS.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.458 2005/07/04 04:51:47 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.459 2005/07/14 05:13:40 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/nodes.h" #include "nodes/nodes.h"
#include "pgstat.h" #include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/fork_process.h" #include "postmaster/fork_process.h"
#include "postmaster/pgarch.h" #include "postmaster/pgarch.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
...@@ -207,6 +208,7 @@ char *preload_libraries_string = NULL; ...@@ -207,6 +208,7 @@ char *preload_libraries_string = NULL;
/* PIDs of special child processes; 0 when not running */ /* PIDs of special child processes; 0 when not running */
static pid_t StartupPID = 0, static pid_t StartupPID = 0,
BgWriterPID = 0, BgWriterPID = 0,
AutoVacPID = 0,
PgArchPID = 0, PgArchPID = 0,
PgStatPID = 0, PgStatPID = 0,
SysLoggerPID = 0; SysLoggerPID = 0;
...@@ -872,8 +874,8 @@ PostmasterMain(int argc, char *argv[]) ...@@ -872,8 +874,8 @@ PostmasterMain(int argc, char *argv[])
* *
* CAUTION: when changing this list, check for side-effects on the signal * CAUTION: when changing this list, check for side-effects on the signal
* handling setup of child processes. See tcop/postgres.c, * handling setup of child processes. See tcop/postgres.c,
* bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/pgarch.c, * bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/autovacuum.c,
* postmaster/pgstat.c, and postmaster/syslogger.c. * postmaster/pgarch.c, postmaster/pgstat.c, and postmaster/syslogger.c.
*/ */
pqinitmask(); pqinitmask();
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
...@@ -930,6 +932,11 @@ PostmasterMain(int argc, char *argv[]) ...@@ -930,6 +932,11 @@ PostmasterMain(int argc, char *argv[])
*/ */
PgStartTime = GetCurrentTimestamp(); PgStartTime = GetCurrentTimestamp();
/*
* Initialize the autovacuum daemon
*/
autovac_init();
status = ServerLoop(); status = ServerLoop();
/* /*
...@@ -1251,6 +1258,15 @@ ServerLoop(void) ...@@ -1251,6 +1258,15 @@ ServerLoop(void)
kill(BgWriterPID, SIGUSR2); kill(BgWriterPID, SIGUSR2);
} }
/*
* Start a new autovacuum process, if there isn't one running already.
* (It'll die relatively quickly.) We check that it's not started
* too frequently in autovac_start.
*/
if (AutoVacuumingActive() && AutoVacPID == 0 &&
StartupPID == 0 && !FatalError && Shutdown == NoShutdown)
AutoVacPID = autovac_start();
/* If we have lost the archiver, try to start a new one */ /* If we have lost the archiver, try to start a new one */
if (XLogArchivingActive() && PgArchPID == 0 && if (XLogArchivingActive() && PgArchPID == 0 &&
StartupPID == 0 && !FatalError && Shutdown == NoShutdown) StartupPID == 0 && !FatalError && Shutdown == NoShutdown)
...@@ -1818,6 +1834,8 @@ SIGHUP_handler(SIGNAL_ARGS) ...@@ -1818,6 +1834,8 @@ SIGHUP_handler(SIGNAL_ARGS)
SignalChildren(SIGHUP); SignalChildren(SIGHUP);
if (BgWriterPID != 0) if (BgWriterPID != 0)
kill(BgWriterPID, SIGHUP); kill(BgWriterPID, SIGHUP);
if (AutoVacPID != 0)
kill(AutoVacPID, SIGHUP);
if (PgArchPID != 0) if (PgArchPID != 0)
kill(PgArchPID, SIGHUP); kill(PgArchPID, SIGHUP);
if (SysLoggerPID != 0) if (SysLoggerPID != 0)
...@@ -1869,6 +1887,16 @@ pmdie(SIGNAL_ARGS) ...@@ -1869,6 +1887,16 @@ pmdie(SIGNAL_ARGS)
ereport(LOG, ereport(LOG,
(errmsg("received smart shutdown request"))); (errmsg("received smart shutdown request")));
/*
* We won't wait out an autovacuum iteration ...
*/
if (AutoVacPID != 0)
{
/* Use statement cancel to shut it down */
kill(AutoVacPID, SIGINT);
break; /* let reaper() handle this */
}
if (DLGetHead(BackendList)) if (DLGetHead(BackendList))
break; /* let reaper() handle this */ break; /* let reaper() handle this */
...@@ -1905,13 +1933,15 @@ pmdie(SIGNAL_ARGS) ...@@ -1905,13 +1933,15 @@ pmdie(SIGNAL_ARGS)
ereport(LOG, ereport(LOG,
(errmsg("received fast shutdown request"))); (errmsg("received fast shutdown request")));
if (DLGetHead(BackendList)) if (DLGetHead(BackendList) || AutoVacPID != 0)
{ {
if (!FatalError) if (!FatalError)
{ {
ereport(LOG, ereport(LOG,
(errmsg("aborting any active transactions"))); (errmsg("aborting any active transactions")));
SignalChildren(SIGTERM); SignalChildren(SIGTERM);
if (AutoVacPID != 0)
kill(AutoVacPID, SIGTERM);
/* reaper() does the rest */ /* reaper() does the rest */
} }
break; break;
...@@ -1953,6 +1983,8 @@ pmdie(SIGNAL_ARGS) ...@@ -1953,6 +1983,8 @@ pmdie(SIGNAL_ARGS)
kill(StartupPID, SIGQUIT); kill(StartupPID, SIGQUIT);
if (BgWriterPID != 0) if (BgWriterPID != 0)
kill(BgWriterPID, SIGQUIT); kill(BgWriterPID, SIGQUIT);
if (AutoVacPID != 0)
kill(AutoVacPID, SIGQUIT);
if (PgArchPID != 0) if (PgArchPID != 0)
kill(PgArchPID, SIGQUIT); kill(PgArchPID, SIGQUIT);
if (PgStatPID != 0) if (PgStatPID != 0)
...@@ -2051,7 +2083,7 @@ reaper(SIGNAL_ARGS) ...@@ -2051,7 +2083,7 @@ reaper(SIGNAL_ARGS)
/* /*
* Go to shutdown mode if a shutdown request was pending. * Go to shutdown mode if a shutdown request was pending.
* Otherwise, try to start the archiver and stats collector * Otherwise, try to start the archiver and stats collector
* too. * too. (We could, but don't, try to start autovacuum here.)
*/ */
if (Shutdown > NoShutdown && BgWriterPID != 0) if (Shutdown > NoShutdown && BgWriterPID != 0)
kill(BgWriterPID, SIGUSR2); kill(BgWriterPID, SIGUSR2);
...@@ -2072,8 +2104,8 @@ reaper(SIGNAL_ARGS) ...@@ -2072,8 +2104,8 @@ reaper(SIGNAL_ARGS)
if (BgWriterPID != 0 && pid == BgWriterPID) if (BgWriterPID != 0 && pid == BgWriterPID)
{ {
BgWriterPID = 0; BgWriterPID = 0;
if (exitstatus == 0 && Shutdown > NoShutdown && if (exitstatus == 0 && Shutdown > NoShutdown && !FatalError &&
!FatalError && !DLGetHead(BackendList)) !DLGetHead(BackendList) && AutoVacPID == 0)
{ {
/* /*
* Normal postmaster exit is here: we've seen normal exit * Normal postmaster exit is here: we've seen normal exit
...@@ -2098,6 +2130,23 @@ reaper(SIGNAL_ARGS) ...@@ -2098,6 +2130,23 @@ reaper(SIGNAL_ARGS)
continue; continue;
} }
/*
* Was it the autovacuum process? Normal exit can be ignored;
* we'll start a new one at the next iteration of the postmaster's
* main loop, if necessary.
*
* An unexpected exit must crash the system.
*/
if (AutoVacPID != 0 && pid == AutoVacPID)
{
AutoVacPID = 0;
autovac_stopped();
if (exitstatus != 0)
HandleChildCrash(pid, exitstatus,
_("autovacuum process"));
continue;
}
/* /*
* Was it the archiver? If so, just try to start a new one; no * Was it the archiver? If so, just try to start a new one; no
* need to force reset of the rest of the system. (If fail, we'll * need to force reset of the rest of the system. (If fail, we'll
...@@ -2156,7 +2205,8 @@ reaper(SIGNAL_ARGS) ...@@ -2156,7 +2205,8 @@ reaper(SIGNAL_ARGS)
* StartupDataBase. (We can ignore the archiver and stats * StartupDataBase. (We can ignore the archiver and stats
* processes here since they are not connected to shmem.) * processes here since they are not connected to shmem.)
*/ */
if (DLGetHead(BackendList) || StartupPID != 0 || BgWriterPID != 0) if (DLGetHead(BackendList) || StartupPID != 0 || BgWriterPID != 0 ||
AutoVacPID != 0)
goto reaper_done; goto reaper_done;
ereport(LOG, ereport(LOG,
(errmsg("all server processes terminated; reinitializing"))); (errmsg("all server processes terminated; reinitializing")));
...@@ -2171,7 +2221,7 @@ reaper(SIGNAL_ARGS) ...@@ -2171,7 +2221,7 @@ reaper(SIGNAL_ARGS)
if (Shutdown > NoShutdown) if (Shutdown > NoShutdown)
{ {
if (DLGetHead(BackendList) || StartupPID != 0) if (DLGetHead(BackendList) || StartupPID != 0 || AutoVacPID != 0)
goto reaper_done; goto reaper_done;
/* Start the bgwriter if not running */ /* Start the bgwriter if not running */
if (BgWriterPID == 0) if (BgWriterPID == 0)
...@@ -2239,7 +2289,7 @@ CleanupBackend(int pid, ...@@ -2239,7 +2289,7 @@ CleanupBackend(int pid,
} }
/* /*
* HandleChildCrash -- cleanup after failed backend or bgwriter. * HandleChildCrash -- cleanup after failed backend, bgwriter, or autovacuum.
* *
* The objectives here are to clean up our local state about the child * The objectives here are to clean up our local state about the child
* process, and to signal all other remaining children to quickdie. * process, and to signal all other remaining children to quickdie.
...@@ -2317,6 +2367,18 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) ...@@ -2317,6 +2367,18 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
kill(BgWriterPID, (SendStop ? SIGSTOP : SIGQUIT)); kill(BgWriterPID, (SendStop ? SIGSTOP : SIGQUIT));
} }
/* Take care of the autovacuum daemon 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));
}
/* Force a power-cycle of the pgarch process too */ /* Force a power-cycle of the pgarch process too */
/* (Shouldn't be necessary, but just for luck) */ /* (Shouldn't be necessary, but just for luck) */
if (PgArchPID != 0 && !FatalError) if (PgArchPID != 0 && !FatalError)
...@@ -3154,6 +3216,7 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3154,6 +3216,7 @@ SubPostmasterMain(int argc, char *argv[])
* can attach at the same address the postmaster used. * can attach at the same address the postmaster used.
*/ */
if (strcmp(argv[1], "-forkbackend") == 0 || if (strcmp(argv[1], "-forkbackend") == 0 ||
strcmp(argv[1], "-forkautovac") == 0 ||
strcmp(argv[1], "-forkboot") == 0) strcmp(argv[1], "-forkboot") == 0)
PGSharedMemoryReAttach(); PGSharedMemoryReAttach();
...@@ -3205,6 +3268,17 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3205,6 +3268,17 @@ SubPostmasterMain(int argc, char *argv[])
BootstrapMain(argc - 2, argv + 2); BootstrapMain(argc - 2, argv + 2);
proc_exit(0); proc_exit(0);
} }
if (strcmp(argv[1], "-forkautovac") == 0)
{
/* Close the postmaster's sockets */
ClosePostmasterPorts(false);
/* Attached process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
AutoVacMain(argc - 2, argv + 2);
proc_exit(0);
}
if (strcmp(argv[1], "-forkarch") == 0) if (strcmp(argv[1], "-forkarch") == 0)
{ {
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
...@@ -3300,7 +3374,11 @@ sigusr1_handler(SIGNAL_ARGS) ...@@ -3300,7 +3374,11 @@ sigusr1_handler(SIGNAL_ARGS)
* use of this. * use of this.
*/ */
if (Shutdown <= SmartShutdown) if (Shutdown <= SmartShutdown)
{
SignalChildren(SIGUSR1); SignalChildren(SIGUSR1);
if (AutoVacPID != 0)
kill(AutoVacPID, SIGUSR1);
}
} }
if (PgArchPID != 0 && Shutdown == NoShutdown) if (PgArchPID != 0 && Shutdown == NoShutdown)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.453 2005/07/10 21:13:58 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.454 2005/07/14 05:13:41 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2111,7 +2111,7 @@ authdie(SIGNAL_ARGS) ...@@ -2111,7 +2111,7 @@ authdie(SIGNAL_ARGS)
* Query-cancel signal from postmaster: abort current transaction * Query-cancel signal from postmaster: abort current transaction
* at soonest convenient time * at soonest convenient time
*/ */
static void void
StatementCancelHandler(SIGNAL_ARGS) StatementCancelHandler(SIGNAL_ARGS)
{ {
int save_errno = errno; int save_errno = errno;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.240 2005/06/30 00:00:51 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.241 2005/07/14 05:13:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -843,7 +843,7 @@ ProcessUtility(Node *parsetree, ...@@ -843,7 +843,7 @@ ProcessUtility(Node *parsetree,
break; break;
case T_VacuumStmt: case T_VacuumStmt:
vacuum((VacuumStmt *) parsetree); vacuum((VacuumStmt *) parsetree, NIL);
break; break;
case T_ExplainStmt: case T_ExplainStmt:
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.145 2005/07/04 04:51:50 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.146 2005/07/14 05:13:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "catalog/pg_authid.h" #include "catalog/pg_authid.h"
#include "libpq/libpq-be.h" #include "libpq/libpq-be.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/autovacuum.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/pg_shmem.h" #include "storage/pg_shmem.h"
...@@ -394,7 +395,7 @@ void ...@@ -394,7 +395,7 @@ void
InitializeSessionUserIdStandalone(void) InitializeSessionUserIdStandalone(void)
{ {
/* This function should only be called in a single-user backend. */ /* This function should only be called in a single-user backend. */
AssertState(!IsUnderPostmaster); AssertState(!IsUnderPostmaster || IsAutoVacuumProcess());
/* call only once */ /* call only once */
AssertState(!OidIsValid(AuthenticatedUserId)); AssertState(!OidIsValid(AuthenticatedUserId));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.152 2005/07/04 04:51:50 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.153 2005/07/14 05:13:41 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "libpq/hba.h" #include "libpq/hba.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "storage/backendid.h" #include "storage/backendid.h"
#include "storage/fd.h" #include "storage/fd.h"
...@@ -268,7 +269,8 @@ BaseInit(void) ...@@ -268,7 +269,8 @@ BaseInit(void)
* InitPostgres * InitPostgres
* Initialize POSTGRES. * Initialize POSTGRES.
* *
* In bootstrap mode neither of the parameters are used. * In bootstrap mode neither of the parameters are used. In autovacuum
* mode, the username parameter is not used.
* *
* The return value indicates whether the userID is a superuser. (That * The return value indicates whether the userID is a superuser. (That
* can only be tested inside a transaction, so we want to do it during * can only be tested inside a transaction, so we want to do it during
...@@ -282,6 +284,7 @@ bool ...@@ -282,6 +284,7 @@ bool
InitPostgres(const char *dbname, const char *username) InitPostgres(const char *dbname, const char *username)
{ {
bool bootstrap = IsBootstrapProcessingMode(); bool bootstrap = IsBootstrapProcessingMode();
bool autovacuum = IsAutoVacuumProcess();
bool am_superuser; bool am_superuser;
/* /*
...@@ -402,10 +405,11 @@ InitPostgres(const char *dbname, const char *username) ...@@ -402,10 +405,11 @@ InitPostgres(const char *dbname, const char *username)
RelationCacheInitializePhase2(); RelationCacheInitializePhase2();
/* /*
* Figure out our postgres user id. In standalone mode we use a fixed * Figure out our postgres user id. In standalone mode and in the
* id, otherwise we figure it out from the authenticated user name. * autovacuum process, we use a fixed id, otherwise we figure it out from
* the authenticated user name.
*/ */
if (bootstrap) if (bootstrap || autovacuum)
InitializeSessionUserIdStandalone(); InitializeSessionUserIdStandalone();
else if (!IsUnderPostmaster) else if (!IsUnderPostmaster)
{ {
...@@ -441,7 +445,7 @@ InitPostgres(const char *dbname, const char *username) ...@@ -441,7 +445,7 @@ InitPostgres(const char *dbname, const char *username)
/* /*
* Check if user is a superuser. * Check if user is a superuser.
*/ */
if (bootstrap) if (bootstrap || autovacuum)
am_superuser = true; am_superuser = true;
else else
am_superuser = superuser(); am_superuser = superuser();
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.273 2005/07/05 23:18:10 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.274 2005/07/14 05:13:42 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "postmaster/autovacuum.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "postmaster/syslogger.h" #include "postmaster/syslogger.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
...@@ -286,6 +287,8 @@ const char *const config_group_names[] = ...@@ -286,6 +287,8 @@ const char *const config_group_names[] =
gettext_noop("Statistics / Monitoring"), gettext_noop("Statistics / Monitoring"),
/* STATS_COLLECTOR */ /* STATS_COLLECTOR */
gettext_noop("Statistics / Query and Index Statistics Collector"), gettext_noop("Statistics / Query and Index Statistics Collector"),
/* AUTOVACUUM */
gettext_noop("Auto Vacuum"),
/* CLIENT_CONN */ /* CLIENT_CONN */
gettext_noop("Client Connection Defaults"), gettext_noop("Client Connection Defaults"),
/* CLIENT_CONN_STATEMENT */ /* CLIENT_CONN_STATEMENT */
...@@ -678,6 +681,15 @@ static struct config_bool ConfigureNamesBool[] = ...@@ -678,6 +681,15 @@ static struct config_bool ConfigureNamesBool[] =
false, NULL, NULL 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, {"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Generates debugging output for LISTEN and NOTIFY."), gettext_noop("Generates debugging output for LISTEN and NOTIFY."),
...@@ -1389,6 +1401,31 @@ static struct config_int ConfigureNamesInt[] = ...@@ -1389,6 +1401,31 @@ static struct config_int ConfigureNamesInt[] =
BLCKSZ, BLCKSZ, BLCKSZ, NULL, NULL BLCKSZ, BLCKSZ, BLCKSZ, NULL, NULL
}, },
{
{"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Time to sleep between autovacuum runs, in seconds."),
NULL
},
&autovacuum_naptime,
60, 0, INT_MAX, NULL, NULL
},
{
{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
NULL
},
&autovacuum_vac_thresh,
1000, 0, INT_MAX, NULL, NULL
},
{
{"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Minimum number of tuple inserts, updates or deletes prior to analyze."),
NULL
},
&autovacuum_anl_thresh,
500, 0, INT_MAX, NULL, NULL
},
/* End-of-list marker */ /* End-of-list marker */
{ {
{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL
...@@ -1487,6 +1524,23 @@ static struct config_real ConfigureNamesReal[] = ...@@ -1487,6 +1524,23 @@ static struct config_real ConfigureNamesReal[] =
0.5, 0.0, 1.0, assign_random_seed, show_random_seed 0.5, 0.0, 1.0, assign_random_seed, show_random_seed
}, },
{
{"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
NULL
},
&autovacuum_vac_scale,
0.4, 0.0, 100.0, NULL, NULL
},
{
{"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples."),
NULL
},
&autovacuum_anl_scale,
0.2, 0.0, 100.0, NULL, NULL
},
/* End-of-list marker */ /* End-of-list marker */
{ {
{NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL {NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL
......
...@@ -284,6 +284,18 @@ ...@@ -284,6 +284,18 @@
#stats_reset_on_server_start = on #stats_reset_on_server_start = on
#---------------------------------------------------------------------------
# AUTOVACUUM PARAMETERS
#---------------------------------------------------------------------------
#autovacuum = false # enable autovacuum subprocess?
#autovacuum_naptime = 60 # time between autovacuum runs, in seconds
#autovacuum_vacuum_threshold = 1000 # min # of tuple updates before vacuum
#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
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS # CLIENT CONNECTION DEFAULTS
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.288 2005/07/10 21:13:59 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.289 2005/07/14 05:13:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200507102 #define CATALOG_VERSION_NO 200507131
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.89 2005/07/07 20:39:59 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.90 2005/07/14 05:13:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -210,6 +210,8 @@ DECLARE_UNIQUE_INDEX(pg_type_oid_index,2703, on pg_type using btree(oid oid_ops) ...@@ -210,6 +210,8 @@ DECLARE_UNIQUE_INDEX(pg_type_oid_index,2703, on pg_type using btree(oid oid_ops)
DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index,2704, on pg_type using btree(typname name_ops, typnamespace oid_ops)); DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index,2704, on pg_type using btree(typname name_ops, typnamespace oid_ops));
#define TypeNameNspIndexId 2704 #define TypeNameNspIndexId 2704
DECLARE_UNIQUE_INDEX(pg_autovacuum_vacrelid_index,1250, on pg_autovacuum using btree(vacrelid oid_ops));
#define AutovacuumRelidIndexId 1250
/* last step of initialization script: build the indexes declared above */ /* last step of initialization script: build the indexes declared above */
BUILD_INDICES BUILD_INDICES
......
/*-------------------------------------------------------------------------
*
* pg_autovacuum.h
* definition of the system "autovacuum" relation (pg_autovacuum)
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_autovacuum.h,v 1.1 2005/07/14 05:13:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#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
* ----------------
*/
#define AutovacuumRelationId 1248
CATALOG(pg_autovacuum,1248) BKI_WITHOUT_OIDS
{
Oid vacrelid; /* OID of table */
bool enabled; /* enabled for this table? */
int4 vac_base_thresh; /* base threshold value */
float4 vac_scale_factor; /* reltuples scaling factor */
int4 anl_base_thresh; /* base threshold value */
float4 anl_scale_factor; /* reltuples scaling factor */
} 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 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 */
#endif /* PG_AUTOVACUUM_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.59 2004/12/31 22:03:28 pgsql Exp $ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.60 2005/07/14 05:13:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -125,7 +125,7 @@ extern DLLIMPORT int default_statistics_target; /* DLLIMPORT for PostGIS */ ...@@ -125,7 +125,7 @@ extern DLLIMPORT int default_statistics_target; /* DLLIMPORT for PostGIS */
/* in commands/vacuum.c */ /* in commands/vacuum.c */
extern void vacuum(VacuumStmt *vacstmt); extern void vacuum(VacuumStmt *vacstmt, List *relids);
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel); int *nindexes, Relation **Irel);
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * Copyright (c) 2001-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.32 2005/06/29 22:51:57 tgl Exp $ * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.33 2005/07/14 05:13:43 tgl Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
...@@ -20,14 +20,20 @@ ...@@ -20,14 +20,20 @@
* The types of backend/postmaster -> collector messages * The types of backend/postmaster -> collector messages
* ---------- * ----------
*/ */
#define PGSTAT_MTYPE_DUMMY 0 typedef enum StatMsgType
#define PGSTAT_MTYPE_BESTART 1 {
#define PGSTAT_MTYPE_BETERM 2 PGSTAT_MTYPE_DUMMY,
#define PGSTAT_MTYPE_ACTIVITY 3 PGSTAT_MTYPE_BESTART,
#define PGSTAT_MTYPE_TABSTAT 4 PGSTAT_MTYPE_BETERM,
#define PGSTAT_MTYPE_TABPURGE 5 PGSTAT_MTYPE_ACTIVITY,
#define PGSTAT_MTYPE_DROPDB 6 PGSTAT_MTYPE_TABSTAT,
#define PGSTAT_MTYPE_RESETCOUNTER 7 PGSTAT_MTYPE_TABPURGE,
PGSTAT_MTYPE_DROPDB,
PGSTAT_MTYPE_RESETCOUNTER,
PGSTAT_MTYPE_AUTOVAC_START,
PGSTAT_MTYPE_VACUUM,
PGSTAT_MTYPE_ANALYZE
} StatMsgType;
/* ---------- /* ----------
* The data type used for counters. * The data type used for counters.
...@@ -48,7 +54,7 @@ typedef int64 PgStat_Counter; ...@@ -48,7 +54,7 @@ typedef int64 PgStat_Counter;
*/ */
typedef struct PgStat_MsgHdr typedef struct PgStat_MsgHdr
{ {
int m_type; StatMsgType m_type;
int m_size; int m_size;
int m_backendid; int m_backendid;
int m_procpid; int m_procpid;
...@@ -114,6 +120,47 @@ typedef struct PgStat_MsgBeterm ...@@ -114,6 +120,47 @@ typedef struct PgStat_MsgBeterm
PgStat_MsgHdr m_hdr; PgStat_MsgHdr m_hdr;
} PgStat_MsgBeterm; } PgStat_MsgBeterm;
/* ----------
* PgStat_MsgAutovacStart Sent by the autovacuum daemon to signal
* that a database is going to be processed
* ----------
*/
typedef struct PgStat_MsgAutovacStart
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
TimestampTz m_start_time;
} PgStat_MsgAutovacStart;
/* ----------
* PgStat_MsgVacuum Sent by the backend or autovacuum daemon
* after VACUUM or VACUUM ANALYZE
* ----------
*/
typedef struct PgStat_MsgVacuum
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
Oid m_tableoid;
bool m_analyze;
PgStat_Counter m_tuples;
} PgStat_MsgVacuum;
/* ----------
* PgStat_MsgAnalyze Sent by the backend or autovacuum daemon
* after ANALYZE
* ----------
*/
typedef struct PgStat_MsgAnalyze
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
Oid m_tableoid;
PgStat_Counter m_live_tuples;
PgStat_Counter m_dead_tuples;
} PgStat_MsgAnalyze;
/* ---------- /* ----------
* PgStat_MsgActivity Sent by the backends when they start * PgStat_MsgActivity Sent by the backends when they start
* to parse a query. * to parse a query.
...@@ -200,14 +247,22 @@ typedef union PgStat_Msg ...@@ -200,14 +247,22 @@ typedef union PgStat_Msg
PgStat_MsgTabpurge msg_tabpurge; PgStat_MsgTabpurge msg_tabpurge;
PgStat_MsgDropdb msg_dropdb; PgStat_MsgDropdb msg_dropdb;
PgStat_MsgResetcounter msg_resetcounter; PgStat_MsgResetcounter msg_resetcounter;
PgStat_MsgAutovacStart msg_autovacuum;
PgStat_MsgVacuum msg_vacuum;
PgStat_MsgAnalyze msg_analyze;
} PgStat_Msg; } PgStat_Msg;
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* Statistic collector data structures follow * Statistic collector data structures follow
*
* PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
* data structures change.
* ------------------------------------------------------------ * ------------------------------------------------------------
*/ */
#define PGSTAT_FILE_FORMAT_ID 0x01A5BC93
/* ---------- /* ----------
* PgStat_StatDBEntry The collectors data per database * PgStat_StatDBEntry The collectors data per database
* ---------- * ----------
...@@ -222,6 +277,7 @@ typedef struct PgStat_StatDBEntry ...@@ -222,6 +277,7 @@ typedef struct PgStat_StatDBEntry
PgStat_Counter n_blocks_fetched; PgStat_Counter n_blocks_fetched;
PgStat_Counter n_blocks_hit; PgStat_Counter n_blocks_hit;
int destroy; int destroy;
TimestampTz last_autovac_time;
} PgStat_StatDBEntry; } PgStat_StatDBEntry;
...@@ -282,6 +338,10 @@ typedef struct PgStat_StatTabEntry ...@@ -282,6 +338,10 @@ typedef struct PgStat_StatTabEntry
PgStat_Counter tuples_updated; PgStat_Counter tuples_updated;
PgStat_Counter tuples_deleted; PgStat_Counter tuples_deleted;
PgStat_Counter n_live_tuples;
PgStat_Counter n_dead_tuples;
PgStat_Counter last_anl_tuples;
PgStat_Counter blocks_fetched; PgStat_Counter blocks_fetched;
PgStat_Counter blocks_hit; PgStat_Counter blocks_hit;
...@@ -323,6 +383,11 @@ extern void pgstat_bestart(void); ...@@ -323,6 +383,11 @@ extern void pgstat_bestart(void);
extern void pgstat_ping(void); extern void pgstat_ping(void);
extern void pgstat_report_activity(const char *what); extern void pgstat_report_activity(const char *what);
extern void pgstat_report_tabstat(void); extern void pgstat_report_tabstat(void);
extern void pgstat_report_autovac(void);
extern void pgstat_report_vacuum(Oid tableoid, bool analyze,
PgStat_Counter tuples);
extern void pgstat_report_analyze(Oid tableoid, PgStat_Counter livetuples,
PgStat_Counter deadtuples);
extern int pgstat_vacuum_tabstat(void); extern int pgstat_vacuum_tabstat(void);
extern void pgstat_reset_counters(void); extern void pgstat_reset_counters(void);
......
/*-------------------------------------------------------------------------
*
* autovacuum.h
* header file for integrated autovacuum daemon
*
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/postmaster/autovacuum.h,v 1.1 2005/07/14 05:13:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef AUTOVACUUM_H
#define AUTOVACUUM_H
/* GUC variables */
extern bool autovacuum_start_daemon;
extern int autovacuum_naptime;
extern int autovacuum_vac_thresh;
extern double autovacuum_vac_scale;
extern int autovacuum_anl_thresh;
extern double autovacuum_anl_scale;
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
extern bool IsAutoVacuumProcess(void);
/* Functions to start autovacuum process, called from postmaster */
extern void autovac_init(void);
extern int autovac_start(void);
extern void autovac_stopped(void);
#ifdef EXEC_BACKEND
extern void AutoVacMain(int argc, char *argv[]);
#endif
#endif /* AUTOVACUUM_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.75 2005/06/03 23:05:30 tgl Exp $ * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.76 2005/07/14 05:13:44 tgl Exp $
* *
* OLD COMMENTS * OLD COMMENTS
* This file was created so that other c files could get the two * This file was created so that other c files could get the two
...@@ -58,6 +58,7 @@ extern bool assign_max_stack_depth(int newval, bool doit, GucSource source); ...@@ -58,6 +58,7 @@ extern bool assign_max_stack_depth(int newval, bool doit, GucSource source);
extern void die(SIGNAL_ARGS); extern void die(SIGNAL_ARGS);
extern void quickdie(SIGNAL_ARGS); extern void quickdie(SIGNAL_ARGS);
extern void authdie(SIGNAL_ARGS); extern void authdie(SIGNAL_ARGS);
extern void StatementCancelHandler(SIGNAL_ARGS);
extern void prepare_for_client_read(void); extern void prepare_for_client_read(void);
extern void client_read_ended(void); extern void client_read_ended(void);
extern int PostgresMain(int argc, char *argv[], const char *username); extern int PostgresMain(int argc, char *argv[], const char *username);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.19 2004/12/31 22:03:46 pgsql Exp $ * $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.20 2005/07/14 05:13:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -62,6 +62,7 @@ enum config_group ...@@ -62,6 +62,7 @@ enum config_group
STATS, STATS,
STATS_MONITORING, STATS_MONITORING,
STATS_COLLECTOR, STATS_COLLECTOR,
AUTOVACUUM,
CLIENT_CONN, CLIENT_CONN,
CLIENT_CONN_STATEMENT, CLIENT_CONN_STATEMENT,
CLIENT_CONN_LOCALE, CLIENT_CONN_LOCALE,
......
...@@ -40,6 +40,7 @@ SELECT relname, relhasindex ...@@ -40,6 +40,7 @@ SELECT relname, relhasindex
pg_attribute | t pg_attribute | t
pg_auth_members | t pg_auth_members | t
pg_authid | t pg_authid | t
pg_autovacuum | t
pg_cast | t pg_cast | t
pg_class | t pg_class | t
pg_constraint | t pg_constraint | t
...@@ -66,7 +67,7 @@ SELECT relname, relhasindex ...@@ -66,7 +67,7 @@ SELECT relname, relhasindex
shighway | t shighway | t
tenk1 | t tenk1 | t
tenk2 | t tenk2 | t
(56 rows) (57 rows)
-- --
-- another sanity check: every system catalog that has OIDs should have -- another sanity check: every system catalog that has OIDs should have
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment