Home Explore Blog CI



postgresql

6th chunk of `doc/src/sgml/ref/reindex.sgml`
a6118a5aa624565b5f05f9d17ea2997e861d6a34f0512c5f0000000100000e07
 the index. However, since
    it allows normal operations to continue while the index is being rebuilt, this
    method is useful for rebuilding indexes in a production environment. Of
    course, the extra CPU, memory and I/O load imposed by the index rebuild
    may slow down other operations.
   </para>

   <para>
    The following steps occur in a concurrent reindex.  Each step is run in a
    separate transaction.  If there are multiple indexes to be rebuilt, then
    each step loops through all the indexes before moving to the next step.

    <orderedlist>
     <listitem>
      <para>
       A new transient index definition is added to the catalog
       <literal>pg_index</literal>.  This definition will be used to replace
       the old index.  A <literal>SHARE UPDATE EXCLUSIVE</literal> lock at
       session level is taken on the indexes being reindexed as well as their
       associated tables to prevent any schema modification while processing.
      </para>
     </listitem>

     <listitem>
      <para>
       A first pass to build the index is done for each new index.  Once the
       index is built, its flag <literal>pg_index.indisready</literal> is
       switched to <quote>true</quote> to make it ready for inserts, making it
       visible to other sessions once the transaction that performed the build
       is finished.  This step is done in a separate transaction for each
       index.
      </para>
     </listitem>

     <listitem>
      <para>
       Then a second pass is performed to add tuples that were added while the
       first pass was running.  This step is also done in a separate
       transaction for each index.
      </para>
     </listitem>

     <listitem>
      <para>
       All the constraints that refer to the index are changed to refer to the
       new index definition, and the names of the indexes are changed.  At
       this point, <literal>pg_index.indisvalid</literal> is switched to
       <quote>true</quote> for the new index and to <quote>false</quote> for
       the old, and a cache invalidation is done causing all sessions that
       referenced the old index to be invalidated.
      </para>
     </listitem>

     <listitem>
      <para>
       The old indexes have <literal>pg_index.indisready</literal> switched to
       <quote>false</quote> to prevent any new tuple insertions, after waiting
       for running queries that might reference the old index to complete.
      </para>
     </listitem>

     <listitem>
      <para>
       The old indexes are dropped.  The <literal>SHARE UPDATE
       EXCLUSIVE</literal> session locks for the indexes and the table are
       released.
      </para>
     </listitem>
    </orderedlist>
   </para>

   <para>
    If a problem arises while rebuilding the indexes, such as a
    uniqueness violation in a unique index, the <command>REINDEX</command>
    command will fail but leave behind an <quote>invalid</quote> new index in addition to
    the pre-existing one. This index will be ignored for querying purposes
    because it might be incomplete; however it will still consume update
    overhead. The <application>psql</application> <command>\d</command> command will report
    such an index as <literal>INVALID</literal>:

<programlisting>
postgres=# \d tab
       Table "public.tab"
 Column |  Type   | Modifiers
--------+---------+-----------
 col    | integer |
Indexes:
    "idx" btree (col)
    "idx_ccnew" btree (col) INVALID
</programlisting>

    If the index marked <literal>INVALID</literal> is suffixed
    <literal>_ccnew</literal>, then

Title: Concurrent Reindex Steps and Handling Failures
Summary
This section details the ordered steps of a concurrent reindex, including adding a transient index definition, building the index in two passes, updating constraints and index names, invalidating the old index, and finally dropping it. Each step runs in a separate transaction. It also describes how REINDEX handles failures like uniqueness violations, leaving behind an invalid index, which can be identified by the INVALID status and the `_ccnew` suffix in psql.