@ -367,9 +367,6 @@ static inline void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId l
static void ProcArrayGroupClearXid ( PGPROC * proc , TransactionId latestXid ) ;
static void ProcArrayGroupClearXid ( PGPROC * proc , TransactionId latestXid ) ;
static void MaintainLatestCompletedXid ( TransactionId latestXid ) ;
static void MaintainLatestCompletedXid ( TransactionId latestXid ) ;
static void MaintainLatestCompletedXidRecovery ( TransactionId latestXid ) ;
static void MaintainLatestCompletedXidRecovery ( TransactionId latestXid ) ;
static void TransactionIdRetreatSafely ( TransactionId * xid ,
int retreat_by ,
FullTransactionId rel ) ;
static inline FullTransactionId FullXidRelativeTo ( FullTransactionId rel ,
static inline FullTransactionId FullXidRelativeTo ( FullTransactionId rel ,
TransactionId xid ) ;
TransactionId xid ) ;
@ -1709,10 +1706,7 @@ TransactionIdIsActive(TransactionId xid)
* do about that - - - data is only protected if the walsender runs continuously
* do about that - - - data is only protected if the walsender runs continuously
* while queries are executed on the standby . ( The Hot Standby code deals
* while queries are executed on the standby . ( The Hot Standby code deals
* with such cases by failing standby queries that needed to access
* with such cases by failing standby queries that needed to access
* already - removed data , so there ' s no integrity bug . ) The computed values
* already - removed data , so there ' s no integrity bug . )
* are also adjusted with vacuum_defer_cleanup_age , so increasing that setting
* on the fly is another easy way to make horizons move backwards , with no
* consequences for data integrity .
*
*
* Note : the approximate horizons ( see definition of GlobalVisState ) are
* Note : the approximate horizons ( see definition of GlobalVisState ) are
* updated by the computations done here . That ' s currently required for
* updated by the computations done here . That ' s currently required for
@ -1877,50 +1871,11 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
TransactionIdOlder ( h - > data_oldest_nonremovable , kaxmin ) ;
TransactionIdOlder ( h - > data_oldest_nonremovable , kaxmin ) ;
/* temp relations cannot be accessed in recovery */
/* temp relations cannot be accessed in recovery */
}
}
else
{
/*
* Compute the cutoff XID by subtracting vacuum_defer_cleanup_age .
*
* vacuum_defer_cleanup_age provides some additional " slop " for the
* benefit of hot standby queries on standby servers . This is quick
* and dirty , and perhaps not all that useful unless the primary has a
* predictable transaction rate , but it offers some protection when
* there ' s no walsender connection . Note that we are assuming
* vacuum_defer_cleanup_age isn ' t large enough to cause wraparound - - -
* so guc . c should limit it to no more than the xidStopLimit threshold
* in varsup . c . Also note that we intentionally don ' t apply
* vacuum_defer_cleanup_age on standby servers .
*
* Need to use TransactionIdRetreatSafely ( ) instead of open - coding the
* subtraction , to prevent creating an xid before
* FirstNormalTransactionId .
*/
Assert ( TransactionIdPrecedesOrEquals ( h - > oldest_considered_running ,
h - > shared_oldest_nonremovable ) ) ;
Assert ( TransactionIdPrecedesOrEquals ( h - > shared_oldest_nonremovable ,
h - > data_oldest_nonremovable ) ) ;
if ( vacuum_defer_cleanup_age > 0 )
Assert ( TransactionIdPrecedesOrEquals ( h - > oldest_considered_running ,
{
h - > shared_oldest_nonremovable ) ) ;
TransactionIdRetreatSafely ( & h - > oldest_considered_running ,
Assert ( TransactionIdPrecedesOrEquals ( h - > shared_oldest_nonremovable ,
vacuum_defer_cleanup_age ,
h - > data_oldest_nonremovable ) ) ;
h - > latest_completed ) ;
TransactionIdRetreatSafely ( & h - > shared_oldest_nonremovable ,
vacuum_defer_cleanup_age ,
h - > latest_completed ) ;
TransactionIdRetreatSafely ( & h - > data_oldest_nonremovable ,
vacuum_defer_cleanup_age ,
h - > latest_completed ) ;
/* defer doesn't apply to temp relations */
Assert ( TransactionIdPrecedesOrEquals ( h - > oldest_considered_running ,
h - > shared_oldest_nonremovable ) ) ;
Assert ( TransactionIdPrecedesOrEquals ( h - > shared_oldest_nonremovable ,
h - > data_oldest_nonremovable ) ) ;
}
}
/*
/*
* Check whether there are replication slots requiring an older xmin .
* Check whether there are replication slots requiring an older xmin .
@ -1947,8 +1902,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
h - > slot_catalog_xmin ) ;
h - > slot_catalog_xmin ) ;
/*
/*
* It ' s possible that slots / vacuum_defer_cleanup_age backed up the
* It ' s possible that slots backed up the horizons further than
* horizons further than oldest_considered_running . Fix .
* oldest_considered_running . Fix .
*/
*/
h - > oldest_considered_running =
h - > oldest_considered_running =
TransactionIdOlder ( h - > oldest_considered_running ,
TransactionIdOlder ( h - > oldest_considered_running ,
@ -2490,15 +2445,9 @@ GetSnapshotData(Snapshot snapshot)
*/
*/
oldestfxid = FullXidRelativeTo ( latest_completed , oldestxid ) ;
oldestfxid = FullXidRelativeTo ( latest_completed , oldestxid ) ;
/* apply vacuum_defer_cleanup_age */
def_vis_xid_data = xmin ;
TransactionIdRetreatSafely ( & def_vis_xid_data ,
vacuum_defer_cleanup_age ,
oldestfxid ) ;
/* Check whether there's a replication slot requiring an older xmin. */
/* Check whether there's a replication slot requiring an older xmin. */
def_vis_xid_data =
def_vis_xid_data =
TransactionIdOlder ( def_vis_xid_data , replication_slot_xmin ) ;
TransactionIdOlder ( xmin , replication_slot_xmin ) ;
/*
/*
* Rows in non - shared , non - catalog tables possibly could be vacuumed
* Rows in non - shared , non - catalog tables possibly could be vacuumed
@ -4320,44 +4269,6 @@ GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)
return GlobalVisTestIsRemovableXid ( state , xid ) ;
return GlobalVisTestIsRemovableXid ( state , xid ) ;
}
}
/*
* Safely retract * xid by retreat_by , store the result in * xid .
*
* Need to be careful to prevent * xid from retreating below
* FirstNormalTransactionId during epoch 0. This is important to prevent
* generating xids that cannot be converted to a FullTransactionId without
* wrapping around .
*
* If retreat_by would lead to a too old xid , FirstNormalTransactionId is
* returned instead .
*/
static void
TransactionIdRetreatSafely ( TransactionId * xid , int retreat_by , FullTransactionId rel )
{
TransactionId original_xid = * xid ;
FullTransactionId fxid ;
uint64 fxid_i ;
Assert ( TransactionIdIsNormal ( original_xid ) ) ;
Assert ( retreat_by > = 0 ) ; /* relevant GUCs are stored as ints */
AssertTransactionIdInAllowableRange ( original_xid ) ;
if ( retreat_by = = 0 )
return ;
fxid = FullXidRelativeTo ( rel , original_xid ) ;
fxid_i = U64FromFullTransactionId ( fxid ) ;
if ( ( fxid_i - FirstNormalTransactionId ) < = retreat_by )
* xid = FirstNormalTransactionId ;
else
{
* xid = TransactionIdRetreatedBy ( original_xid , retreat_by ) ;
Assert ( TransactionIdIsNormal ( * xid ) ) ;
Assert ( NormalTransactionIdPrecedes ( * xid , original_xid ) ) ;
}
}
/*
/*
* Convert a 32 bit transaction id into 64 bit transaction id , by assuming it
* Convert a 32 bit transaction id into 64 bit transaction id , by assuming it
* is within MaxTransactionId / 2 of XidFromFullTransactionId ( rel ) .
* is within MaxTransactionId / 2 of XidFromFullTransactionId ( rel ) .