michail-nikolaev · GitHub

Commits on Aug 17, 2026

  1. Add stress tests for concurrent index builds

    Introduce stress tests for concurrent index operations:
    - test concurrent inserts/updates during CREATE/REINDEX INDEX CONCURRENTLY
    - cover various index types (btree, gin, gist, brin, hash, spgist)
    - test unique and non-unique indexes
    - test with expressions and predicates
    - test both parallel and non-parallel operations
    - test both read-committed and repeatable-read isolation levels
    These tests verify the behavior of the following commits.

    authored and Commitfest Bot committed

    Aug 17, 2026
    Configuration menu

    Browse the repository at this point in the history

  2. Add STIR access method and validate_index flag in IndexVacuumInfo

    This patch provides infrastructure for following enhancements to concurrent index builds by:
    - validate_index in IndexVacuumInfo: set if index_bulk_delete called during the validation phase of concurrent index build
    - STIR (Short-Term Index Replacement) access method is introduced, intended solely for short-lived, auxiliary usage
    STIR functions are designed as an ephemeral helper during concurrent index builds, temporarily storing TIDs without providing the full features of a typical access method. As such, it raises warnings or errors when accessed outside its specialized usage path.
    Notable implementation points:
    - STIR indexes are always created unlogged, but the init-fork metapage is WAL-logged: it is the template the main fork is reset to after a crash, and it disables inserts into such leftover indexes
    - inserts are spread across several insertion pages (with the current page cached in rd_amcache) to avoid lock contention on a single insertion point
    Planned to be used in following commits.
    Configuration menu

    Browse the repository at this point in the history

  3. Add Datum storage support to tuplestore

    Extend tuplestore to store individual Datum values. The read/write callbacks are specialized for byval, fixed-length by-reference and variable-length by-reference types, selected once at tuplestore_begin_datum() time.
    This support enables usages of tuplestore for non-tuple data (TIDs) in the next commit.
    Configuration menu

    Browse the repository at this point in the history

  4. Use auxiliary indexes for concurrent index operations

    Replace the second table full scan in concurrent index builds with an auxiliary index approach:
    - create a STIR auxiliary index with the same predicate (if exists) as in main index
    - ii_Auxiliary in IndexInfo marks such auxiliary indexes; STIR may only be built as an auxiliary one
    - use it to track tuples inserted during the first phase
    - merge auxiliary index with main index during validation to catch up new index with any tuples missed during the first phase
    - automatically drop auxiliary when main index is ready
    To merge main and auxiliary indexes:
    - index_bulk_delete called for both, TIDs put into tuplesort
    - both tuplesort are being sorted
    - both tuplesort scanned with two pointers looking for the TIDs present in auxiliary index, but absent in main one
    - all such TIDs are put into tuplestore
    - all TIDs in tuplestore are fetched using the stream, tuplestore used in heapam_index_validate_scan_read_stream_next to provide the next page to prefetch
    - if fetched tuple is alive - it is inserted into the main index
    This eliminates the need for a second full table scan during validation, improving performance, especially for large tables. Affects both CREATE INDEX CONCURRENTLY and REINDEX INDEX CONCURRENTLY operations.
    Configuration menu

    Browse the repository at this point in the history

  5. Track and drop auxiliary indexes in DROP/REINDEX

    During concurrent index operations, auxiliary indexes may be left as orphaned objects when errors occur (junk auxiliary indexes).
    This patch improves the handling of such auxiliary indexes:
    - add ii_AuxiliaryForIndexId to IndexInfo to track the main index of an auxiliary one
    - automatically drop auxiliary indexes when the main index is dropped
    - delete junk auxiliary indexes properly during REINDEX operations
    Also add a TAP test verifying that a leftover auxiliary index is harmless after a crash: it is reset to its init fork, so inserts are silently ignored, VACUUM merely warns, and DROP INDEX removes it together with the main index.
    Configuration menu

    Browse the repository at this point in the history

  6. Optimize auxiliary index handling

    Skip unnecessary computations for auxiliary indices by:
    - in the index-insert path, detect auxiliary indexes and bypass Datum value computation
    - set indexUnchanged=false for auxiliary indices to avoid redundant checks
    These optimizations reduce overhead during concurrent index operations.
    Configuration menu

    Browse the repository at this point in the history

  7. Refresh snapshot periodically during index validation

    Enhances validation phase of concurrently built indexes by periodically refreshing snapshots rather than using a single reference snapshot. This addresses issues with xmin propagation during long-running validations.
    The validation now takes a fresh snapshot at page boundaries, paced by time (debug_cic_validate_snapshot_interval), allowing the xmin horizon to advance. The snapshot switch is ordered so that the backend's xmin is never invalid and only moves forward, and stays robust if something else (say, a cursor opened by an index expression) keeps a snapshot registered. Injection points let tests verify both that resets happen and that they fully advance xmin.
    This restores feature of commit  d9d0762 , which was reverted in commit  e28bb88 . New STIR-based approach does not depend on single reference snapshot anymore.
    Configuration menu

    Browse the repository at this point in the history

  8. Configuration menu

    Browse the repository at this point in the history

Read the original on github.com ↗