mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Convert the arithmetic for shared memory size calculation from 'int'
to 'Size' (that is, size_t), and install overflow detection checks in it. This allows us to remove the former arbitrary restrictions on NBuffers etc. It won't make any difference in a 32-bit machine, but in a 64-bit machine you could theoretically have terabytes of shared buffers. (How efficiently we could manage 'em remains to be seen.) Similarly, num_temp_buffers, work_mem, and maintenance_work_mem can be set above 2Gb on a 64-bit machine. Original patch from Koichi Suzuki, additional work by moi.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.63 2005/06/26 23:32:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.64 2005/08/20 23:26:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/shmem.h"
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/memutils.h"
|
||||
@@ -391,10 +392,10 @@ init_htab(HTAB *hashp, long nelem)
|
||||
* memory; therefore it does not count HTAB which is in local memory.
|
||||
* NB: assumes that all hash structure parameters have default values!
|
||||
*/
|
||||
long
|
||||
Size
|
||||
hash_estimate_size(long num_entries, Size entrysize)
|
||||
{
|
||||
long size = 0;
|
||||
Size size;
|
||||
long nBuckets,
|
||||
nSegments,
|
||||
nDirEntries,
|
||||
@@ -412,17 +413,20 @@ hash_estimate_size(long num_entries, Size entrysize)
|
||||
nDirEntries <<= 1; /* dir_alloc doubles dsize at each call */
|
||||
|
||||
/* fixed control info */
|
||||
size += MAXALIGN(sizeof(HASHHDR)); /* but not HTAB, per above */
|
||||
size = MAXALIGN(sizeof(HASHHDR)); /* but not HTAB, per above */
|
||||
/* directory */
|
||||
size += MAXALIGN(nDirEntries * sizeof(HASHSEGMENT));
|
||||
size = add_size(size, mul_size(nDirEntries, sizeof(HASHSEGMENT)));
|
||||
/* segments */
|
||||
size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET));
|
||||
size = add_size(size, mul_size(nSegments,
|
||||
MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET))));
|
||||
/* elements --- allocated in groups of up to HASHELEMENT_ALLOC_MAX */
|
||||
elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(entrysize);
|
||||
elementAllocCnt = Min(num_entries, HASHELEMENT_ALLOC_MAX);
|
||||
elementAllocCnt = Max(elementAllocCnt, 1);
|
||||
nElementAllocs = (num_entries - 1) / elementAllocCnt + 1;
|
||||
size += nElementAllocs * elementAllocCnt * elementSize;
|
||||
size = add_size(size,
|
||||
mul_size(nElementAllocs,
|
||||
mul_size(elementAllocCnt, elementSize)));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.283 2005/08/19 18:58:18 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.284 2005/08/20 23:26:26 tgl Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
@@ -78,6 +78,13 @@
|
||||
#define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
|
||||
#endif
|
||||
|
||||
/* upper limit for GUC variables measured in kilobytes of memory */
|
||||
#if SIZEOF_SIZE_T > 4
|
||||
#define MAX_KILOBYTES INT_MAX
|
||||
#else
|
||||
#define MAX_KILOBYTES (INT_MAX / 1024)
|
||||
#endif
|
||||
|
||||
/* XXX these should appear in other modules' header files */
|
||||
extern bool Log_disconnections;
|
||||
extern DLLIMPORT bool check_function_bodies;
|
||||
@@ -1027,6 +1034,10 @@ static struct config_int ConfigureNamesInt[] =
|
||||
* constraints here are partially unused. Similarly, the superuser
|
||||
* reserved number is checked to ensure it is less than the max
|
||||
* backends number.
|
||||
*
|
||||
* MaxBackends is limited to INT_MAX/4 because some places compute
|
||||
* 4*MaxBackends without any overflow check. Likewise we have to
|
||||
* limit NBuffers to INT_MAX/2.
|
||||
*/
|
||||
{
|
||||
{"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
||||
@@ -1034,7 +1045,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&MaxBackends,
|
||||
100, 1, INT_MAX / BLCKSZ, NULL, NULL
|
||||
100, 1, INT_MAX / 4, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1043,7 +1054,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&ReservedBackends,
|
||||
2, 0, INT_MAX / BLCKSZ, NULL, NULL
|
||||
2, 0, INT_MAX / 4, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1052,7 +1063,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&NBuffers,
|
||||
1000, 16, INT_MAX / BLCKSZ, NULL, NULL
|
||||
1000, 16, INT_MAX / 2, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1061,7 +1072,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&num_temp_buffers,
|
||||
1000, 100, INT_MAX / BLCKSZ, NULL, show_num_temp_buffers
|
||||
1000, 100, INT_MAX / 2, NULL, show_num_temp_buffers
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1094,7 +1105,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
"temporary disk files.")
|
||||
},
|
||||
&work_mem,
|
||||
1024, 8 * BLCKSZ / 1024, INT_MAX / 1024, NULL, NULL
|
||||
1024, 8 * BLCKSZ / 1024, MAX_KILOBYTES, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1103,7 +1114,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
gettext_noop("This includes operations such as VACUUM and CREATE INDEX.")
|
||||
},
|
||||
&maintenance_work_mem,
|
||||
16384, 1024, INT_MAX / 1024, NULL, NULL
|
||||
16384, 1024, MAX_KILOBYTES, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1112,7 +1123,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&max_stack_depth,
|
||||
2048, 100, INT_MAX / 1024, assign_max_stack_depth, NULL
|
||||
2048, 100, MAX_KILOBYTES, assign_max_stack_depth, NULL
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1193,7 +1204,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&max_prepared_xacts,
|
||||
50, 0, 10000, NULL, NULL
|
||||
50, 0, INT_MAX, NULL, NULL
|
||||
},
|
||||
|
||||
#ifdef LOCK_DEBUG
|
||||
@@ -1310,7 +1321,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
NULL
|
||||
},
|
||||
&XLOGbuffers,
|
||||
8, 4, INT_MAX / BLCKSZ, NULL, NULL
|
||||
8, 4, INT_MAX, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
#shared_buffers = 1000 # min 16 or max_connections*2, 8KB each
|
||||
#temp_buffers = 1000 # min 100, 8KB each
|
||||
#max_prepared_transactions = 50 # 0-10000
|
||||
#max_prepared_transactions = 50 # can be 0 or more
|
||||
#work_mem = 1024 # min 64, size in KB
|
||||
#maintenance_work_mem = 16384 # min 1024, size in KB
|
||||
#max_stack_depth = 2048 # min 100, size in KB
|
||||
|
||||
Reference in New Issue
Block a user