Commits on Aug 17, 2026
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.