diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index bcbf866fc86fba591646b36955c073d1937ba8c2..bc1a826d38c48256db6ba29c957805ac471690db 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -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> diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 0b77731e3411c30a26de6fc2f7ebde1e974c7257..7a4786fcf586c391390a30d4f14db9753bd54edc 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -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> diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index ad9c38da55b862d7271bc4bba64a21c46580f6de..2b6f53bcffaeb0f73f539a07f01fc4288abf0c8f 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -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 diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index b19c89f421141098900ffb212368a227fffb7547..a86ffbba811156d27b698277aee98e193216baaa 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -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. diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 285ed5bd2e95b6ad0634987514ecb3bd2fe43bc4..704378266541e81c8916facdea25532918ee69c7 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -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> + 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> - Same as above, for the supplementary storage table, if any; see - <xref linkend="storage-toast">. + Custom <xref linkend="guc-vacuum-freeze-table-age"> parameter. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index e566a136442bc325593be9247e81473a6515d889..548c0b00de84bac3832cc79cdb219f6b1dfdb3dc 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -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); diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 58973c9a88991588372d59b42e8ddae702447d84..9a828d66fe19a693bd47826a4614ce649550bedc 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -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 \ diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index ed77c51c9fff116370a598c7b46a1be9bdd24b18..e7aea7fc23c9e9ebecc661fe93a86b76150a7a0c 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -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); - - 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); - } + 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); - 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; diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 1db49f6a152e6f9a65675b4ef372cadad9abdc38..d02bde48c82acb992c9acbc7e749ce43a6e24385 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 1c517c7f3b664f2cdd97bbfe2030c05135b57064..bb5b9eabf63e68e92d1389149997d35eab551eb0 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -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)); diff --git a/src/include/catalog/pg_autovacuum.h b/src/include/catalog/pg_autovacuum.h deleted file mode 100644 index 94eb05b925017bf2859731a523e501159286ef3d..0000000000000000000000000000000000000000 --- a/src/include/catalog/pg_autovacuum.h +++ /dev/null @@ -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 */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index ffb2b8530d34a4c8bbde6f51a56066874873c0e9..a3aaf69e2f102c0c2dfd4bed7fbc825e0d82ba7b 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.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 diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index e677d4580fdcafa85a05165db435bcc3e7a5e92a..c6f1f158ee55cd48471074ac2338a2eff90b7775 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -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