mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
Update autovacuum to use reloptions instead of a system catalog, for
per-table overrides of parameters. This removes a whole class of problems related to misusing the catalog, and perhaps more importantly, gives us pg_dump support for the parameters. Based on a patch by Euler Taveira de Oliveira, heavily reworked by me.
This commit is contained in:
parent
57b10ebcd4
commit
834a6da4f7
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.196 2009/02/07 19:27:25 momjian Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.197 2009/02/09 20:57:59 alvherre Exp $ -->
|
||||
<!--
|
||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||
-->
|
||||
@ -88,11 +88,6 @@
|
||||
<entry>authorization identifier membership relationships</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-autovacuum"><structname>pg_autovacuum</structname></link></entry>
|
||||
<entry>per-relation autovacuum configuration parameters</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry>
|
||||
<entry>casts (data type conversions)</entry>
|
||||
@ -1256,178 +1251,6 @@
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="catalog-pg-autovacuum">
|
||||
<title><structname>pg_autovacuum</structname></title>
|
||||
|
||||
<indexterm zone="catalog-pg-autovacuum">
|
||||
<primary>pg_autovacuum</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm zone="catalog-pg-autovacuum">
|
||||
<primary>autovacuum</primary>
|
||||
<secondary>table-specific configuration</secondary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The catalog <structname>pg_autovacuum</structname> stores optional
|
||||
per-relation configuration parameters for the autovacuum daemon.
|
||||
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. For more information
|
||||
about the autovacuum daemon, see <xref linkend="autovacuum">.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
It is likely that <structname>pg_autovacuum</structname> will disappear
|
||||
in a future release, with the information instead being kept in
|
||||
<structname>pg_class</>.<structfield>reloptions</> entries.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<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 will not be autovacuumed, except
|
||||
to prevent transaction ID wraparound</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 <structfield>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 <structfield>reltuples</> to add to
|
||||
<structfield>anl_base_thresh</></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>vac_cost_delay</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Custom <varname>vacuum_cost_delay</> parameter</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>vac_cost_limit</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Custom <varname>vacuum_cost_limit</> parameter</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>freeze_min_age</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Custom <varname>vacuum_freeze_min_age</> parameter</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>freeze_max_age</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Custom <varname>autovacuum_freeze_max_age</> parameter</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>freeze_table_age</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Custom <varname>vacuum_freeze_table_age</> parameter</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>
|
||||
Also, the autovacuum daemon will perform a <command>VACUUM</> operation
|
||||
to prevent transaction ID wraparound if the table's
|
||||
<structname>pg_class</>.<structfield>relfrozenxid</> field attains an age
|
||||
of more than <structfield>freeze_max_age</> transactions, whether the table
|
||||
has been changed or not, even if
|
||||
<structname>pg_autovacuum</>.<structfield>enabled</> is set to
|
||||
<literal>false</> for it. The system will launch autovacuum to perform
|
||||
such <command>VACUUM</>s even if autovacuum is otherwise disabled.
|
||||
See <xref linkend="vacuum-for-wraparound"> for more about wraparound
|
||||
prevention.
|
||||
</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. Observe that the
|
||||
<structfield>vac_cost_delay</> variable inherits its default value from the
|
||||
<xref linkend="guc-autovacuum-vacuum-cost-delay"> configuration parameter,
|
||||
or from <xref linkend="guc-vacuum-cost-delay"> if the former is set to a
|
||||
negative value. The same applies to <structfield>vac_cost_limit</>.
|
||||
Also, autovacuum will ignore attempts to set a per-table
|
||||
<structfield>freeze_max_age</> larger than the system-wide setting (it can
|
||||
only be set smaller), and the <structfield>freeze_min_age</> value will be
|
||||
limited to half the system-wide <xref
|
||||
linkend="guc-autovacuum-freeze-max-age"> setting. Note that while you
|
||||
can set <structfield>freeze_max_age</> very small, or even zero, this
|
||||
is usually unwise since it will force frequent vacuuming.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="catalog-pg-cast">
|
||||
<title><structname>pg_cast</structname></title>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.206 2009/01/16 13:27:23 heikki Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.207 2009/02/09 20:57:59 alvherre Exp $ -->
|
||||
|
||||
<chapter Id="runtime-config">
|
||||
<title>Server Configuration</title>
|
||||
@ -3547,8 +3547,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
The default is 50 tuples.
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -3565,8 +3565,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
The default is 50 tuples.
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -3584,8 +3584,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
The default is 0.2 (20% of table size).
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -3603,8 +3603,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
The default is 0.1 (10% of table size).
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -3624,8 +3624,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
autovacuum is otherwise disabled.
|
||||
The default is 200 million transactions.
|
||||
This parameter can only be set at server start, but the setting
|
||||
can be reduced for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
can be reduced for individual tables by
|
||||
changing storage parameters.
|
||||
For more information see <xref linkend="vacuum-for-wraparound">.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -3645,8 +3645,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
The default value is 20 milliseconds.
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -3667,8 +3667,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
||||
each worker never exceeds the limit on this variable.
|
||||
This parameter can only be set in the <filename>postgresql.conf</>
|
||||
file or on the server command line.
|
||||
This setting can be overridden for individual tables by entries in
|
||||
<structname>pg_autovacuum</>.
|
||||
This setting can be overridden for individual tables by
|
||||
changing storage parameters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.89 2009/01/16 13:27:23 heikki Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.90 2009/02/09 20:57:59 alvherre Exp $ -->
|
||||
|
||||
<chapter id="maintenance">
|
||||
<title>Routine Database Maintenance Tasks</title>
|
||||
@ -573,7 +573,9 @@ HINT: Stop the postmaster and use a standalone backend to VACUUM in "mydb".
|
||||
<para>
|
||||
Tables whose <structfield>relfrozenxid</> value is more than
|
||||
<varname>autovacuum_freeze_max_age</> transactions old are always
|
||||
vacuumed. Otherwise, if the number of tuples obsoleted since the last
|
||||
vacuumed (this also applies to those tables whose freeze max age has
|
||||
been modified via storage parameters; see below). Otherwise, if the
|
||||
number of tuples obsoleted since the last
|
||||
<command>VACUUM</command> exceeds the <quote>vacuum threshold</quote>, the
|
||||
table is vacuumed. The vacuum threshold is defined as:
|
||||
<programlisting>
|
||||
@ -604,65 +606,39 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
|
||||
<para>
|
||||
The default thresholds and scale factors are taken from
|
||||
<filename>postgresql.conf</filename>, but it is possible to override them
|
||||
on a table-by-table basis by making entries in the system catalog
|
||||
<link
|
||||
linkend="catalog-pg-autovacuum"><structname>pg_autovacuum</></link>.
|
||||
If a <structname>pg_autovacuum</structname> row exists for a particular
|
||||
table, the settings it specifies are applied; otherwise the global
|
||||
settings are used. See <xref linkend="runtime-config-autovacuum"> for
|
||||
on a table-by-table basis; see
|
||||
<xref linkend="sql-createtable-storage-parameters"
|
||||
endterm="sql-createtable-storage-parameters-title"> for more information.
|
||||
If a setting
|
||||
has been changed via storage parameters, that value is used; otherwise the
|
||||
global settings are used. See <xref linkend="runtime-config-autovacuum"> for
|
||||
more details on the global settings.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Besides the base threshold values and scale factors, there are five
|
||||
more parameters that can be set for each table in
|
||||
<structname>pg_autovacuum</structname>.
|
||||
The first, <structname>pg_autovacuum</>.<structfield>enabled</>,
|
||||
Besides the base threshold values and scale factors, there are six
|
||||
more autovacuum parameters that can be set for each table via
|
||||
storage parameters.
|
||||
The first parameter, <literal>autovacuum_enabled</>,
|
||||
can be set to <literal>false</literal> to instruct the autovacuum daemon
|
||||
to skip that particular table entirely. In this case
|
||||
autovacuum will only touch the table if it must do so
|
||||
to prevent transaction ID wraparound.
|
||||
The next two parameters, the vacuum cost delay
|
||||
(<structname>pg_autovacuum</structname>.<structfield>vac_cost_delay</structfield>)
|
||||
and the vacuum cost limit
|
||||
(<structname>pg_autovacuum</structname>.<structfield>vac_cost_limit</structfield>),
|
||||
are used to set table-specific values for the
|
||||
<xref linkend="runtime-config-resource-vacuum-cost" endterm="runtime-config-resource-vacuum-cost-title">
|
||||
Another two parameters,
|
||||
<literal>autovacuum_vacuum_cost_delay</literal> and
|
||||
<literal>autovacuum_vacuum_cost_limit</literal>, are used to set
|
||||
table-specific values for the
|
||||
<xref linkend="runtime-config-resource-vacuum-cost"
|
||||
endterm="runtime-config-resource-vacuum-cost-title">
|
||||
feature.
|
||||
The last two parameters,
|
||||
(<structname>pg_autovacuum</structname>.<structfield>freeze_min_age</structfield>)
|
||||
and
|
||||
(<structname>pg_autovacuum</structname>.<structfield>freeze_max_age</structfield>),
|
||||
are used to set table-specific values for
|
||||
<xref linkend="guc-vacuum-freeze-min-age"> and
|
||||
<xref linkend="guc-autovacuum-freeze-max-age"> respectively.
|
||||
<literal>autovacuum_freeze_min_age</literal>,
|
||||
<literal>autovacuum_freeze_max_age</literal> and
|
||||
<literal>autovacuum_freeze_table_age</literal> are used to set
|
||||
values for <xref linkend="guc-vacuum-freeze-min-age">,
|
||||
<xref linkend="guc-autovacuum-freeze-max-age"> and
|
||||
<xref linkend="guc-vacuum-freeze-table-age"> respectively.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If any of the values in <structname>pg_autovacuum</structname>
|
||||
are set to a negative number, or if a row is not present at all in
|
||||
<structname>pg_autovacuum</structname> for any particular table, the
|
||||
corresponding values from <filename>postgresql.conf</filename> are used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There is not currently any support for making
|
||||
<structname>pg_autovacuum</structname> entries, except by doing
|
||||
manual <command>INSERT</>s into the catalog. This feature will be
|
||||
improved in future releases, and it is likely that the catalog
|
||||
definition will change.
|
||||
</para>
|
||||
|
||||
<caution>
|
||||
<para>
|
||||
The contents of the <structname>pg_autovacuum</structname> system
|
||||
catalog are currently not saved in database dumps created by the
|
||||
tools <application>pg_dump</> and <application>pg_dumpall</>. If
|
||||
you want to preserve them across a dump/reload cycle, make sure
|
||||
you dump the catalog manually.
|
||||
</para>
|
||||
</caution>
|
||||
|
||||
<para>
|
||||
When multiple workers are running, the cost limit is
|
||||
<quote>balanced</quote> among all the running workers, so that the
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.102 2008/12/13 19:13:44 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.103 2009/02/09 20:57:59 alvherre Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -286,7 +286,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
<listitem>
|
||||
<para>
|
||||
This form changes one or more storage parameters for the table. See
|
||||
<xref linkend="SQL-CREATETABLE" endterm="sql-createtable-title">
|
||||
<xref linkend="SQL-CREATETABLE-storage-parameters"
|
||||
endterm="sql-createtable-storage-parameters-title">
|
||||
for details on the available parameters. Note that the table contents
|
||||
will not be modified immediately by this command; depending on the
|
||||
parameter you might need to rewrite the table to get the desired effects.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.112 2009/02/02 19:31:38 alvherre Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.113 2009/02/09 20:57:59 alvherre Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -685,19 +685,29 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
||||
<refsect2 id="SQL-CREATETABLE-storage-parameters">
|
||||
<title id="SQL-CREATETABLE-storage-parameters-title">Storage Parameters</title>
|
||||
|
||||
<indexterm zone="sql-createtable-storage-parameters">
|
||||
<primary>storage parameters</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The <literal>WITH</> clause can specify <firstterm>storage parameters</>
|
||||
for tables, and for indexes associated with a <literal>UNIQUE</literal> or
|
||||
<literal>PRIMARY KEY</literal> constraint. Storage parameters for
|
||||
indexes are documented in <xref linkend="SQL-CREATEINDEX"
|
||||
endterm="sql-createindex-title">. The storage parameters currently
|
||||
available for tables are:
|
||||
available for tables are listed below. For each parameter, there is an
|
||||
additional, identically named parameter, prefixed with
|
||||
<literal>toast.</literal> which can be used to control the behavior of the
|
||||
supplementary storage table, if any; see <xref linkend="storage-toast">.
|
||||
Note that the supplementary storage table inherits the
|
||||
<literal>autovacuum</literal> values from its parent table, if there are
|
||||
no <literal>toast.autovacuum_*</literal> settings set.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>FILLFACTOR</></term>
|
||||
<term><literal>fillfactor</>, <literal>toast.fillfactor</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The fillfactor for a table is a percentage between 10 and 100.
|
||||
@ -715,11 +725,118 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>TOAST.FILLFACTOR</literal></term>
|
||||
<term><literal>autovacuum_enabled</>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Same as above, for the supplementary storage table, if any; see
|
||||
<xref linkend="storage-toast">.
|
||||
Enables or disables the autovacuum daemon on a particular table.
|
||||
If true, the autovacuum daemon will initiate a <command>VACUUM</> operation
|
||||
on a particular table when the number of updated or deleted tuples exceeds
|
||||
<literal>autovacuum_vacuum_threshold</> plus
|
||||
<literal>autovacuum_vacuum_scale_factor</> 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
|
||||
<literal>autovacuum_analyze_threshold</> plus
|
||||
<literal>autovacuum_analyze_scale_factor</> times the number of live tuples
|
||||
currently estimated to be in the relation.
|
||||
If false, this table will not be autovacuumed, except to prevent
|
||||
transaction Id wraparound. See <xref linkend="vacuum-for-wraparound"> for
|
||||
more about wraparound prevention.
|
||||
Observe that this variable inherits its value from the <xref
|
||||
linkend="guc-autovacuum"> setting.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_vacuum_threshold</>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Minimum number of updated or deleted tuples before initiate a
|
||||
<command>VACUUM</> operation on a particular table.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_vacuum_scale_factor</>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>float4</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Multiplier for <structfield>reltuples</> to add to
|
||||
<literal>autovacuum_vacuum_threshold</>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_analyze_threshold</>, <literal>toast.autovacuum_analyze_threshold</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Minimum number of inserted, updated, or deleted tuples before initiate an
|
||||
<command>ANALYZE</> operation on a particular table.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_analyze_scale_factor</>, <literal>toast.autovacuum_analyze_scale_factor</literal> (<type>float4</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Multiplier for <structfield>reltuples</> to add to
|
||||
<literal>autovacuum_analyze_threshold</>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_vacuum_cost_delay</>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Custom <xref linkend="guc-autovacuum-vacuum-cost-delay"> parameter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_vacuum_cost_limit</>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Custom <xref linkend="guc-autovacuum-vacuum-cost-limit"> parameter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_freeze_min_age</>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Custom <xref linkend="guc-vacuum-freeze-min-age"> parameter. Note that
|
||||
autovacuum will ignore attempts to set a per-table
|
||||
<literal>autovacuum_freeze_min_age</> larger than the half system-wide
|
||||
<xref linkend="guc-autovacuum-freeze-max-age"> setting.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_freeze_max_age</>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Custom <xref linkend="guc-autovacuum-freeze-max-age"> parameter. Note that
|
||||
autovacuum will ignore attempts to set a per-table
|
||||
<literal>autovacuum_freeze_max_age</> larger than the system-wide setting
|
||||
(it can only be set smaller). Note that while you can set
|
||||
<literal>autovacuum_freeze_max_age</> very small, or even zero, this is
|
||||
usually unwise since it will force frequent vacuuming.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Custom <xref linkend="guc-vacuum-freeze-table-age"> parameter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.20 2009/02/02 19:31:38 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.21 2009/02/09 20:57:59 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -48,6 +48,14 @@
|
||||
|
||||
static relopt_bool boolRelOpts[] =
|
||||
{
|
||||
{
|
||||
{
|
||||
"autovacuum_enabled",
|
||||
"Enables autovacuum in this relation",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
true
|
||||
},
|
||||
/* list terminator */
|
||||
{ { NULL } }
|
||||
};
|
||||
@ -86,12 +94,83 @@ static relopt_int intRelOpts[] =
|
||||
},
|
||||
GIST_DEFAULT_FILLFACTOR, GIST_MIN_FILLFACTOR, 100
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_threshold",
|
||||
"Minimum number of tuple updates or deletes prior to vacuum",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
50, 0, INT_MAX
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_analyze_threshold",
|
||||
"Minimum number of tuple inserts, updates or deletes prior to analyze",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
50, 0, INT_MAX
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_cost_delay",
|
||||
"Vacuum cost delay in milliseconds, for autovacuum",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
20, 0, 1000
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_cost_limit",
|
||||
"Vacuum cost amount available before napping, for autovacuum",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
200, 1, 10000
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_freeze_min_age",
|
||||
"Minimum age at which VACUUM should freeze a table row, for autovacuum",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
100000000, 0, 1000000000
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_freeze_max_age",
|
||||
"Age at which to autovacuum a table to prevent transaction ID wraparound",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
200000000, 100000000, 2000000000
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_freeze_table_age",
|
||||
"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
|
||||
RELOPT_KIND_HEAP
|
||||
}, 150000000, 0, 2000000000
|
||||
},
|
||||
/* list terminator */
|
||||
{ { NULL } }
|
||||
};
|
||||
|
||||
static relopt_real realRelOpts[] =
|
||||
{
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_scale_factor",
|
||||
"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
0.2, 0.0, 100.0
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_analyze_scale_factor",
|
||||
"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
|
||||
RELOPT_KIND_HEAP
|
||||
},
|
||||
0.1, 0.0, 100.0
|
||||
},
|
||||
/* list terminator */
|
||||
{ { NULL } }
|
||||
};
|
||||
@ -973,7 +1052,8 @@ fillRelOptions(void *rdopts, Size basesize, relopt_value *options,
|
||||
|
||||
|
||||
/*
|
||||
* Option parser for anything that uses StdRdOptions (i.e. fillfactor only)
|
||||
* Option parser for anything that uses StdRdOptions (i.e. fillfactor and
|
||||
* autovacuum)
|
||||
*/
|
||||
bytea *
|
||||
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
||||
@ -982,7 +1062,27 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
||||
StdRdOptions *rdopts;
|
||||
int numoptions;
|
||||
relopt_parse_elt tab[] = {
|
||||
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)}
|
||||
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
|
||||
{"autovacuum_enabled", RELOPT_TYPE_BOOL,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled)},
|
||||
{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
|
||||
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
|
||||
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
|
||||
{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
|
||||
{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_min_age)},
|
||||
{"autovacuum_freeze_max_age", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_max_age)},
|
||||
{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_table_age)},
|
||||
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
|
||||
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_scale_factor)}
|
||||
};
|
||||
|
||||
options = parseRelOptions(reloptions, validate, kind, &numoptions);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile for backend/catalog
|
||||
#
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.68 2008/12/19 16:25:16 petere Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.69 2009/02/09 20:57:59 alvherre Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -26,7 +26,7 @@ all: $(BKIFILES)
|
||||
# indexing.h had better be last, and toasting.h just before it.
|
||||
|
||||
POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
|
||||
pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
|
||||
pg_proc.h pg_type.h pg_attribute.h pg_class.h \
|
||||
pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
|
||||
pg_opfamily.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 \
|
||||
|
@ -55,7 +55,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.92 2009/01/16 13:27:24 heikki Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.93 2009/02/09 20:57:59 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -69,12 +69,12 @@
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "access/reloptions.h"
|
||||
#include "access/transam.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_autovacuum.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "commands/vacuum.h"
|
||||
@ -165,13 +165,15 @@ typedef struct av_relation
|
||||
{
|
||||
Oid ar_toastrelid; /* hash key - must be first */
|
||||
Oid ar_relid;
|
||||
bool ar_hasrelopts;
|
||||
AutoVacOpts ar_reloptions; /* copy of AutoVacOpts from the main table's
|
||||
reloptions, or NULL if none */
|
||||
} av_relation;
|
||||
|
||||
/* struct to keep track of tables to vacuum and/or analyze, after rechecking */
|
||||
typedef struct autovac_table
|
||||
{
|
||||
Oid at_relid;
|
||||
Oid at_toastrelid;
|
||||
bool at_dovacuum;
|
||||
bool at_doanalyze;
|
||||
int at_freeze_min_age;
|
||||
@ -282,16 +284,17 @@ static void autovac_balance_cost(void);
|
||||
static void do_autovacuum(void);
|
||||
static void FreeWorkerInfo(int code, Datum arg);
|
||||
|
||||
static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map);
|
||||
static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
|
||||
static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map,
|
||||
TupleDesc pg_class_desc);
|
||||
static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts,
|
||||
Form_pg_class classForm,
|
||||
PgStat_StatTabEntry *tabentry, bool *dovacuum,
|
||||
bool *doanalyze, bool *wraparound);
|
||||
PgStat_StatTabEntry *tabentry,
|
||||
bool *dovacuum, bool *doanalyze, bool *wraparound);
|
||||
|
||||
static void autovacuum_do_vac_analyze(autovac_table *tab,
|
||||
BufferAccessStrategy bstrategy);
|
||||
static HeapTuple get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid,
|
||||
HTAB *table_toast_map);
|
||||
static AutoVacOpts *extract_autovac_opts(HeapTuple tup,
|
||||
TupleDesc pg_class_desc);
|
||||
static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
|
||||
PgStat_StatDBEntry *shared,
|
||||
PgStat_StatDBEntry *dbentry);
|
||||
@ -1816,8 +1819,7 @@ get_database_list(void)
|
||||
static void
|
||||
do_autovacuum(void)
|
||||
{
|
||||
Relation classRel,
|
||||
avRel;
|
||||
Relation classRel;
|
||||
HeapTuple tuple;
|
||||
HeapScanDesc relScan;
|
||||
Form_pg_database dbForm;
|
||||
@ -1829,6 +1831,7 @@ do_autovacuum(void)
|
||||
PgStat_StatDBEntry *dbentry;
|
||||
BufferAccessStrategy bstrategy;
|
||||
ScanKeyData key;
|
||||
TupleDesc pg_class_desc;
|
||||
|
||||
/*
|
||||
* StartTransactionCommand and CommitTransactionCommand will automatically
|
||||
@ -1890,12 +1893,14 @@ do_autovacuum(void)
|
||||
shared = pgstat_fetch_stat_dbentry(InvalidOid);
|
||||
|
||||
classRel = heap_open(RelationRelationId, AccessShareLock);
|
||||
avRel = heap_open(AutovacuumRelationId, AccessShareLock);
|
||||
|
||||
/* create a copy so we can use it after closing pg_class */
|
||||
pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel));
|
||||
|
||||
/* create hash table for toast <-> main relid mapping */
|
||||
MemSet(&ctl, 0, sizeof(ctl));
|
||||
ctl.keysize = sizeof(Oid);
|
||||
ctl.entrysize = sizeof(Oid) * 2;
|
||||
ctl.entrysize = sizeof(av_relation);
|
||||
ctl.hash = oid_hash;
|
||||
|
||||
table_toast_map = hash_create("TOAST to main relid map",
|
||||
@ -1909,9 +1914,9 @@ do_autovacuum(void)
|
||||
* We do this in two passes: on the first one we collect the list of
|
||||
* plain relations, and on the second one we collect TOAST tables.
|
||||
* The reason for doing the second pass is that during it we want to use
|
||||
* the main relation's pg_autovacuum entry if the TOAST table does not have
|
||||
* any, and we cannot obtain it unless we know beforehand what's the main
|
||||
* table OID.
|
||||
* the main relation's pg_class.reloptions entry if the TOAST table does
|
||||
* not have any, and we cannot obtain it unless we know beforehand what's
|
||||
* the main table OID.
|
||||
*
|
||||
* We need to check TOAST tables separately because in cases with short,
|
||||
* wide tables there might be proportionally much more activity in the
|
||||
@ -1931,9 +1936,8 @@ do_autovacuum(void)
|
||||
while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
|
||||
Form_pg_autovacuum avForm = NULL;
|
||||
PgStat_StatTabEntry *tabentry;
|
||||
HeapTuple avTup;
|
||||
AutoVacOpts *relopts;
|
||||
Oid relid;
|
||||
bool dovacuum;
|
||||
bool doanalyze;
|
||||
@ -1942,17 +1946,13 @@ do_autovacuum(void)
|
||||
|
||||
relid = HeapTupleGetOid(tuple);
|
||||
|
||||
/* Fetch the pg_autovacuum tuple for the relation, if any */
|
||||
avTup = get_pg_autovacuum_tuple_relid(avRel, relid, NULL);
|
||||
if (HeapTupleIsValid(avTup))
|
||||
avForm = (Form_pg_autovacuum) GETSTRUCT(avTup);
|
||||
|
||||
/* Fetch the pgstat entry for this table */
|
||||
/* Fetch reloptions and the pgstat entry for this table */
|
||||
relopts = extract_autovac_opts(tuple, pg_class_desc);
|
||||
tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
|
||||
shared, dbentry);
|
||||
|
||||
/* Check if it needs vacuum or analyze */
|
||||
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
||||
relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
|
||||
&dovacuum, &doanalyze, &wraparound);
|
||||
|
||||
/*
|
||||
@ -1998,7 +1998,7 @@ do_autovacuum(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Plain relations that need work are added to table_oids */
|
||||
/* relations that need work are added to table_oids */
|
||||
if (dovacuum || doanalyze)
|
||||
table_oids = lappend_oid(table_oids, relid);
|
||||
|
||||
@ -2020,12 +2020,16 @@ do_autovacuum(void)
|
||||
{
|
||||
/* hash_search already filled in the key */
|
||||
hentry->ar_relid = relid;
|
||||
hentry->ar_hasrelopts = false;
|
||||
if (relopts != NULL)
|
||||
{
|
||||
hentry->ar_hasrelopts = true;
|
||||
memcpy(&hentry->ar_reloptions, relopts,
|
||||
sizeof(AutoVacOpts));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HeapTupleIsValid(avTup))
|
||||
heap_freetuple(avTup);
|
||||
}
|
||||
|
||||
heap_endscan(relScan);
|
||||
@ -2040,10 +2044,9 @@ do_autovacuum(void)
|
||||
while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
|
||||
Form_pg_autovacuum avForm = NULL;
|
||||
PgStat_StatTabEntry *tabentry;
|
||||
HeapTuple avTup;
|
||||
Oid relid;
|
||||
AutoVacOpts *relopts = NULL;
|
||||
bool dovacuum;
|
||||
bool doanalyze;
|
||||
bool wraparound;
|
||||
@ -2057,17 +2060,26 @@ do_autovacuum(void)
|
||||
|
||||
relid = HeapTupleGetOid(tuple);
|
||||
|
||||
/* Fetch the pg_autovacuum tuple for this rel */
|
||||
avTup = get_pg_autovacuum_tuple_relid(avRel, relid, table_toast_map);
|
||||
/*
|
||||
* fetch reloptions -- if this toast table does not have them,
|
||||
* try the main rel
|
||||
*/
|
||||
relopts = extract_autovac_opts(tuple, pg_class_desc);
|
||||
if (relopts == NULL)
|
||||
{
|
||||
av_relation *hentry;
|
||||
bool found;
|
||||
|
||||
if (HeapTupleIsValid(avTup))
|
||||
avForm = (Form_pg_autovacuum) GETSTRUCT(avTup);
|
||||
hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
|
||||
if (found && hentry->ar_hasrelopts)
|
||||
relopts = &hentry->ar_reloptions;
|
||||
}
|
||||
|
||||
/* Fetch the pgstat entry for this table */
|
||||
tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
|
||||
shared, dbentry);
|
||||
|
||||
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
||||
relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
|
||||
&dovacuum, &doanalyze, &wraparound);
|
||||
|
||||
/* ignore analyze for toast tables */
|
||||
@ -2076,7 +2088,6 @@ do_autovacuum(void)
|
||||
}
|
||||
|
||||
heap_endscan(relScan);
|
||||
heap_close(avRel, AccessShareLock);
|
||||
heap_close(classRel, AccessShareLock);
|
||||
|
||||
/*
|
||||
@ -2163,10 +2174,10 @@ do_autovacuum(void)
|
||||
* condition is not closed but it is very small.
|
||||
*/
|
||||
MemoryContextSwitchTo(AutovacMemCxt);
|
||||
tab = table_recheck_autovac(relid, table_toast_map);
|
||||
tab = table_recheck_autovac(relid, table_toast_map, pg_class_desc);
|
||||
if (tab == NULL)
|
||||
{
|
||||
/* someone else vacuumed the table */
|
||||
/* someone else vacuumed the table, or it went away */
|
||||
LWLockRelease(AutovacuumScheduleLock);
|
||||
continue;
|
||||
}
|
||||
@ -2292,49 +2303,29 @@ deleted:
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a copy of the pg_autovacuum tuple for the given relid, or NULL if
|
||||
* there isn't any. avRel is pg_autovacuum, already open and suitably locked.
|
||||
* extract_autovac_opts
|
||||
*
|
||||
* If table_toast_map is not null, use it to find an alternative OID with which
|
||||
* to search a pg_autovacuum entry, if the passed relid does not yield one
|
||||
* directly.
|
||||
* Given a relation's pg_class tuple, return the AutoVacOpts portion of
|
||||
* reloptions, if set; otherwise, return NULL.
|
||||
*/
|
||||
static HeapTuple
|
||||
get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid,
|
||||
HTAB *table_toast_map)
|
||||
AutoVacOpts *
|
||||
extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
|
||||
{
|
||||
ScanKeyData entry[1];
|
||||
SysScanDesc avScan;
|
||||
HeapTuple avTup;
|
||||
bytea *relopts;
|
||||
AutoVacOpts *av;
|
||||
|
||||
ScanKeyInit(&entry[0],
|
||||
Anum_pg_autovacuum_vacrelid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
|
||||
((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
|
||||
|
||||
avScan = systable_beginscan(avRel, AutovacuumRelidIndexId, true,
|
||||
SnapshotNow, 1, entry);
|
||||
relopts = extractRelOptions(tup, pg_class_desc, InvalidOid);
|
||||
if (relopts == NULL)
|
||||
return NULL;
|
||||
|
||||
av = palloc(sizeof(AutoVacOpts));
|
||||
memcpy(av, &(((StdRdOptions *) relopts)->autovacuum), sizeof(AutoVacOpts));
|
||||
pfree(relopts);
|
||||
|
||||
avTup = systable_getnext(avScan);
|
||||
|
||||
if (HeapTupleIsValid(avTup))
|
||||
avTup = heap_copytuple(avTup);
|
||||
|
||||
systable_endscan(avScan);
|
||||
|
||||
if (!HeapTupleIsValid(avTup) && table_toast_map != NULL)
|
||||
{
|
||||
av_relation *hentry;
|
||||
bool found;
|
||||
|
||||
hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
|
||||
if (found)
|
||||
/* avoid second recursion */
|
||||
avTup = get_pg_autovacuum_tuple_relid(avRel, hentry->ar_relid,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return avTup;
|
||||
return av;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2370,13 +2361,11 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
|
||||
* Note that the returned autovac_table does not have the name fields set.
|
||||
*/
|
||||
static autovac_table *
|
||||
table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
table_recheck_autovac(Oid relid, HTAB *table_toast_map,
|
||||
TupleDesc pg_class_desc)
|
||||
{
|
||||
Form_pg_autovacuum avForm = NULL;
|
||||
Form_pg_class classForm;
|
||||
HeapTuple classTup;
|
||||
HeapTuple avTup;
|
||||
Relation avRel;
|
||||
bool dovacuum;
|
||||
bool doanalyze;
|
||||
autovac_table *tab = NULL;
|
||||
@ -2384,6 +2373,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
PgStat_StatDBEntry *shared;
|
||||
PgStat_StatDBEntry *dbentry;
|
||||
bool wraparound;
|
||||
AutoVacOpts *avopts;
|
||||
|
||||
/* use fresh stats */
|
||||
autovac_refresh_stats();
|
||||
@ -2399,23 +2389,27 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
return NULL;
|
||||
classForm = (Form_pg_class) GETSTRUCT(classTup);
|
||||
|
||||
/*
|
||||
* Fetch the pg_autovacuum entry, if any. For a toast table, also try the
|
||||
* main rel's pg_autovacuum entry if there isn't one for the TOAST table
|
||||
* itself.
|
||||
/*
|
||||
* Get the applicable reloptions. If it is a TOAST table, try to get the
|
||||
* main table reloptions if the toast table itself doesn't have.
|
||||
*/
|
||||
avRel = heap_open(AutovacuumRelationId, AccessShareLock);
|
||||
avTup = get_pg_autovacuum_tuple_relid(avRel, relid,
|
||||
classForm->relkind == RELKIND_TOASTVALUE ? table_toast_map : NULL);
|
||||
avopts = extract_autovac_opts(classTup, pg_class_desc);
|
||||
if (classForm->relkind == RELKIND_TOASTVALUE &&
|
||||
avopts == NULL && table_toast_map != NULL)
|
||||
{
|
||||
av_relation *hentry;
|
||||
bool found;
|
||||
|
||||
if (HeapTupleIsValid(avTup))
|
||||
avForm = (Form_pg_autovacuum) GETSTRUCT(avTup);
|
||||
hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
|
||||
if (found && hentry->ar_hasrelopts)
|
||||
avopts = &hentry->ar_reloptions;
|
||||
}
|
||||
|
||||
/* fetch the pgstat table entry */
|
||||
tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
|
||||
shared, dbentry);
|
||||
|
||||
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
||||
relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
|
||||
&dovacuum, &doanalyze, &wraparound);
|
||||
|
||||
/* ignore ANALYZE for toast tables */
|
||||
@ -2431,41 +2425,28 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
int vac_cost_delay;
|
||||
|
||||
/*
|
||||
* Calculate the vacuum cost parameters and the minimum freeze age. If
|
||||
* there is a tuple in pg_autovacuum, use it; else, use the GUC
|
||||
* defaults. Note that the fields may contain "-1" (or indeed any
|
||||
* negative value), which means use the GUC defaults for each setting.
|
||||
* In cost_limit, the value 0 also means to use the value from
|
||||
* elsewhere.
|
||||
* Calculate the vacuum cost parameters and the freeze ages. If there
|
||||
* are options set in pg_class.reloptions, use them; in the case of a
|
||||
* toast table, try the main table too. Otherwise use the GUC
|
||||
* defaults, autovacuum's own first and plain vacuum second.
|
||||
*/
|
||||
if (avForm != NULL)
|
||||
if (avopts)
|
||||
{
|
||||
vac_cost_limit = (avForm->vac_cost_limit > 0) ?
|
||||
avForm->vac_cost_limit :
|
||||
((autovacuum_vac_cost_limit > 0) ?
|
||||
autovacuum_vac_cost_limit : VacuumCostLimit);
|
||||
|
||||
vac_cost_delay = (avForm->vac_cost_delay >= 0) ?
|
||||
avForm->vac_cost_delay :
|
||||
((autovacuum_vac_cost_delay >= 0) ?
|
||||
autovacuum_vac_cost_delay : VacuumCostDelay);
|
||||
|
||||
freeze_min_age = (avForm->freeze_min_age >= 0) ?
|
||||
avForm->freeze_min_age : default_freeze_min_age;
|
||||
|
||||
freeze_table_age = (avForm->freeze_table_age >= 0) ?
|
||||
avForm->freeze_table_age : default_freeze_table_age;
|
||||
vac_cost_delay = avopts->vacuum_cost_delay;
|
||||
vac_cost_limit = avopts->vacuum_cost_limit;
|
||||
freeze_min_age = avopts->freeze_min_age;
|
||||
freeze_table_age = avopts->freeze_table_age;
|
||||
}
|
||||
else
|
||||
{
|
||||
vac_cost_limit = (autovacuum_vac_cost_limit > 0) ?
|
||||
autovacuum_vac_cost_limit : VacuumCostLimit;
|
||||
|
||||
vac_cost_delay = (autovacuum_vac_cost_delay >= 0) ?
|
||||
/* -1 in autovac setting means use plain vacuum_cost_delay */
|
||||
vac_cost_delay = autovacuum_vac_cost_delay >= 0 ?
|
||||
autovacuum_vac_cost_delay : VacuumCostDelay;
|
||||
|
||||
/* 0 or -1 in autovac setting means use plain vacuum_cost_limit */
|
||||
vac_cost_limit = autovacuum_vac_cost_limit > 0 ?
|
||||
autovacuum_vac_cost_limit : VacuumCostLimit;
|
||||
/* these do not have autovacuum-specific settings */
|
||||
freeze_min_age = default_freeze_min_age;
|
||||
|
||||
freeze_table_age = default_freeze_table_age;
|
||||
}
|
||||
|
||||
@ -2483,9 +2464,6 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
tab->at_datname = NULL;
|
||||
}
|
||||
|
||||
heap_close(avRel, AccessShareLock);
|
||||
if (HeapTupleIsValid(avTup))
|
||||
heap_freetuple(avTup);
|
||||
heap_freetuple(classTup);
|
||||
|
||||
return tab;
|
||||
@ -2496,8 +2474,12 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
*
|
||||
* Check whether a relation needs to be vacuumed or analyzed; return each into
|
||||
* "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
|
||||
* being forced because of Xid wraparound. avForm and tabentry can be NULL,
|
||||
* classForm shouldn't.
|
||||
* being forced because of Xid wraparound.
|
||||
*
|
||||
* relopts is a pointer to the AutoVacOpts options (either for itself in the
|
||||
* case of a plain table, or for either itself or its parent table in the case
|
||||
* of a TOAST table), NULL if none; tabentry is the pgstats entry, which can be
|
||||
* NULL.
|
||||
*
|
||||
* A table needs to be vacuumed if the number of dead tuples exceeds a
|
||||
* threshold. This threshold is calculated as
|
||||
@ -2513,19 +2495,19 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map)
|
||||
* We also force vacuum if the table's relfrozenxid is more than freeze_max_age
|
||||
* transactions back.
|
||||
*
|
||||
* A table whose pg_autovacuum.enabled value is false, is automatically
|
||||
* skipped (unless we have to vacuum it due to freeze_max_age). Thus
|
||||
* autovacuum can be disabled for specific tables. Also, when the stats
|
||||
* A table whose autovacuum_enabled option is false is
|
||||
* automatically skipped (unless we have to vacuum it due to freeze_max_age).
|
||||
* Thus autovacuum can be disabled for specific tables. Also, when the stats
|
||||
* collector does not have data about a table, it will be skipped.
|
||||
*
|
||||
* A table whose vac_base_thresh value is <0 takes the base value from the
|
||||
* A table whose vac_base_thresh value is < 0 takes the base value from the
|
||||
* autovacuum_vacuum_threshold GUC variable. Similarly, a vac_scale_factor
|
||||
* value <0 is substituted with the value of
|
||||
* value < 0 is substituted with the value of
|
||||
* autovacuum_vacuum_scale_factor GUC variable. Ditto for analyze.
|
||||
*/
|
||||
static void
|
||||
relation_needs_vacanalyze(Oid relid,
|
||||
Form_pg_autovacuum avForm,
|
||||
AutoVacOpts *relopts,
|
||||
Form_pg_class classForm,
|
||||
PgStat_StatTabEntry *tabentry,
|
||||
/* output params below */
|
||||
@ -2534,9 +2516,10 @@ relation_needs_vacanalyze(Oid relid,
|
||||
bool *wraparound)
|
||||
{
|
||||
bool force_vacuum;
|
||||
bool av_enabled;
|
||||
float4 reltuples; /* pg_class.reltuples */
|
||||
|
||||
/* constants from pg_autovacuum or GUC variables */
|
||||
/* constants from reloptions or GUC variables */
|
||||
int vac_base_thresh,
|
||||
anl_base_thresh;
|
||||
float4 vac_scale_factor,
|
||||
@ -2558,36 +2541,28 @@ relation_needs_vacanalyze(Oid relid,
|
||||
AssertArg(OidIsValid(relid));
|
||||
|
||||
/*
|
||||
* Determine vacuum/analyze equation parameters. If there is a tuple in
|
||||
* pg_autovacuum, use it; else, use the GUC defaults. Note that the
|
||||
* fields may contain "-1" (or indeed any negative value), which means use
|
||||
* the GUC defaults for each setting.
|
||||
* Determine vacuum/analyze equation parameters. We have two possible
|
||||
* sources: the passed reloptions (which could be a main table or a toast
|
||||
* table), or the autovacuum GUC variables.
|
||||
*/
|
||||
if (avForm != NULL)
|
||||
if (relopts)
|
||||
{
|
||||
vac_scale_factor = (avForm->vac_scale_factor >= 0) ?
|
||||
avForm->vac_scale_factor : autovacuum_vac_scale;
|
||||
vac_base_thresh = (avForm->vac_base_thresh >= 0) ?
|
||||
avForm->vac_base_thresh : autovacuum_vac_thresh;
|
||||
|
||||
anl_scale_factor = (avForm->anl_scale_factor >= 0) ?
|
||||
avForm->anl_scale_factor : autovacuum_anl_scale;
|
||||
anl_base_thresh = (avForm->anl_base_thresh >= 0) ?
|
||||
avForm->anl_base_thresh : autovacuum_anl_thresh;
|
||||
|
||||
freeze_max_age = (avForm->freeze_max_age >= 0) ?
|
||||
Min(avForm->freeze_max_age, autovacuum_freeze_max_age) :
|
||||
autovacuum_freeze_max_age;
|
||||
vac_scale_factor = relopts->vacuum_scale_factor;
|
||||
vac_base_thresh = relopts->vacuum_threshold;
|
||||
anl_scale_factor = relopts->analyze_scale_factor;
|
||||
anl_base_thresh = relopts->analyze_threshold;
|
||||
freeze_max_age = Min(relopts->freeze_max_age,
|
||||
autovacuum_freeze_max_age);
|
||||
av_enabled = relopts->enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
vac_scale_factor = autovacuum_vac_scale;
|
||||
vac_base_thresh = autovacuum_vac_thresh;
|
||||
|
||||
anl_scale_factor = autovacuum_anl_scale;
|
||||
anl_base_thresh = autovacuum_anl_thresh;
|
||||
|
||||
freeze_max_age = autovacuum_freeze_max_age;
|
||||
av_enabled = true;
|
||||
}
|
||||
|
||||
/* Force vacuum if table is at risk of wraparound */
|
||||
@ -2599,8 +2574,8 @@ relation_needs_vacanalyze(Oid relid,
|
||||
xidForceLimit));
|
||||
*wraparound = force_vacuum;
|
||||
|
||||
/* User disabled it in pg_autovacuum? (But ignore if at risk) */
|
||||
if (avForm && !avForm->enabled && !force_vacuum)
|
||||
/* User disabled it in pg_class.reloptions? (But ignore if at risk) */
|
||||
if (!force_vacuum && !av_enabled)
|
||||
{
|
||||
*doanalyze = false;
|
||||
*dovacuum = false;
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.521 2009/02/06 21:15:11 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.522 2009/02/09 20:57:59 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200902061
|
||||
#define CATALOG_VERSION_NO 200902091
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.106 2009/01/22 20:16:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.107 2009/02/09 20:57:59 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -97,9 +97,6 @@ DECLARE_UNIQUE_INDEX(pg_auth_members_role_member_index, 2694, on pg_auth_members
|
||||
DECLARE_UNIQUE_INDEX(pg_auth_members_member_role_index, 2695, on pg_auth_members using btree(member oid_ops, roleid oid_ops));
|
||||
#define AuthMemMemRoleIndexId 2695
|
||||
|
||||
DECLARE_UNIQUE_INDEX(pg_autovacuum_vacrelid_index, 1250, on pg_autovacuum using btree(vacrelid oid_ops));
|
||||
#define AutovacuumRelidIndexId 1250
|
||||
|
||||
DECLARE_UNIQUE_INDEX(pg_cast_oid_index, 2660, on pg_cast using btree(oid oid_ops));
|
||||
#define CastOidIndexId 2660
|
||||
DECLARE_UNIQUE_INDEX(pg_cast_source_target_index, 2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops));
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pg_autovacuum.h
|
||||
* definition of the system "autovacuum" relation (pg_autovacuum)
|
||||
*
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_autovacuum.h,v 1.11 2009/01/16 13:27:24 heikki Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PG_AUTOVACUUM_H
|
||||
#define PG_AUTOVACUUM_H
|
||||
|
||||
#include "catalog/genbki.h"
|
||||
|
||||
/* ----------------
|
||||
* 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 */
|
||||
int4 vac_cost_delay; /* vacuum cost-based delay */
|
||||
int4 vac_cost_limit; /* vacuum cost limit */
|
||||
int4 freeze_min_age; /* vacuum min freeze age */
|
||||
int4 freeze_max_age; /* max age before forcing vacuum */
|
||||
int4 freeze_table_age; /* age at which vacuum scans whole table */
|
||||
} 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 10
|
||||
#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
|
||||
#define Anum_pg_autovacuum_freeze_min_age 9
|
||||
#define Anum_pg_autovacuum_freeze_max_age 10
|
||||
#define Anum_pg_autovacuum_freeze_table_age 11
|
||||
|
||||
/* There are no preloaded tuples in pg_autovacuum.h */
|
||||
|
||||
#endif /* PG_AUTOVACUUM_H */
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.111 2009/01/01 17:24:02 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.112 2009/02/09 20:57:59 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -214,10 +214,26 @@ typedef struct RelationData
|
||||
* be applied to relations that use this format or a superset for
|
||||
* private options data.
|
||||
*/
|
||||
/* autovacuum-related reloptions. */
|
||||
typedef struct AutoVacOpts
|
||||
{
|
||||
bool enabled;
|
||||
int vacuum_threshold;
|
||||
int analyze_threshold;
|
||||
int vacuum_cost_delay;
|
||||
int vacuum_cost_limit;
|
||||
int freeze_min_age;
|
||||
int freeze_max_age;
|
||||
int freeze_table_age;
|
||||
float8 vacuum_scale_factor;
|
||||
float8 analyze_scale_factor;
|
||||
} AutoVacOpts;
|
||||
|
||||
typedef struct StdRdOptions
|
||||
{
|
||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||
int fillfactor; /* page fill factor in percent (0..100) */
|
||||
AutoVacOpts autovacuum; /* autovacuum-related options */
|
||||
} StdRdOptions;
|
||||
|
||||
#define HEAP_MIN_FILLFACTOR 10
|
||||
|
@ -90,7 +90,6 @@ SELECT relname, relhasindex
|
||||
pg_attribute | t
|
||||
pg_auth_members | t
|
||||
pg_authid | t
|
||||
pg_autovacuum | t
|
||||
pg_cast | t
|
||||
pg_class | t
|
||||
pg_constraint | t
|
||||
@ -152,7 +151,7 @@ SELECT relname, relhasindex
|
||||
timetz_tbl | f
|
||||
tinterval_tbl | f
|
||||
varchar_tbl | f
|
||||
(141 rows)
|
||||
(140 rows)
|
||||
|
||||
--
|
||||
-- another sanity check: every system catalog that has OIDs should have
|
||||
|
Loading…
Reference in New Issue
Block a user