Home Explore Blog CI



postgresql

17th chunk of `doc/src/sgml/indexam.sgml`
a29dd948a148c84ecbfc2ccbea3851da387499432781fb2b0000000100000fa0
 position.  The same
   position might be restored multiple times.  However, only one position need
   be remembered per scan; a new <function>ammarkpos</function> call overrides the
   previously marked position.  An access method that does not support ordered
   scans need not provide <function>ammarkpos</function> and <function>amrestrpos</function>
   functions in <structname>IndexAmRoutine</structname>; set those pointers to NULL
   instead.
  </para>

  <para>
   Both the scan position and the mark position (if any) must be maintained
   consistently in the face of concurrent insertions or deletions in the
   index.  It is OK if a freshly-inserted entry is not returned by a scan that
   would have found the entry if it had existed when the scan started, or for
   the scan to return such an entry upon rescanning or backing
   up even though it had not been returned the first time through.  Similarly,
   a concurrent delete might or might not be reflected in the results of a scan.
   What is important is that insertions or deletions not cause the scan to
   miss or multiply return entries that were not themselves being inserted or
   deleted.
  </para>

  <para>
   If the index stores the original indexed data values (and not some lossy
   representation of them), it is useful to
   support <link linkend="indexes-index-only-scans">index-only scans</link>, in
   which the index returns the actual data not just the TID of the heap tuple.
   This will only avoid I/O if the visibility map shows that the TID is on an
   all-visible page; else the heap tuple must be visited anyway to check
   MVCC visibility.  But that is no concern of the access method's.
  </para>

  <para>
   Instead of using <function>amgettuple</function>, an index scan can be done with
   <function>amgetbitmap</function> to fetch all tuples in one call.  This can be
   noticeably more efficient than <function>amgettuple</function> because it allows
   avoiding lock/unlock cycles within the access method.  In principle
   <function>amgetbitmap</function> should have the same effects as repeated
   <function>amgettuple</function> calls, but we impose several restrictions to
   simplify matters.  First of all, <function>amgetbitmap</function> returns all
   tuples at once and marking or restoring scan positions isn't
   supported. Secondly, the tuples are returned in a bitmap which doesn't
   have any specific ordering, which is why <function>amgetbitmap</function> doesn't
   take a <literal>direction</literal> argument.  (Ordering operators will never be
   supplied for such a scan, either.)
   Also, there is no provision for index-only scans with
   <function>amgetbitmap</function>, since there is no way to return the contents of
   index tuples.
   Finally, <function>amgetbitmap</function>
   does not guarantee any locking of the returned tuples, with implications
   spelled out in <xref linkend="index-locking"/>.
  </para>

  <para>
   Note that it is permitted for an access method to implement only
   <function>amgetbitmap</function> and not <function>amgettuple</function>, or vice versa,
   if its internal implementation is unsuited to one API or the other.
  </para>

 </sect1>

 <sect1 id="index-locking">
  <title>Index Locking Considerations</title>

  <para>
   Index access methods must handle concurrent updates
   of the index by multiple processes.
   The core <productname>PostgreSQL</productname> system obtains
   <literal>AccessShareLock</literal> on the index during an index scan, and
   <literal>RowExclusiveLock</literal> when updating the index (including plain
   <command>VACUUM</command>).  Since these lock types do not conflict, the access
   method is responsible for handling any fine-grained locking it might need.
   An <literal>ACCESS EXCLUSIVE</literal> lock on the index as a whole will be
   taken only during index creation, destruction, or <command>REINDEX</command>
   (<literal>SHARE UPDATE EXCLUSIVE</literal> is taken instead with
 

Title: Index Scan Consistency, Index-Only Scans, Bitmap Scans, and Locking
Summary
This section discusses maintaining consistent scan and mark positions in the face of concurrent updates, supporting index-only scans when the index stores original data values, and performing index scans efficiently with amgetbitmap to fetch all tuples at once (though with limitations on ordering, marking, and index-only scans). It also covers the index access methods need to handle concurrent updates, including considerations for AccessShareLock and RowExclusiveLock.