@@ -2040,18 +2040,24 @@ index_build(Relation heapRelation,
20402040 /*
20412041 * If we found any potentially broken HOT chains, mark the index as not
20422042 * being usable until the current transaction is below the event horizon.
2043- * See src/backend/access/heap/README.HOT for discussion.
2043+ * See src/backend/access/heap/README.HOT for discussion. Also set this
2044+ * if early pruning/vacuuming is enabled for the heap relation. While it
2045+ * might become safe to use the index earlier based on actual cleanup
2046+ * activity and other active transactions, the test for that would be much
2047+ * more complex and would require some form of blocking, so keep it simple
2048+ * and fast by just using the current transaction.
20442049 *
20452050 * However, when reindexing an existing index, we should do nothing here.
20462051 * Any HOT chains that are broken with respect to the index must predate
20472052 * the index's original creation, so there is no need to change the
20482053 * index's usability horizon. Moreover, we *must not* try to change the
20492054 * index's pg_index entry while reindexing pg_index itself, and this
2050- * optimization nicely prevents that.
2055+ * optimization nicely prevents that. The more complex rules needed for a
2056+ * reindex are handled separately after this function returns.
20512057 *
20522058 * We also need not set indcheckxmin during a concurrent index build,
20532059 * because we won't set indisvalid true until all transactions that care
2054- * about the broken HOT chains are gone.
2060+ * about the broken HOT chains or early pruning/vacuuming are gone.
20552061 *
20562062 * Therefore, this code path can only be taken during non-concurrent
20572063 * CREATE INDEX. Thus the fact that heap_update will set the pg_index
@@ -2060,7 +2066,8 @@ index_build(Relation heapRelation,
20602066 * about any concurrent readers of the tuple; no other transaction can see
20612067 * it yet.
20622068 */
2063- if (indexInfo -> ii_BrokenHotChain && !isreindex &&
2069+ if ((indexInfo -> ii_BrokenHotChain || EarlyPruningEnabled (heapRelation )) &&
2070+ !isreindex &&
20642071 !indexInfo -> ii_Concurrent )
20652072 {
20662073 Oid indexId = RelationGetRelid (indexRelation );
@@ -3389,13 +3396,19 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
33893396 * reindexing pg_index itself, we must not try to update tuples in it.
33903397 * pg_index's indexes should always have these flags in their clean state,
33913398 * so that won't happen.
3399+ *
3400+ * If early pruning/vacuuming is enabled for the heap relation, the
3401+ * usability horizon must be advanced to the current transaction on every
3402+ * build or rebuild. pg_index is OK in this regard because catalog tables
3403+ * are not subject to early cleanup.
33923404 */
33933405 if (!skipped_constraint )
33943406 {
33953407 Relation pg_index ;
33963408 HeapTuple indexTuple ;
33973409 Form_pg_index indexForm ;
33983410 bool index_bad ;
3411+ bool early_vacuum_enabled = EarlyPruningEnabled (heapRelation );
33993412
34003413 pg_index = heap_open (IndexRelationId , RowExclusiveLock );
34013414
@@ -3409,11 +3422,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
34093422 !indexForm -> indisready ||
34103423 !indexForm -> indislive );
34113424 if (index_bad ||
3412- (indexForm -> indcheckxmin && !indexInfo -> ii_BrokenHotChain ))
3425+ (indexForm -> indcheckxmin && !indexInfo -> ii_BrokenHotChain ) ||
3426+ early_vacuum_enabled )
34133427 {
3414- if (!indexInfo -> ii_BrokenHotChain )
3428+ if (!indexInfo -> ii_BrokenHotChain && ! early_vacuum_enabled )
34153429 indexForm -> indcheckxmin = false;
3416- else if (index_bad )
3430+ else if (index_bad || early_vacuum_enabled )
34173431 indexForm -> indcheckxmin = true;
34183432 indexForm -> indisvalid = true;
34193433 indexForm -> indisready = true;
0 commit comments