Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08b1040

Browse files
committed
Shared-memory hashtables have non-extensible directories, which means
it's a good idea to choose the directory size based on the expectednumber of entries. But ShmemInitHash was using a hard-wired constant.Boo hiss. This accounts for recent report of postmaster failure whenasking for 64K or more buffers.
1 parentc05abfb commit08b1040

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

‎src/backend/storage/ipc/shmem.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.48 2000/01/26 05:56:58 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.49 2000/02/26 05:25:55 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -332,27 +332,29 @@ ShmemIsValid(unsigned long addr)
332332
HTAB*
333333
ShmemInitHash(char*name,/* table string name for shmem index */
334334
longinit_size,/* initial table size */
335-
longmax_size,/* max size of the table(NOT USED)*/
335+
longmax_size,/* max size of the table */
336336
HASHCTL*infoP,/* info about key and bucket size */
337337
inthash_flags)/* info about infoP */
338338
{
339339
boolfound;
340340
long*location;
341341

342342
/*
343-
* Hash tables allocated in shared memory have a fixed directory; it
344-
* can't grow or other backends wouldn't be able to find it. The
345-
* segbase is for calculating pointer values. The shared memory
343+
* Hash tables allocated in shared memory have a fixed directory;
344+
* it can't grow or other backends wouldn't be able to find it.
345+
* So, make sure we make it big enough to start with.
346+
*
347+
* The segbase is for calculating pointer values. The shared memory
346348
* allocator must be specified too.
347349
*/
348-
infoP->dsize=infoP->max_dsize=DEF_DIRSIZE;
350+
infoP->dsize=infoP->max_dsize=hash_select_dirsize(max_size);
349351
infoP->segbase= (long*)ShmemBase;
350352
infoP->alloc=ShmemAlloc;
351353
hash_flags |=HASH_SHARED_MEM |HASH_DIRSIZE;
352354

353355
/* look it up in the shmem index */
354356
location=ShmemInitStruct(name,
355-
sizeof(HHDR)+DEF_DIRSIZE*sizeof(SEG_OFFSET),
357+
sizeof(HHDR)+infoP->dsize*sizeof(SEG_OFFSET),
356358
&found);
357359

358360
/*

‎src/backend/utils/hash/dynahash.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.28 2000/01/26 05:57:24 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.29 2000/02/26 05:25:54 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -328,10 +328,7 @@ init_htab(HTAB *hashp, int nelem)
328328
{
329329
*segp=seg_alloc(hashp);
330330
if (*segp== (SEG_OFFSET)0)
331-
{
332-
hash_destroy(hashp);
333-
return0;
334-
}
331+
return-1;
335332
}
336333

337334
#ifHASH_DEBUG
@@ -392,6 +389,34 @@ hash_estimate_size(long num_entries, long keysize, long datasize)
392389
returnsize;
393390
}
394391

392+
/*
393+
* Select an appropriate directory size for a hashtable with the given
394+
* maximum number of entries.
395+
* This is only needed for hashtables in shared memory, whose directories
396+
* cannot be expanded dynamically.
397+
* NB: assumes that all hash structure parameters have default values!
398+
*
399+
* XXX this had better agree with the behavior of init_htab()...
400+
*/
401+
long
402+
hash_select_dirsize(longnum_entries)
403+
{
404+
longnBuckets,
405+
nSegments,
406+
nDirEntries;
407+
408+
/* estimate number of buckets wanted */
409+
nBuckets=1L <<my_log2((num_entries-1) /DEF_FFACTOR+1);
410+
/* # of segments needed for nBuckets */
411+
nSegments=1L <<my_log2((nBuckets-1) /DEF_SEGSIZE+1);
412+
/* directory entries */
413+
nDirEntries=DEF_DIRSIZE;
414+
while (nDirEntries<nSegments)
415+
nDirEntries <<=1;/* dir_alloc doubles dsize at each call */
416+
417+
returnnDirEntries;
418+
}
419+
395420

396421
/********************** DESTROY ROUTINES ************************/
397422

‎src/include/utils/hsearch.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/*-------------------------------------------------------------------------
22
*
33
* hsearch.h
4-
* forhashing in the new buffer manager
4+
* forhash tables, particularly hash tables in shared memory
55
*
66
*
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: hsearch.h,v 1.13 2000/01/26 05:58:38 momjian Exp $
10+
* $Id: hsearch.h,v 1.14 2000/02/26 05:25:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -25,12 +25,15 @@
2525
* whole lot of records per bucket or performance goes down.
2626
*
2727
* In a hash table allocated in shared memory, the directory cannot be
28-
* expanded because it must stay at a fixed address.
28+
* expanded because it must stay at a fixed address. The directory size
29+
* should be selected using hash_select_dirsize (and you'd better have
30+
* a good idea of the maximum number of entries!). For non-shared hash
31+
* tables, the initial directory size can be left at the default.
2932
*/
3033
#defineDEF_SEGSIZE 256
31-
#defineDEF_SEGSIZE_SHIFT 8/* log2(SEGSIZE) */
34+
#defineDEF_SEGSIZE_SHIFT 8/*must belog2(DEF_SEGSIZE) */
3235
#defineDEF_DIRSIZE 256
33-
#defineDEF_FFACTOR 1/* default fill factor */
36+
#defineDEF_FFACTOR 1/* default fill factor */
3437

3538
#definePRIME1 37/* for the hash function */
3639
#definePRIME2 1048583
@@ -42,13 +45,13 @@
4245
*/
4346
typedefstructelement
4447
{
45-
unsigned longnext;/* secret from user */
48+
unsigned longnext;/* secret from user */
4649
longkey;
4750
}ELEMENT;
4851

4952
typedefunsigned longBUCKET_INDEX;
5053

51-
/* segment is an array of bucket pointers*/
54+
/* segment is an array of bucket pointers */
5255
typedefBUCKET_INDEX*SEGMENT;
5356
typedefunsigned longSEG_OFFSET;
5457

@@ -65,10 +68,8 @@ typedef struct hashhdr
6568
longnsegs;/* Number of allocated segments */
6669
longkeysize;/* hash key length in bytes */
6770
longdatasize;/* elem data length in bytes */
68-
longmax_dsize;/* 'dsize' limit if directory is fixed
69-
* size */
70-
BUCKET_INDEXfreeBucketIndex;
71-
/* index of first free bucket */
71+
longmax_dsize;/* 'dsize' limit if directory is fixed size */
72+
BUCKET_INDEXfreeBucketIndex;/* index of first free bucket */
7273
#ifdefHASH_STATISTICS
7374
longaccesses;
7475
longcollisions;
@@ -84,7 +85,6 @@ typedef struct htab
8485
SEG_OFFSET*dir;/* 'directory' of segm starts */
8586
long*(*alloc) ();/* memory allocator (long * for alignment
8687
* reasons) */
87-
8888
}HTAB;
8989

9090
typedefstructhashctl
@@ -115,7 +115,7 @@ typedef struct hashctl
115115
#defineHASH_ALLOC0x100/* Setting memory allocator */
116116

117117

118-
/* seg_alloc assumes that INVALID_INDEX is 0*/
118+
/* seg_alloc assumes that INVALID_INDEX is 0*/
119119
#defineINVALID_INDEX(0)
120120
#defineNO_MAX_DSIZE(-1)
121121
/* number of hash buckets allocated at once */
@@ -141,6 +141,7 @@ extern long *hash_search(HTAB *hashp, char *keyPtr, HASHACTION action,
141141
bool*foundPtr);
142142
externlong*hash_seq(HTAB*hashp);
143143
externlonghash_estimate_size(longnum_entries,longkeysize,longdatasize);
144+
externlonghash_select_dirsize(longnum_entries);
144145

145146
/*
146147
* prototypes from functions in hashfn.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp