]> granicus.if.org Git - postgresql/commitdiff
Fix the size of predicate lock manager's shared memory hash tables at creation.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 11 Apr 2011 10:43:31 +0000 (13:43 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 11 Apr 2011 10:43:31 +0000 (13:43 +0300)
This way they don't compete with the regular lock manager for the slack shared
memory, making the behavior more predictable.

src/backend/storage/lmgr/predicate.c
src/backend/utils/hash/dynahash.c
src/include/utils/hsearch.h

index 72385c2f3eba67cd0cb9e8d749c4bb8f735ac4b6..eceb384e581fb7370bae11f074a9a495070881b0 100644 (file)
@@ -970,17 +970,15 @@ InitPredicateLocks(void)
 {
        HASHCTL         info;
        int                     hash_flags;
-       long            init_table_size,
-                               max_table_size;
+       long            max_table_size;
        Size            requestSize;
        bool            found;
 
        /*
-        * Compute init/max size to request for predicate lock target hashtable.
+        * Compute size of predicate lock target hashtable.
         * Note these calculations must agree with PredicateLockShmemSize!
         */
        max_table_size = NPREDICATELOCKTARGETENTS();
-       init_table_size = max_table_size / 2;
 
        /*
         * Allocate hash table for PREDICATELOCKTARGET structs.  This stores
@@ -991,17 +989,16 @@ InitPredicateLocks(void)
        info.entrysize = sizeof(PREDICATELOCKTARGET);
        info.hash = tag_hash;
        info.num_partitions = NUM_PREDICATELOCK_PARTITIONS;
-       hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
+       hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE);
 
        PredicateLockTargetHash = ShmemInitHash("PREDICATELOCKTARGET hash",
-                                                                                       init_table_size,
+                                                                                       max_table_size,
                                                                                        max_table_size,
                                                                                        &info,
                                                                                        hash_flags);
 
        /* Assume an average of 2 xacts per target */
        max_table_size *= 2;
-       init_table_size *= 2;
 
        /*
         * Reserve an entry in the hash table; we use it to make sure there's
@@ -1022,18 +1019,17 @@ InitPredicateLocks(void)
        info.entrysize = sizeof(PREDICATELOCK);
        info.hash = predicatelock_hash;
        info.num_partitions = NUM_PREDICATELOCK_PARTITIONS;
-       hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
+       hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE);
 
        PredicateLockHash = ShmemInitHash("PREDICATELOCK hash",
-                                                                         init_table_size,
+                                                                         max_table_size,
                                                                          max_table_size,
                                                                          &info,
                                                                          hash_flags);
 
        /*
-        * Compute init/max size to request for serializable transaction
-        * hashtable. Note these calculations must agree with
-        * PredicateLockShmemSize!
+        * Compute size for serializable transaction hashtable.
+        * Note these calculations must agree with PredicateLockShmemSize!
         */
        max_table_size = (MaxBackends + max_prepared_xacts);
 
@@ -1104,7 +1100,7 @@ InitPredicateLocks(void)
        info.keysize = sizeof(SERIALIZABLEXIDTAG);
        info.entrysize = sizeof(SERIALIZABLEXID);
        info.hash = tag_hash;
-       hash_flags = (HASH_ELEM | HASH_FUNCTION);
+       hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_FIXED_SIZE);
 
        SerializableXidHash = ShmemInitHash("SERIALIZABLEXID hash",
                                                                                max_table_size,
index f718785ee47cadcd4861aeaf6e499146d1930569..d9027291ee355057c813d3184e779193008f7c1f 100644 (file)
@@ -160,6 +160,7 @@ struct HTAB
        MemoryContext hcxt;                     /* memory context if default allocator used */
        char       *tabname;            /* table name (for error messages) */
        bool            isshared;               /* true if table is in shared memory */
+       bool            isfixed;                /* if true, don't enlarge */
 
        /* freezing a shared table isn't allowed, so we can keep state here */
        bool            frozen;                 /* true = no more inserts allowed */
@@ -435,6 +436,8 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
                                         errmsg("out of memory")));
        }
 
+       if (flags & HASH_FIXED_SIZE)
+               hashp->isfixed = true;
        return hashp;
 }
 
@@ -1334,6 +1337,9 @@ element_alloc(HTAB *hashp, int nelem)
        HASHELEMENT *prevElement;
        int                     i;
 
+       if (hashp->isfixed)
+               return false;
+
        /* Each element has a HASHELEMENT header plus user data. */
        elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(hctlv->entrysize);
 
index bca34d23e2ed33649ec0024f428c84e3131a7f69..ce54c0a21b17c4e5bd5b966a5456e8932b14aa67 100644 (file)
@@ -92,6 +92,7 @@ typedef struct HASHCTL
 #define HASH_CONTEXT   0x200   /* Set memory allocation context */
 #define HASH_COMPARE   0x400   /* Set user defined comparison function */
 #define HASH_KEYCOPY   0x800   /* Set user defined key-copying function */
+#define HASH_FIXED_SIZE        0x1000  /* Initial size is a hard limit */
 
 
 /* max_dsize value to indicate expansible directory */