@ -1840,8 +1840,9 @@ index_build(Relation heapRelation,
*
*
* A side effect is to set indexInfo - > ii_BrokenHotChain to true if we detect
* A side effect is to set indexInfo - > ii_BrokenHotChain to true if we detect
* any potentially broken HOT chains . Currently , we set this if there are
* any potentially broken HOT chains . Currently , we set this if there are
* any RECENTLY_DEAD entries in a HOT chain , without trying very hard to
* any RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain , without
* detect whether they ' re really incompatible with the chain tip .
* trying very hard to detect whether they ' re really incompatible with the
* chain tip .
*/
*/
double
double
IndexBuildHeapScan ( Relation heapRelation ,
IndexBuildHeapScan ( Relation heapRelation ,
@ -1953,8 +1954,14 @@ IndexBuildHeapScan(Relation heapRelation,
* buffer continuously while visiting the page , so no pruning
* buffer continuously while visiting the page , so no pruning
* operation can occur either .
* operation can occur either .
*
*
* Also , although our opinions about tuple liveness could change while
* we scan the page ( due to concurrent transaction commits / aborts ) ,
* the chain root locations won ' t , so this info doesn ' t need to be
* rebuilt after waiting for another transaction .
*
* Note the implied assumption that there is no more than one live
* Note the implied assumption that there is no more than one live
* tuple per HOT - chain . . .
* tuple per HOT - chain - - - else we could create more than one index
* entry pointing to the same root tuple .
*/
*/
if ( scan - > rs_cblock ! = root_blkno )
if ( scan - > rs_cblock ! = root_blkno )
{
{
@ -2008,11 +2015,6 @@ IndexBuildHeapScan(Relation heapRelation,
* the live tuple at the end of the HOT - chain . Since this
* the live tuple at the end of the HOT - chain . Since this
* breaks semantics for pre - existing snapshots , mark the
* breaks semantics for pre - existing snapshots , mark the
* index as unusable for them .
* index as unusable for them .
*
* If we ' ve already decided that the index will be unsafe
* for old snapshots , we may as well stop indexing
* recently - dead tuples , since there ' s no longer any
* point .
*/
*/
if ( HeapTupleIsHotUpdated ( heapTuple ) )
if ( HeapTupleIsHotUpdated ( heapTuple ) )
{
{
@ -2020,8 +2022,6 @@ IndexBuildHeapScan(Relation heapRelation,
/* mark the index as unsafe for old snapshots */
/* mark the index as unsafe for old snapshots */
indexInfo - > ii_BrokenHotChain = true ;
indexInfo - > ii_BrokenHotChain = true ;
}
}
else if ( indexInfo - > ii_BrokenHotChain )
indexIt = false ;
else
else
indexIt = true ;
indexIt = true ;
/* In any case, exclude the tuple from unique-checking */
/* In any case, exclude the tuple from unique-checking */
@ -2071,7 +2071,8 @@ IndexBuildHeapScan(Relation heapRelation,
case HEAPTUPLE_DELETE_IN_PROGRESS :
case HEAPTUPLE_DELETE_IN_PROGRESS :
/*
/*
* Similar situation to INSERT_IN_PROGRESS case .
* As with INSERT_IN_PROGRESS case , this is unexpected
* unless it ' s our own deletion or a system catalog .
*/
*/
Assert ( ! ( heapTuple - > t_data - > t_infomask & HEAP_XMAX_IS_MULTI ) ) ;
Assert ( ! ( heapTuple - > t_data - > t_infomask & HEAP_XMAX_IS_MULTI ) ) ;
xwait = HeapTupleHeaderGetXmax ( heapTuple - > t_data ) ;
xwait = HeapTupleHeaderGetXmax ( heapTuple - > t_data ) ;
@ -2086,8 +2087,17 @@ IndexBuildHeapScan(Relation heapRelation,
* the tuple is dead could lead to missing a
* the tuple is dead could lead to missing a
* uniqueness violation . In that case we wait for the
* uniqueness violation . In that case we wait for the
* deleting transaction to finish and check again .
* deleting transaction to finish and check again .
*
* Also , if it ' s a HOT - updated tuple , we should not
* index it but rather the live tuple at the end of
* the HOT - chain . However , the deleting transaction
* could abort , possibly leaving this tuple as live
* after all , in which case it has to be indexed . The
* only way to know what to do is to wait for the
* deleting transaction to finish and check again .
*/
*/
if ( checking_uniqueness )
if ( checking_uniqueness | |
HeapTupleIsHotUpdated ( heapTuple ) )
{
{
/*
/*
* Must drop the lock on the buffer before we wait
* Must drop the lock on the buffer before we wait
@ -2096,22 +2106,34 @@ IndexBuildHeapScan(Relation heapRelation,
XactLockTableWait ( xwait ) ;
XactLockTableWait ( xwait ) ;
goto recheck ;
goto recheck ;
}
}
}
/*
/*
* Otherwise , we have to treat these tuples just like
* Otherwise index it but don ' t check for uniqueness ,
* RECENTLY_DELETED ones .
* the same as a RECENTLY_DEAD tuple .
*/
*/
if ( HeapTupleIsHotUpdated ( heapTuple ) )
indexIt = true ;
}
else if ( HeapTupleIsHotUpdated ( heapTuple ) )
{
{
/*
* It ' s a HOT - updated tuple deleted by our own xact .
* We can assume the deletion will commit ( else the
* index contents don ' t matter ) , so treat the same
* as RECENTLY_DEAD HOT - updated tuples .
*/
indexIt = false ;
indexIt = false ;
/* mark the index as unsafe for old snapshots */
/* mark the index as unsafe for old snapshots */
indexInfo - > ii_BrokenHotChain = true ;
indexInfo - > ii_BrokenHotChain = true ;
}
}
else if ( indexInfo - > ii_BrokenHotChain )
indexIt = false ;
else
else
{
/*
* It ' s a regular tuple deleted by our own xact .
* Index it but don ' t check for uniqueness , the same
* as a RECENTLY_DEAD tuple .
*/
indexIt = true ;
indexIt = true ;
}
/* In any case, exclude the tuple from unique-checking */
/* In any case, exclude the tuple from unique-checking */
tupleIsAlive = false ;
tupleIsAlive = false ;
break ;
break ;