summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-09-28 20:46:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-09-28 20:46:37 +0000
commit3a246cc28572db1b96467f15fd4df2be1e32925d (patch)
treecbd62990e88b9cb8676cd198119aebb38ac3c9ab
parentd9b68c8061ac925f341537ab03239f239bb51f29 (diff)
Arrange to preallocate all required space for the buffer and FSM hash
tables in shared memory. This ensures that overflow of the lock table creates no long-lasting problems. Per discussion with Merlin Moncure.
-rw-r--r--src/backend/storage/freespace/freespace.c6
-rw-r--r--src/backend/storage/ipc/shmem.c13
-rw-r--r--src/backend/storage/lmgr/lock.c4
-rw-r--r--src/backend/utils/hash/dynahash.c27
-rw-r--r--src/include/storage/shmem.h6
-rw-r--r--src/include/utils/hsearch.h4
6 files changed, 42 insertions, 18 deletions
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 9def3df7483..7a7d204bf5f 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.34 2004/08/29 05:06:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.35 2004/09/28 20:46:27 tgl Exp $
*
*
* NOTES:
@@ -283,8 +283,8 @@ InitFreeSpaceMap(void)
info.hash = tag_hash;
FreeSpaceMapRelHash = ShmemInitHash("Free Space Map Hash",
- MaxFSMRelations / 10,
- MaxFSMRelations,
+ MaxFSMRelations + 1,
+ MaxFSMRelations + 1,
&info,
(HASH_ELEM | HASH_FUNCTION));
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index d9cd8850395..29ef5413c89 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.80 2004/08/29 05:06:48 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.81 2004/09/28 20:46:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -262,8 +262,17 @@ InitShmemIndex(void)
* shared memory hash table.
*
* We assume caller is doing some kind of synchronization
- * so that two people dont try to create/initialize the
+ * so that two people don't try to create/initialize the
* table at once.
+ *
+ * max_size is the estimated maximum number of hashtable entries. This is
+ * not a hard limit, but the access efficiency will degrade if it is
+ * exceeded substantially (since it's used to compute directory size and
+ * the hash table buckets will get overfull).
+ *
+ * init_size is the number of hashtable entries to preallocate. For a table
+ * whose maximum size is certain, this should be equal to max_size; that
+ * ensures that no run-time out-of-shared-memory failures can occur.
*/
HTAB *
ShmemInitHash(const char *name, /* table string name for shmem index */
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index f90a3fd0e84..9699469e6d3 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.140 2004/09/12 18:30:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.141 2004/09/28 20:46:32 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@@ -241,7 +241,7 @@ LockMethodTableInit(const char *tabName,
/* Compute init/max size to request for lock hashtables */
max_table_size = NLOCKENTS(maxBackends);
- init_table_size = max_table_size / 10;
+ init_table_size = max_table_size / 2;
/* Allocate a string for the shmem index table lookups. */
/* This is just temp space in this routine, so palloc is OK. */
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index c55bcf38aa5..8078994ba55 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.53 2004/08/29 05:06:50 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.54 2004/09/28 20:46:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -63,7 +63,7 @@
*/
static void *DynaHashAlloc(Size size);
static HASHSEGMENT seg_alloc(HTAB *hashp);
-static bool element_alloc(HTAB *hashp);
+static bool element_alloc(HTAB *hashp, int nelem);
static bool dir_realloc(HTAB *hashp);
static bool expand_table(HTAB *hashp);
static bool hdefault(HTAB *hashp);
@@ -228,11 +228,26 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
CurrentDynaHashCxt = hashp->hcxt;
}
+ /* Build the hash directory structure */
if (!init_htab(hashp, nelem))
{
hash_destroy(hashp);
return NULL;
}
+
+ /*
+ * For a shared hash table, preallocate the requested number of elements.
+ * This reduces problems with run-time out-of-shared-memory conditions.
+ */
+ if (flags & HASH_SHARED_MEM)
+ {
+ if (!element_alloc(hashp, (int) nelem))
+ {
+ hash_destroy(hashp);
+ return NULL;
+ }
+ }
+
return hashp;
}
@@ -631,7 +646,7 @@ hash_search(HTAB *hashp,
if (currBucket == NULL)
{
/* no free elements. allocate another chunk of buckets */
- if (!element_alloc(hashp))
+ if (!element_alloc(hashp, HASHELEMENT_ALLOC_INCR))
return NULL; /* out of memory */
currBucket = hctl->freeList;
Assert(currBucket != NULL);
@@ -898,7 +913,7 @@ seg_alloc(HTAB *hashp)
* allocate some new elements and link them into the free list
*/
static bool
-element_alloc(HTAB *hashp)
+element_alloc(HTAB *hashp, int nelem)
{
HASHHDR *hctl = hashp->hctl;
Size elementSize;
@@ -910,13 +925,13 @@ element_alloc(HTAB *hashp)
CurrentDynaHashCxt = hashp->hcxt;
tmpElement = (HASHELEMENT *)
- hashp->alloc(HASHELEMENT_ALLOC_INCR * elementSize);
+ hashp->alloc(nelem * elementSize);
if (!tmpElement)
return false;
/* link all the new entries into the freelist */
- for (i = 0; i < HASHELEMENT_ALLOC_INCR; i++)
+ for (i = 0; i < nelem; i++)
{
tmpElement->link = hctl->freeList;
hctl->freeList = tmpElement;
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index b7a0d7b158c..fe67be6ac28 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.42 2004/08/29 04:13:10 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.43 2004/09/28 20:46:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,8 +73,8 @@ extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
/* size constants for the shmem index table */
/* max size of data structure string name */
#define SHMEM_INDEX_KEYSIZE (48)
- /* maximum size of the shmem index table */
-#define SHMEM_INDEX_SIZE (100)
+ /* max size of the shmem index table (not a hard limit) */
+#define SHMEM_INDEX_SIZE (32)
/* this is a hash bucket in the shmem index table */
typedef struct
diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h
index c19f662a610..43a86f7c169 100644
--- a/src/include/utils/hsearch.h
+++ b/src/include/utils/hsearch.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.32 2004/08/29 05:06:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.33 2004/09/28 20:46:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -135,7 +135,7 @@ typedef struct HASHCTL
#define HASH_FFACTOR 0x008 /* Set fill factor */
#define HASH_FUNCTION 0x010 /* Set user defined hash function */
#define HASH_ELEM 0x020 /* Set key/entry size */
-#define HASH_SHARED_MEM 0x040 /* Set shared mem const */
+#define HASH_SHARED_MEM 0x040 /* Hashtable is in shared memory */
#define HASH_ATTACH 0x080 /* Do not initialize hctl */
#define HASH_ALLOC 0x100 /* Set memory allocator */
#define HASH_CONTEXT 0x200 /* Set explicit memory context */