@ -352,8 +352,15 @@ static OldSerXidControl oldSerXidControl;
static SERIALIZABLEXACT * OldCommittedSxact ;
static SERIALIZABLEXACT * OldCommittedSxact ;
/* This configuration variable is used to set the predicate lock table size */
/*
* These configuration variables are used to set the predicate lock table size
* and to control promotion of predicate locks to coarser granularity in an
* attempt to degrade performance ( mostly as false positive serialization
* failure ) gracefully in the face of memory pressurel
*/
int max_predicate_locks_per_xact ; /* set by guc.c */
int max_predicate_locks_per_xact ; /* set by guc.c */
int max_predicate_locks_per_relation ; /* set by guc.c */
int max_predicate_locks_per_page ; /* set by guc.c */
/*
/*
* This provides a list of objects in order to track transactions
* This provides a list of objects in order to track transactions
@ -437,7 +444,7 @@ static void RestoreScratchTarget(bool lockheld);
static void RemoveTargetIfNoLongerUsed ( PREDICATELOCKTARGET * target ,
static void RemoveTargetIfNoLongerUsed ( PREDICATELOCKTARGET * target ,
uint32 targettaghash ) ;
uint32 targettaghash ) ;
static void DeleteChildTargetLocks ( const PREDICATELOCKTARGETTAG * newtargettag ) ;
static void DeleteChildTargetLocks ( const PREDICATELOCKTARGETTAG * newtargettag ) ;
static int PredicateLockPromotionThre shold ( const PREDICATELOCKTARGETTAG * tag ) ;
static int Max PredicateChild Locks( const PREDICATELOCKTARGETTAG * tag ) ;
static bool CheckAndPromotePredicateLockRequest ( const PREDICATELOCKTARGETTAG * reqtag ) ;
static bool CheckAndPromotePredicateLockRequest ( const PREDICATELOCKTARGETTAG * reqtag ) ;
static void DecrementParentLocks ( const PREDICATELOCKTARGETTAG * targettag ) ;
static void DecrementParentLocks ( const PREDICATELOCKTARGETTAG * targettag ) ;
static void CreatePredicateLock ( const PREDICATELOCKTARGETTAG * targettag ,
static void CreatePredicateLock ( const PREDICATELOCKTARGETTAG * targettag ,
@ -2118,28 +2125,35 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag)
}
}
/*
/*
* Returns the promotion threshold for a given predicate lock
* Returns the promotion limit for a given predicate lock target . This is the
* target . This is the number of descendant locks required to promote
* max number of descendant locks allowed before promoting to the specified
* to the specified tag . Note that the threshold includes non - direct
* tag . Note that the limit includes non - direct descendants ( e . g . , both tuples
* descendants , e . g . both tuples and pages for a relation lock .
* and pages for a relation lock ) .
*
* Currently the default limit is 2 for a page lock , and half of the value of
* max_pred_locks_per_transaction - 1 for a relation lock , to match behavior
* of earlier releases when upgrading .
*
*
* TODO SSI : We should do something more intelligent about what the
* TODO SSI : We should probably add additional GUCs to allow a maximum ratio
* thresholds are , either making it proportional to the number of
* of page and tuple locks based on the pages in a relation , and the maximum
* tuples in a page & pages in a relation , or at least making it a
* ratio of tuple locks to tuples in a page . This would provide more
* GUC . Currently the threshold is 3 for a page lock , and
* generally " balanced " allocation of locks to where they are most useful ,
* max_pred_locks_per_transaction / 2 for a relation lock , chosen
* while still allowing the absolute numbers to prevent one relation from
* entirely arbitrarily ( and without benchmarking ) .
* tying up all predicate lock resources .
*/
*/
static int
static int
PredicateLockPromotionThre shold ( const PREDICATELOCKTARGETTAG * tag )
Max PredicateChild Locks( const PREDICATELOCKTARGETTAG * tag )
{
{
switch ( GET_PREDICATELOCKTARGETTAG_TYPE ( * tag ) )
switch ( GET_PREDICATELOCKTARGETTAG_TYPE ( * tag ) )
{
{
case PREDLOCKTAG_RELATION :
case PREDLOCKTAG_RELATION :
return max_predicate_locks_per_xact / 2 ;
return max_predicate_locks_per_relation < 0
? ( max_predicate_locks_per_xact
/ ( - max_predicate_locks_per_relation ) ) - 1
: max_predicate_locks_per_relation ;
case PREDLOCKTAG_PAGE :
case PREDLOCKTAG_PAGE :
return 3 ;
return max_predicate_locks_per_page ;
case PREDLOCKTAG_TUPLE :
case PREDLOCKTAG_TUPLE :
@ -2194,8 +2208,8 @@ CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag)
else
else
parentlock - > childLocks + + ;
parentlock - > childLocks + + ;
if ( parentlock - > childLocks > =
if ( parentlock - > childLocks >
PredicateLockPromotionThre shold ( & targettag ) )
Max PredicateChild Locks( & targettag ) )
{
{
/*
/*
* We should promote to this parent lock . Continue to check its
* We should promote to this parent lock . Continue to check its