Re: [HACKERS] [PATCH] Add GUCs for predicate lock promotion thresholds

Поиск
Список
Период
Сортировка
От ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Тема Re: [HACKERS] [PATCH] Add GUCs for predicate lock promotion thresholds
Дата
Msg-id d8ja8977o4b.fsf@dalvik.ping.uio.no
обсуждение исходный текст
Ответ на Re: [HACKERS] [PATCH] Add GUCs for predicate lock promotion thresholds  (Kevin Grittner <kgrittn@gmail.com>)
Ответы Re: [HACKERS] [PATCH] Add GUCs for predicate lock promotion thresholds  (Kevin Grittner <kgrittn@gmail.com>)
Список pgsql-hackers
Kevin Grittner <kgrittn@gmail.com> writes:

> It occurred to me that it would make sense to allow these settings
> to be attached to a database or table (though *not* a role).  I'll
> look at that when I get back if you don't get to it first.

Attached is a draft patch (no docs or tests) on top of the previous one,
adding reloptions for the per-relation and per-page thresholds.  That
made me realise that the corresponding GUCs don't need to be PGC_SIGHUP,
but could be PGC_SUSET or PGC_USERSET.  I'll adjust the original patch
if you agree.  I have not got around around to adding per-database
versions of the setting, but could have a stab at that.


-- 
- Twitter seems more influential [than blogs] in the 'gets reported in
  the mainstream press' sense at least.               - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
  to a mainstream media article.                      - Calle Dybedahl

From e2ae108ca8212790604ef7e54f278e41ca460ffb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Wed, 25 Jan 2017 00:13:53 +0000
Subject: [PATCH 2/2] Add max_pred_locks_per_{relation,page} reloptions

---
 src/backend/access/common/reloptions.c | 24 +++++++++++++++++++++-
 src/backend/storage/lmgr/predicate.c   | 37 +++++++++++++++++++++++-----------
 src/bin/psql/tab-complete.c            |  2 ++
 src/include/utils/rel.h                | 21 +++++++++++++++++++
 4 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 42b4ea410f..ab8977a218 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -284,6 +284,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}}
@@ -1310,7 +1328,11 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
         {"user_catalog_table", RELOPT_TYPE_BOOL,
         offsetof(StdRdOptions, user_catalog_table)},
         {"parallel_workers", RELOPT_TYPE_INT,
-        offsetof(StdRdOptions, parallel_workers)}
+        offsetof(StdRdOptions, parallel_workers)},
+        {"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);
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index ac927f2c3a..9b767d7e04 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -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,
@@ -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);
@@ -2138,17 +2140,27 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag)
  * entirely arbitrarily (and without benchmarking).
  */
 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
                 : 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:
 
@@ -2174,7 +2186,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,
@@ -2204,7 +2217,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
@@ -2220,7 +2233,7 @@ CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag)
     if (promote)
     {
         /* acquire coarsest ancestor eligible for promotion */
-        PredicateLockAcquire(&promotiontag);
+        PredicateLockAcquire(&promotiontag, relation);
         return true;
     }
     else
@@ -2362,7 +2375,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;
@@ -2395,7 +2408,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
@@ -2431,7 +2444,7 @@ PredicateLockRelation(Relation relation, Snapshot snapshot)
     SET_PREDICATELOCKTARGETTAG_RELATION(tag,
                                         relation->rd_node.dbNode,
                                         relation->rd_id);
-    PredicateLockAcquire(&tag);
+    PredicateLockAcquire(&tag, relation);
 }
 
 /*
@@ -2455,7 +2468,7 @@ PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)
                                     relation->rd_node.dbNode,
                                     relation->rd_id,
                                     blkno);
-    PredicateLockAcquire(&tag);
+    PredicateLockAcquire(&tag, relation);
 }
 
 /*
@@ -2518,7 +2531,7 @@ PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snapshot)
                                      relation->rd_id,
                                      ItemPointerGetBlockNumber(tid),
                                      ItemPointerGetOffsetNumber(tid));
-    PredicateLockAcquire(&tag);
+    PredicateLockAcquire(&tag, relation);
 }
 
 
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index ddad71a10f..ca75de7df6 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1919,6 +1919,8 @@ psql_completion(const char *text, int start, int end)
             "autovacuum_vacuum_threshold",
             "fillfactor",
             "parallel_workers",
+            "max_pred_locks_per_relation",
+            "max_pred_locks_per_page",
             "log_autovacuum_min_duration",
             "toast.autovacuum_enabled",
             "toast.autovacuum_freeze_max_age",
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index a617a7cf56..0e5722f6ed 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -277,6 +277,8 @@ typedef struct StdRdOptions
     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
@@ -325,6 +327,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
-- 
2.11.0


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: [HACKERS] I propose killing PL/Tcl's "modules" infrastructure
Следующее
От: Peter Eisentraut
Дата:
Сообщение: Re: [HACKERS] bytea_output output of base64