Skip to content

Commit

Permalink
Support disabling index bypassing by VACUUM.
Browse files Browse the repository at this point in the history
Generalize the INDEX_CLEANUP VACUUM parameter (and the corresponding
reloption): make it into a ternary style boolean parameter.  It now
exposes a third option, "auto".  The "auto" option (which is now the
default) enables the "bypass index vacuuming" optimization added by
commit 1e55e7d.

"VACUUM (INDEX_CLEANUP TRUE)" is redefined to once again make VACUUM
simply do any required index vacuuming, regardless of how few dead
tuples are encountered during the first scan of the target heap relation
(unless there are exactly zero).  This gives users a way of opting out
of the "bypass index vacuuming" optimization, if for whatever reason
that proves necessary.  It is also expected to be used by PostgreSQL
developers as a testing option from time to time.

"VACUUM (INDEX_CLEANUP FALSE)" does the same thing as it always has: it
forcibly disables both index vacuuming and index cleanup.  It's not
expected to be used much in PostgreSQL 14.  The failsafe mechanism added
by commit 1e55e7d addresses the same problem in a simpler way.
INDEX_CLEANUP can now be thought of as a testing and compatibility
option.

Author: Peter Geoghegan <pg@bowt.ie>
Reviewed-By: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-By: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/CAH2-WznrBoCST4_Gxh_G9hA8NzGUbeBGnOUC8FcXcrhqsv6OHQ@mail.gmail.com
  • Loading branch information
petergeoghegan committed Jun 19, 2021
1 parent 0912698 commit 3499df0
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 127 deletions.
23 changes: 15 additions & 8 deletions doc/src/sgml/ref/create_table.sgml
Expand Up @@ -1473,20 +1473,27 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
</varlistentry>

<varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup">
<term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>boolean</type>)
<term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>)
<indexterm>
<primary><varname>vacuum_index_cleanup</varname> storage parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Enables or disables index cleanup when <command>VACUUM</command> is
run on this table. The default value is <literal>true</literal>.
Disabling index cleanup can speed up <command>VACUUM</command> very
significantly, but may also lead to severely bloated indexes if table
modifications are frequent. The <literal>INDEX_CLEANUP</literal>
parameter of <link linkend="sql-vacuum"><command>VACUUM</command></link>, if specified, overrides
the value of this option.
Forces or disables index cleanup when <command>VACUUM</command>
is run on this table. The default value is
<literal>AUTO</literal>. With <literal>OFF</literal>, index
cleanup is disabled, with <literal>ON</literal> it is enabled,
and with <literal>AUTO</literal> a decision is made dynamically,
each time <command>VACUUM</command> runs. The dynamic behavior
allows <command>VACUUM</command> to avoid needlessly scanning
indexes to remove very few dead tuples. Forcibly disabling all
index cleanup can speed up <command>VACUUM</command> very
significantly, but may also lead to severely bloated indexes if
table modifications are frequent. The
<literal>INDEX_CLEANUP</literal> parameter of <link
linkend="sql-vacuum"><command>VACUUM</command></link>, if
specified, overrides the value of this option.
</para>
</listitem>
</varlistentry>
Expand Down
57 changes: 41 additions & 16 deletions doc/src/sgml/ref/vacuum.sgml
Expand Up @@ -32,7 +32,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
ANALYZE [ <replaceable class="parameter">boolean</replaceable> ]
DISABLE_PAGE_SKIPPING [ <replaceable class="parameter">boolean</replaceable> ]
SKIP_LOCKED [ <replaceable class="parameter">boolean</replaceable> ]
INDEX_CLEANUP [ <replaceable class="parameter">boolean</replaceable> ]
INDEX_CLEANUP { AUTO | ON | OFF }
PROCESS_TOAST [ <replaceable class="parameter">boolean</replaceable> ]
TRUNCATE [ <replaceable class="parameter">boolean</replaceable> ]
PARALLEL <replaceable class="parameter">integer</replaceable>
Expand Down Expand Up @@ -193,20 +193,45 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
<term><literal>INDEX_CLEANUP</literal></term>
<listitem>
<para>
Specifies that <command>VACUUM</command> should attempt to remove
index entries pointing to dead tuples. This is normally the desired
behavior and is the default unless the
<literal>vacuum_index_cleanup</literal> option has been set to false
for the table to be vacuumed. Setting this option to false may be
useful when it is necessary to make vacuum run as quickly as possible,
for example to avoid imminent transaction ID wraparound
(see <xref linkend="vacuum-for-wraparound"/>). However, if index
cleanup is not performed regularly, performance may suffer, because
as the table is modified, indexes will accumulate dead tuples
and the table itself will accumulate dead line pointers that cannot be
removed until index cleanup is completed. This option has no effect
for tables that do not have an index and is ignored if the
<literal>FULL</literal> option is used.
Normally, <command>VACUUM</command> will skip index vacuuming
when there are very few dead tuples in the table. The cost of
processing all of the table's indexes is expected to greatly
exceed the benefit of removing dead index tuples when this
happens. This option can be used to force
<command>VACUUM</command> to process indexes when there are more
than zero dead tuples. The default is <literal>AUTO</literal>,
which allows <command>VACUUM</command> to skip index vacuuming
when appropriate. If <literal>INDEX_CLEANUP</literal> is set to
<literal>ON</literal>, <command>VACUUM</command> will
conservatively remove all dead tuples from indexes. This may be
useful for backwards compatibility with earlier releases of
<productname>PostgreSQL</productname> where this was the
standard behavior.
</para>
<para>
<literal>INDEX_CLEANUP</literal> can also be set to
<literal>OFF</literal> to force <command>VACUUM</command> to
<emphasis>always</emphasis> skip index vacuuming, even when
there are many dead tuples in the table. This may be useful
when it is necessary to make <command>VACUUM</command> run as
quickly as possible to avoid imminent transaction ID wraparound
(see <xref linkend="vacuum-for-wraparound"/>). However, the
wraparound failsafe mechanism controlled by <xref
linkend="guc-vacuum-failsafe-age"/> will generally trigger
automatically to avoid transaction ID wraparound failure, and
should be preferred. If index cleanup is not performed
regularly, performance may suffer, because as the table is
modified indexes will accumulate dead tuples and the table
itself will accumulate dead line pointers that cannot be removed
until index cleanup is completed.
</para>
<para>
This option has no effect for tables that have no index and is
ignored if the <literal>FULL</literal> option is used. It also
has no effect on the transaction ID wraparound failsafe
mechanism. When triggered it will skip index vacuuming, even
when <literal>INDEX_CLEANUP</literal> is set to
<literal>ON</literal>.
</para>
</listitem>
</varlistentry>
Expand All @@ -217,7 +242,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
<para>
Specifies that <command>VACUUM</command> should attempt to process the
corresponding <literal>TOAST</literal> table for each relation, if one
exists. This is normally the desired behavior and is the default.
exists. This is usually the desired behavior and is the default.
Setting this option to false may be useful when it is only necessary to
vacuum the main relation. This option is required when the
<literal>FULL</literal> option is used.
Expand Down
15 changes: 15 additions & 0 deletions doc/src/sgml/ref/vacuumdb.sgml
Expand Up @@ -244,6 +244,21 @@ PostgreSQL documentation
</listitem>
</varlistentry>

<varlistentry>
<term><option>--force-index-cleanup</option></term>
<listitem>
<para>
Always remove index entries pointing to dead tuples.
</para>
<note>
<para>
This option is only available for servers running
<productname>PostgreSQL</productname> 12 and later.
</para>
</note>
</listitem>
</varlistentry>

<varlistentry>
<term><option>--no-process-toast</option></term>
<listitem>
Expand Down
35 changes: 26 additions & 9 deletions src/backend/access/common/reloptions.c
Expand Up @@ -140,15 +140,6 @@ static relopt_bool boolRelOpts[] =
},
false
},
{
{
"vacuum_index_cleanup",
"Enables index vacuuming and index cleanup",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
true
},
{
{
"vacuum_truncate",
Expand Down Expand Up @@ -474,6 +465,21 @@ static relopt_real realRelOpts[] =
{{NULL}}
};

/* values from StdRdOptIndexCleanup */
relopt_enum_elt_def StdRdOptIndexCleanupValues[] =
{
{"auto", STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO},
{"on", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
{"off", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
{"true", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
{"false", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
{"yes", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
{"no", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
{"1", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
{"0", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
{(const char *) NULL} /* list terminator */
};

/* values from GistOptBufferingMode */
relopt_enum_elt_def gistBufferingOptValues[] =
{
Expand All @@ -494,6 +500,17 @@ relopt_enum_elt_def viewCheckOptValues[] =

static relopt_enum enumRelOpts[] =
{
{
{
"vacuum_index_cleanup",
"Controls index vacuuming and index cleanup",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
StdRdOptIndexCleanupValues,
STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO,
gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")
},
{
{
"buffering",
Expand Down

0 comments on commit 3499df0

Please sign in to comment.