mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
Repair some pretty serious problems in dynahash.c and
shared memory space allocation. It's a wonder we have not seen bug reports traceable to this area ... it's quite clear that the routine dir_realloc() has never worked correctly, for example.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.21 1999/02/13 23:17:54 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.22 1999/02/22 06:16:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "storage/lmgr.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "executor/execdebug.h" /* for NDirectFileRead */
|
||||
@@ -261,21 +260,11 @@ int
|
||||
BufferShmemSize()
|
||||
{
|
||||
int size = 0;
|
||||
int nbuckets;
|
||||
int nsegs;
|
||||
int tmp;
|
||||
|
||||
nbuckets = 1 << (int) my_log2((NBuffers - 1) / DEF_FFACTOR + 1);
|
||||
nsegs = 1 << (int) my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
|
||||
|
||||
/* size of shmem index table */
|
||||
size += MAXALIGN(my_log2(SHMEM_INDEX_SIZE) * sizeof(void *)); /* HTAB->dir */
|
||||
size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
|
||||
size += MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
size += BUCKET_ALLOC_INCR *
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(SHMEM_INDEX_KEYSIZE) +
|
||||
MAXALIGN(SHMEM_INDEX_DATASIZE));
|
||||
/* size of shmem index hash table */
|
||||
size += hash_estimate_size(SHMEM_INDEX_SIZE,
|
||||
SHMEM_INDEX_KEYSIZE,
|
||||
SHMEM_INDEX_DATASIZE);
|
||||
|
||||
/* size of buffer descriptors */
|
||||
size += MAXALIGN((NBuffers + 1) * sizeof(BufferDesc));
|
||||
@@ -284,17 +273,13 @@ BufferShmemSize()
|
||||
size += NBuffers * MAXALIGN(BLCKSZ);
|
||||
|
||||
/* size of buffer hash table */
|
||||
size += MAXALIGN(my_log2(NBuffers) * sizeof(void *)); /* HTAB->dir */
|
||||
size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
|
||||
size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
tmp = (int) ceil((double) NBuffers / BUCKET_ALLOC_INCR);
|
||||
size += tmp * BUCKET_ALLOC_INCR *
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(sizeof(BufferTag)) +
|
||||
MAXALIGN(sizeof(Buffer)));
|
||||
size += hash_estimate_size(NBuffers,
|
||||
sizeof(BufferTag),
|
||||
sizeof(Buffer));
|
||||
|
||||
#ifdef BMTRACE
|
||||
size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);
|
||||
#endif
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.21 1999/02/21 01:41:44 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.22 1999/02/22 06:16:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -72,11 +72,19 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends)
|
||||
* ----------------
|
||||
*/
|
||||
CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
|
||||
size = BufferShmemSize() + LockShmemSize(maxBackends);
|
||||
|
||||
/*
|
||||
* Size of the primary shared-memory block is estimated via
|
||||
* moderately-accurate estimates for the big hogs, plus 100K for
|
||||
* the stuff that's too small to bother with estimating.
|
||||
* Then we add 10% for a safety margin.
|
||||
*/
|
||||
size = BufferShmemSize() + LockShmemSize(maxBackends);
|
||||
#ifdef STABLE_MEMORY_STORAGE
|
||||
size += MMShmemSize();
|
||||
#endif
|
||||
size += 100000;
|
||||
size += size / 10;
|
||||
|
||||
if (DebugLvl > 1)
|
||||
{
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.36 1999/02/13 23:18:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.37 1999/02/22 06:16:48 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -65,7 +65,6 @@
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/proc.h"
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "access/xact.h"
|
||||
@@ -215,7 +214,7 @@ InitShmem(unsigned int key, unsigned int size)
|
||||
/* create OR attach to the shared memory shmem index */
|
||||
info.keysize = SHMEM_INDEX_KEYSIZE;
|
||||
info.datasize = SHMEM_INDEX_DATASIZE;
|
||||
hash_flags = (HASH_ELEM);
|
||||
hash_flags = HASH_ELEM;
|
||||
|
||||
/* This will acquire the shmem index lock, but not release it. */
|
||||
ShmemIndex = ShmemInitHash("ShmemIndex",
|
||||
@@ -340,8 +339,8 @@ ShmemIsValid(unsigned long addr)
|
||||
*/
|
||||
HTAB *
|
||||
ShmemInitHash(char *name, /* table string name for shmem index */
|
||||
long init_size, /* initial size */
|
||||
long max_size, /* max size of the table */
|
||||
long init_size, /* initial table size */
|
||||
long max_size, /* max size of the table (NOT USED) */
|
||||
HASHCTL *infoP, /* info about key and bucket size */
|
||||
int hash_flags) /* info about infoP */
|
||||
{
|
||||
@@ -349,17 +348,20 @@ ShmemInitHash(char *name, /* table string name for shmem index */
|
||||
long *location;
|
||||
|
||||
/*
|
||||
* shared memory hash tables have a fixed max size so that the control
|
||||
* structures don't try to grow. The segbase is for calculating
|
||||
* pointer values. The shared memory allocator must be specified.
|
||||
* Hash tables allocated in shared memory have a fixed directory;
|
||||
* it can't grow or other backends wouldn't be able to find it.
|
||||
* The segbase is for calculating pointer values.
|
||||
* The shared memory allocator must be specified too.
|
||||
*/
|
||||
infoP->dsize = infoP->max_dsize = DEF_DIRSIZE;
|
||||
infoP->segbase = (long *) ShmemBase;
|
||||
infoP->alloc = ShmemAlloc;
|
||||
infoP->max_size = max_size;
|
||||
hash_flags |= HASH_SHARED_MEM;
|
||||
hash_flags |= HASH_SHARED_MEM | HASH_DIRSIZE;
|
||||
|
||||
/* look it up in the shmem index */
|
||||
location = ShmemInitStruct(name, my_log2(max_size) + sizeof(HHDR), &found);
|
||||
location = ShmemInitStruct(name,
|
||||
sizeof(HHDR) + DEF_DIRSIZE * sizeof(SEG_OFFSET),
|
||||
&found);
|
||||
|
||||
/*
|
||||
* shmem index is corrupted. Let someone else give the error
|
||||
@@ -375,13 +377,11 @@ ShmemInitHash(char *name, /* table string name for shmem index */
|
||||
if (found)
|
||||
hash_flags |= HASH_ATTACH;
|
||||
|
||||
/* these structures were allocated or bound in ShmemInitStruct */
|
||||
/* control information and parameters */
|
||||
/* Now provide the header and directory pointers */
|
||||
infoP->hctl = (long *) location;
|
||||
/* directory for hash lookup */
|
||||
infoP->dir = (long *) (location + sizeof(HHDR));
|
||||
infoP->dir = (long *) (((char*) location) + sizeof(HHDR));
|
||||
|
||||
return hash_create(init_size, infoP, hash_flags);;
|
||||
return hash_create(init_size, infoP, hash_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.44 1999/02/21 03:49:22 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.45 1999/02/22 06:16:52 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Outside modules can create a lock table and acquire/release
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "storage/spin.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/lock.h"
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/palloc.h"
|
||||
@@ -1481,36 +1480,21 @@ int
|
||||
LockShmemSize(int maxBackends)
|
||||
{
|
||||
int size = 0;
|
||||
int nLockEnts = NLOCKENTS(maxBackends);
|
||||
int nLockBuckets,
|
||||
nLockSegs;
|
||||
int nXidBuckets,
|
||||
nXidSegs;
|
||||
|
||||
nLockBuckets = 1 << (int) my_log2((nLockEnts - 1) / DEF_FFACTOR + 1);
|
||||
nLockSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
|
||||
|
||||
nXidBuckets = 1 << (int) my_log2((NLOCKS_PER_XACT - 1) / DEF_FFACTOR + 1);
|
||||
nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
|
||||
|
||||
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
||||
size += MAXALIGN(maxBackends * sizeof(PROC)); /* each MyProc */
|
||||
size += MAXALIGN(maxBackends * sizeof(LOCKMETHODCTL)); /* each
|
||||
* lockMethodTable->ctl */
|
||||
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
||||
|
||||
size += MAXALIGN(my_log2(nLockEnts) * sizeof(void *));
|
||||
size += MAXALIGN(sizeof(HHDR));
|
||||
size += nLockSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
size += nLockEnts * /* XXX not multiple of BUCKET_ALLOC_INCR? */
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(sizeof(LOCK))); /* contains hash key */
|
||||
/* lockHash table */
|
||||
size += hash_estimate_size(NLOCKENTS(maxBackends),
|
||||
sizeof(LOCKTAG),
|
||||
sizeof(LOCK));
|
||||
|
||||
size += MAXALIGN(my_log2(maxBackends) * sizeof(void *));
|
||||
size += MAXALIGN(sizeof(HHDR));
|
||||
size += nXidSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
size += maxBackends * /* XXX not multiple of BUCKET_ALLOC_INCR? */
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */
|
||||
/* xidHash table */
|
||||
size += hash_estimate_size(maxBackends,
|
||||
XID_TAGSIZE,
|
||||
sizeof(XIDLookupEnt));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.13 1999/02/13 23:18:36 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.14 1999/02/22 06:16:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/spin.h"
|
||||
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/memutils.h"
|
||||
@@ -565,36 +564,20 @@ int
|
||||
MMShmemSize()
|
||||
{
|
||||
int size = 0;
|
||||
int nbuckets;
|
||||
int nsegs;
|
||||
int tmp;
|
||||
|
||||
/*
|
||||
* first compute space occupied by the (dbid,relid,blkno) hash table
|
||||
*/
|
||||
|
||||
nbuckets = 1 << (int) my_log2((MMNBUFFERS - 1) / DEF_FFACTOR + 1);
|
||||
nsegs = 1 << (int) my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
|
||||
|
||||
size += MAXALIGN(my_log2(MMNBUFFERS) * sizeof(void *));
|
||||
size += MAXALIGN(sizeof(HHDR));
|
||||
size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
tmp = (int) ceil((double) MMNBUFFERS / BUCKET_ALLOC_INCR);
|
||||
size += tmp * BUCKET_ALLOC_INCR *
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(sizeof(MMHashEntry))); /* contains hash key */
|
||||
size += hash_estimate_size(MMNBUFFERS,
|
||||
0, /* MMHashEntry includes key */
|
||||
sizeof(MMHashEntry));
|
||||
|
||||
/*
|
||||
* now do the same for the rel hash table
|
||||
*/
|
||||
|
||||
size += MAXALIGN(my_log2(MMNRELATIONS) * sizeof(void *));
|
||||
size += MAXALIGN(sizeof(HHDR));
|
||||
size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
|
||||
tmp = (int) ceil((double) MMNRELATIONS / BUCKET_ALLOC_INCR);
|
||||
size += tmp * BUCKET_ALLOC_INCR *
|
||||
(MAXALIGN(sizeof(BUCKET_INDEX)) +
|
||||
MAXALIGN(sizeof(MMRelHashEntry))); /* contains hash key */
|
||||
size += hash_estimate_size(MMNRELATIONS,
|
||||
0, /* MMRelHashEntry includes key */
|
||||
sizeof(MMRelHashEntry));
|
||||
|
||||
/*
|
||||
* finally, add in the memory block we use directly
|
||||
|
Reference in New Issue
Block a user