Commit 3a246cc2 authored by Tom Lane's avatar Tom Lane

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.
parent d9b68c80
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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: * NOTES:
...@@ -283,8 +283,8 @@ InitFreeSpaceMap(void) ...@@ -283,8 +283,8 @@ InitFreeSpaceMap(void)
info.hash = tag_hash; info.hash = tag_hash;
FreeSpaceMapRelHash = ShmemInitHash("Free Space Map Hash", FreeSpaceMapRelHash = ShmemInitHash("Free Space Map Hash",
MaxFSMRelations / 10, MaxFSMRelations + 1,
MaxFSMRelations, MaxFSMRelations + 1,
&info, &info,
(HASH_ELEM | HASH_FUNCTION)); (HASH_ELEM | HASH_FUNCTION));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -262,8 +262,17 @@ InitShmemIndex(void)
* shared memory hash table. * shared memory hash table.
* *
* We assume caller is doing some kind of synchronization * 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. * 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 * HTAB *
ShmemInitHash(const char *name, /* table string name for shmem index */ ShmemInitHash(const char *name, /* table string name for shmem index */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Outside modules can create a lock table and acquire/release * Outside modules can create a lock table and acquire/release
...@@ -241,7 +241,7 @@ LockMethodTableInit(const char *tabName, ...@@ -241,7 +241,7 @@ LockMethodTableInit(const char *tabName,
/* Compute init/max size to request for lock hashtables */ /* Compute init/max size to request for lock hashtables */
max_table_size = NLOCKENTS(maxBackends); 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. */ /* Allocate a string for the shmem index table lookups. */
/* This is just temp space in this routine, so palloc is OK. */ /* This is just temp space in this routine, so palloc is OK. */
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -63,7 +63,7 @@
*/ */
static void *DynaHashAlloc(Size size); static void *DynaHashAlloc(Size size);
static HASHSEGMENT seg_alloc(HTAB *hashp); 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 dir_realloc(HTAB *hashp);
static bool expand_table(HTAB *hashp); static bool expand_table(HTAB *hashp);
static bool hdefault(HTAB *hashp); static bool hdefault(HTAB *hashp);
...@@ -228,11 +228,26 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) ...@@ -228,11 +228,26 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
CurrentDynaHashCxt = hashp->hcxt; CurrentDynaHashCxt = hashp->hcxt;
} }
/* Build the hash directory structure */
if (!init_htab(hashp, nelem)) if (!init_htab(hashp, nelem))
{ {
hash_destroy(hashp); hash_destroy(hashp);
return NULL; 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; return hashp;
} }
...@@ -631,7 +646,7 @@ hash_search(HTAB *hashp, ...@@ -631,7 +646,7 @@ hash_search(HTAB *hashp,
if (currBucket == NULL) if (currBucket == NULL)
{ {
/* no free elements. allocate another chunk of buckets */ /* no free elements. allocate another chunk of buckets */
if (!element_alloc(hashp)) if (!element_alloc(hashp, HASHELEMENT_ALLOC_INCR))
return NULL; /* out of memory */ return NULL; /* out of memory */
currBucket = hctl->freeList; currBucket = hctl->freeList;
Assert(currBucket != NULL); Assert(currBucket != NULL);
...@@ -898,7 +913,7 @@ seg_alloc(HTAB *hashp) ...@@ -898,7 +913,7 @@ seg_alloc(HTAB *hashp)
* allocate some new elements and link them into the free list * allocate some new elements and link them into the free list
*/ */
static bool static bool
element_alloc(HTAB *hashp) element_alloc(HTAB *hashp, int nelem)
{ {
HASHHDR *hctl = hashp->hctl; HASHHDR *hctl = hashp->hctl;
Size elementSize; Size elementSize;
...@@ -910,13 +925,13 @@ element_alloc(HTAB *hashp) ...@@ -910,13 +925,13 @@ element_alloc(HTAB *hashp)
CurrentDynaHashCxt = hashp->hcxt; CurrentDynaHashCxt = hashp->hcxt;
tmpElement = (HASHELEMENT *) tmpElement = (HASHELEMENT *)
hashp->alloc(HASHELEMENT_ALLOC_INCR * elementSize); hashp->alloc(nelem * elementSize);
if (!tmpElement) if (!tmpElement)
return false; return false;
/* link all the new entries into the freelist */ /* 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; tmpElement->link = hctl->freeList;
hctl->freeList = tmpElement; hctl->freeList = tmpElement;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -73,8 +73,8 @@ extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
/* size constants for the shmem index table */ /* size constants for the shmem index table */
/* max size of data structure string name */ /* max size of data structure string name */
#define SHMEM_INDEX_KEYSIZE (48) #define SHMEM_INDEX_KEYSIZE (48)
/* maximum size of the shmem index table */ /* max size of the shmem index table (not a hard limit) */
#define SHMEM_INDEX_SIZE (100) #define SHMEM_INDEX_SIZE (32)
/* this is a hash bucket in the shmem index table */ /* this is a hash bucket in the shmem index table */
typedef struct typedef struct
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -135,7 +135,7 @@ typedef struct HASHCTL
#define HASH_FFACTOR 0x008 /* Set fill factor */ #define HASH_FFACTOR 0x008 /* Set fill factor */
#define HASH_FUNCTION 0x010 /* Set user defined hash function */ #define HASH_FUNCTION 0x010 /* Set user defined hash function */
#define HASH_ELEM 0x020 /* Set key/entry size */ #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_ATTACH 0x080 /* Do not initialize hctl */
#define HASH_ALLOC 0x100 /* Set memory allocator */ #define HASH_ALLOC 0x100 /* Set memory allocator */
#define HASH_CONTEXT 0x200 /* Set explicit memory context */ #define HASH_CONTEXT 0x200 /* Set explicit memory context */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment