Skip to content

Commit

Permalink
Add max_pred_locks_per_{relation,page} reloptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ilmari committed Dec 18, 2018
1 parent 6b0faf7 commit cb5745f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 13 deletions.
24 changes: 23 additions & 1 deletion src/backend/access/common/reloptions.c
Expand Up @@ -348,6 +348,24 @@ static relopt_int intRelOpts[] =
},
-1, 0, 1024
},
{
{
"max_pred_locks_per_relation",
"Maximum number of pages or rows that can be predicate-locked before locking the whole relation.",
RELOPT_KIND_HEAP,
AccessExclusiveLock,
},
-1, 0, INT_MAX
},
{
{
"max_pred_locks_per_page",
"Maximum number of rows on a single page that can be predicate-locked before locking the whole page.",
RELOPT_KIND_HEAP,
AccessExclusiveLock,
},
-1, 0, INT_MAX
},

/* list terminator */
{{NULL}}
Expand Down Expand Up @@ -1397,7 +1415,11 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
{"parallel_workers", RELOPT_TYPE_INT,
offsetof(StdRdOptions, parallel_workers)},
{"vacuum_cleanup_index_scale_factor", RELOPT_TYPE_REAL,
offsetof(StdRdOptions, vacuum_cleanup_index_scale_factor)}
offsetof(StdRdOptions, vacuum_cleanup_index_scale_factor)},
{"max_pred_locks_per_relation", RELOPT_TYPE_INT,
offsetof(StdRdOptions, max_predicate_locks_per_relation)},
{"max_pred_locks_per_page", RELOPT_TYPE_INT,
offsetof(StdRdOptions, max_predicate_locks_per_page)}
};

options = parseRelOptions(reloptions, validate, kind, &numoptions);
Expand Down
37 changes: 25 additions & 12 deletions src/backend/storage/lmgr/predicate.c
Expand Up @@ -443,8 +443,9 @@ static void RestoreScratchTarget(bool lockheld);
static void RemoveTargetIfNoLongerUsed(PREDICATELOCKTARGET *target,
uint32 targettaghash);
static void DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag);
static int MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag);
static bool CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag);
static int MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag, Relation relation);
static bool CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag,
Relation relation);
static void DecrementParentLocks(const PREDICATELOCKTARGETTAG *targettag);
static void CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag,
uint32 targettaghash,
Expand All @@ -453,7 +454,8 @@ static void DeleteLockTarget(PREDICATELOCKTARGET *target, uint32 targettaghash);
static bool TransferPredicateLocksToNewTarget(PREDICATELOCKTARGETTAG oldtargettag,
PREDICATELOCKTARGETTAG newtargettag,
bool removeOld);
static void PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag);
static void PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag,
Relation relation);
static void DropAllPredicateLocksFromTable(Relation relation,
bool transfer);
static void SetNewSxactGlobalXmin(void);
Expand Down Expand Up @@ -2165,18 +2167,28 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag)
* tying up all predicate lock resources.
*/
static int
MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag)
MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag, Relation relation)
{
switch (GET_PREDICATELOCKTARGETTAG_TYPE(*tag))
{
case PREDLOCKTAG_RELATION:
{
int rel_max_pred_locks = RelationGetMaxPredicateLocksPerRelation(relation, -1);
if (rel_max_pred_locks != -1)
return rel_max_pred_locks;
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:
{
int rel_max_pred_locks_per_page = RelationGetMaxPredicateLocksPerPage(relation, -1);
if (rel_max_pred_locks_per_page != -1)
return rel_max_pred_locks_per_page;
return max_predicate_locks_per_page;
}

case PREDLOCKTAG_TUPLE:

Expand All @@ -2202,7 +2214,8 @@ MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag)
* Returns true if a parent lock was acquired and false otherwise.
*/
static bool
CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag)
CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag,
Relation relation)
{
PREDICATELOCKTARGETTAG targettag,
nexttag,
Expand Down Expand Up @@ -2232,7 +2245,7 @@ CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag)
parentlock->childLocks++;

if (parentlock->childLocks >
MaxPredicateChildLocks(&targettag))
MaxPredicateChildLocks(&targettag, relation))
{
/*
* We should promote to this parent lock. Continue to check its
Expand All @@ -2248,7 +2261,7 @@ CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag)
if (promote)
{
/* acquire coarsest ancestor eligible for promotion */
PredicateLockAcquire(&promotiontag);
PredicateLockAcquire(&promotiontag, relation);
return true;
}
else
Expand Down Expand Up @@ -2390,7 +2403,7 @@ CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag,
* any finer-grained locks covered by the new one.
*/
static void
PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag)
PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag, Relation relation)
{
uint32 targettaghash;
bool found;
Expand Down Expand Up @@ -2423,7 +2436,7 @@ PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag)
* coarser granularity, or whether there are finer-granularity locks to
* clean up.
*/
if (CheckAndPromotePredicateLockRequest(targettag))
if (CheckAndPromotePredicateLockRequest(targettag, relation))
{
/*
* Lock request was promoted to a coarser-granularity lock, and that
Expand Down Expand Up @@ -2459,7 +2472,7 @@ PredicateLockRelation(Relation relation, Snapshot snapshot)
SET_PREDICATELOCKTARGETTAG_RELATION(tag,
relation->rd_node.dbNode,
relation->rd_id);
PredicateLockAcquire(&tag);
PredicateLockAcquire(&tag, relation);
}

/*
Expand All @@ -2483,7 +2496,7 @@ PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)
relation->rd_node.dbNode,
relation->rd_id,
blkno);
PredicateLockAcquire(&tag);
PredicateLockAcquire(&tag, relation);
}

/*
Expand Down Expand Up @@ -2546,7 +2559,7 @@ PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snapshot)
relation->rd_id,
ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid));
PredicateLockAcquire(&tag);
PredicateLockAcquire(&tag, relation);
}


Expand Down
2 changes: 2 additions & 0 deletions src/bin/psql/tab-complete.c
Expand Up @@ -1911,6 +1911,8 @@ psql_completion(const char *text, int start, int end)
"fillfactor",
"parallel_workers",
"log_autovacuum_min_duration",
"max_pred_locks_per_relation",
"max_pred_locks_per_page",
"toast_tuple_target",
"toast.autovacuum_enabled",
"toast.autovacuum_freeze_max_age",
Expand Down
21 changes: 21 additions & 0 deletions src/include/utils/rel.h
Expand Up @@ -263,6 +263,8 @@ typedef struct StdRdOptions
AutoVacOpts autovacuum; /* autovacuum-related options */
bool user_catalog_table; /* use as an additional catalog relation */
int parallel_workers; /* max number of parallel workers */
int max_predicate_locks_per_relation; /* max number of predicate locks */
int max_predicate_locks_per_page; /* max number of predicate locks per page */
} StdRdOptions;

#define HEAP_MIN_FILLFACTOR 10
Expand Down Expand Up @@ -319,6 +321,25 @@ typedef struct StdRdOptions
((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))


/*
* RelationGetMaxPredicateLocksPerRelation
* Returns the relation's max_predicate_locks_per_relation reloption setting.
* Note multiple eval of argument!
*/
#define RelationGetMaxPredicateLocksPerRelation(relation, defaultmpl) \
((relation)->rd_options ? \
((StdRdOptions *) (relation)->rd_options)->max_predicate_locks_per_relation : (defaultmpl))

/*
* RelationGetMaxPredicateLocksPerPage
* Returns the relation's max_predicate_locks_per_page reloption setting.
* Note multiple eval of argument!
*/
#define RelationGetMaxPredicateLocksPerPage(relation, defaultmplpp) \
((relation)->rd_options ? \
((StdRdOptions *) (relation)->rd_options)->max_predicate_locks_per_page : (defaultmplpp))


/*
* ViewOptions
* Contents of rd_options for views
Expand Down

0 comments on commit cb5745f

Please sign in to comment.