@@ -2040,18 +2040,24 @@ index_build(Relation heapRelation,
2040
2040
/*
2041
2041
* If we found any potentially broken HOT chains, mark the index as not
2042
2042
* 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.
2044
2049
*
2045
2050
* However, when reindexing an existing index, we should do nothing here.
2046
2051
* Any HOT chains that are broken with respect to the index must predate
2047
2052
* the index's original creation, so there is no need to change the
2048
2053
* index's usability horizon. Moreover, we *must not* try to change the
2049
2054
* 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.
2051
2057
*
2052
2058
* We also need not set indcheckxmin during a concurrent index build,
2053
2059
* 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.
2055
2061
*
2056
2062
* Therefore, this code path can only be taken during non-concurrent
2057
2063
* CREATE INDEX. Thus the fact that heap_update will set the pg_index
@@ -2060,7 +2066,8 @@ index_build(Relation heapRelation,
2060
2066
* about any concurrent readers of the tuple; no other transaction can see
2061
2067
* it yet.
2062
2068
*/
2063
- if (indexInfo -> ii_BrokenHotChain && !isreindex &&
2069
+ if ((indexInfo -> ii_BrokenHotChain || EarlyPruningEnabled (heapRelation )) &&
2070
+ !isreindex &&
2064
2071
!indexInfo -> ii_Concurrent )
2065
2072
{
2066
2073
Oid indexId = RelationGetRelid (indexRelation );
@@ -3389,13 +3396,19 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3389
3396
* reindexing pg_index itself, we must not try to update tuples in it.
3390
3397
* pg_index's indexes should always have these flags in their clean state,
3391
3398
* 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.
3392
3404
*/
3393
3405
if (!skipped_constraint )
3394
3406
{
3395
3407
Relation pg_index ;
3396
3408
HeapTuple indexTuple ;
3397
3409
Form_pg_index indexForm ;
3398
3410
bool index_bad ;
3411
+ bool early_vacuum_enabled = EarlyPruningEnabled (heapRelation );
3399
3412
3400
3413
pg_index = heap_open (IndexRelationId , RowExclusiveLock );
3401
3414
@@ -3409,11 +3422,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3409
3422
!indexForm -> indisready ||
3410
3423
!indexForm -> indislive );
3411
3424
if (index_bad ||
3412
- (indexForm -> indcheckxmin && !indexInfo -> ii_BrokenHotChain ))
3425
+ (indexForm -> indcheckxmin && !indexInfo -> ii_BrokenHotChain ) ||
3426
+ early_vacuum_enabled )
3413
3427
{
3414
- if (!indexInfo -> ii_BrokenHotChain )
3428
+ if (!indexInfo -> ii_BrokenHotChain && ! early_vacuum_enabled )
3415
3429
indexForm -> indcheckxmin = false;
3416
- else if (index_bad )
3430
+ else if (index_bad || early_vacuum_enabled )
3417
3431
indexForm -> indcheckxmin = true;
3418
3432
indexForm -> indisvalid = true;
3419
3433
indexForm -> indisready = true;
0 commit comments