diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index 08ee37e..69cf625 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -220,6 +220,17 @@ PostgreSQL documentation + + + + Specify the maximum amount of memory to try for setting . + The default is 128Mb. It can be specified in Gigabytes (e.g. 8Gb), + Megabytes (e.g. 32Mb) or blocks (with no suffix). + + + + + diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 4292231..44243b9 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -120,6 +120,7 @@ static bool noclean = false; static bool do_sync = true; static bool show_setting = false; static char *xlog_dir = ""; +static int max_shared_buffers = 16384; /* internal vars */ @@ -227,6 +228,7 @@ static bool check_locale_name(int category, const char *locale, static bool check_locale_encoding(const char *locale, int encoding); static void setlocales(void); static void usage(const char *progname); +static void set_max_shared_buffers(const char * arg); #ifdef WIN32 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo); @@ -1071,7 +1073,7 @@ test_config_settings(void) static const int trial_conns[] = { 100, 50, 40, 30, 20, 10 }; - static const int trial_bufs[] = { + static const int preset_trial_bufs[] = { 16384, 8192, 4096, 3584, 3072, 2560, 2048, 1536, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 50 @@ -1079,14 +1081,40 @@ test_config_settings(void) char cmd[MAXPGPATH]; const int connslen = sizeof(trial_conns) / sizeof(int); - const int bufslen = sizeof(trial_bufs) / sizeof(int); + const int preset_bufslen = sizeof(preset_trial_bufs) / sizeof(int); + int *trial_bufs; int i, + max_bufs = preset_trial_bufs[0], + n_extra = 1, + bufslen = 1, status, test_conns, test_buffs, ok_buffers = 0; + while (max_bufs * 2 < max_shared_buffers) + { + n_extra++; + max_bufs *= 2; + } + + trial_bufs = pg_malloc((preset_bufslen + n_extra) * sizeof(int)); + + trial_bufs[0] = max_shared_buffers; + + while (max_bufs > preset_trial_bufs[0]) + { + trial_bufs[bufslen++] = max_bufs; + max_bufs = max_bufs / 2; + } + for (i= 0; i < preset_bufslen; i++) + { + if (preset_trial_bufs[i] >= max_shared_buffers) + continue; + trial_bufs[bufslen++] = preset_trial_bufs[i]; + } + printf(_("selecting default max_connections ... ")); fflush(stdout); @@ -1122,7 +1150,8 @@ test_config_settings(void) for (i = 0; i < bufslen; i++) { /* Use same amount of memory, independent of BLCKSZ */ - test_buffs = (trial_bufs[i] * 8192) / BLCKSZ; + /* Avoid overflow by doing the operations in the right order */ + test_buffs = BLCKSZ <= 8192 ? trial_bufs[i] * (8192 / BLCKSZ) : trial_bufs[i] / (BLCKSZ / 8192); if (test_buffs <= ok_buffers) { test_buffs = ok_buffers; @@ -1143,7 +1172,9 @@ test_config_settings(void) } n_buffers = test_buffs; - if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0) + if ((n_buffers * (BLCKSZ / 1024)) % (1024 * 1024) == 0) + printf("%dGB\n", (n_buffers * (BLCKSZ / 1024)) / (1024 * 1024)); + else if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0) printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024); else printf("%dkB\n", n_buffers * (BLCKSZ / 1024)); @@ -2740,9 +2771,11 @@ usage(const char *progname) " set default locale in the respective category for\n" " new databases (default taken from environment)\n")); printf(_(" --no-locale equivalent to --locale=C\n")); + printf(_(" --max-shared-buffers=MEMORY\n" + " maximum shared buffers setting to try, default 128Mb\n")); printf(_(" --pwfile=FILE read password for the new superuser from file\n")); printf(_(" -T, --text-search-config=CFG\n" - " default text search configuration\n")); + " default text search configuration\n")); printf(_(" -U, --username=NAME database superuser name\n")); printf(_(" -W, --pwprompt prompt for a password for the new superuser\n")); printf(_(" -X, --xlogdir=XLOGDIR location for the transaction log directory\n")); @@ -2810,6 +2843,36 @@ check_need_password(const char *authmethodlocal, const char *authmethodhost) } } +static void +set_max_shared_buffers(const char * arg) +{ + long int bufs; + char * endptr; + bufs = strtol(arg, &endptr, 10); + + if (pg_strcasecmp(endptr,"MB") == 0) + { + printf("endptr: '%s'\n",endptr); + /* convert megabytes to 8k pages */ + bufs *= ((1024 * 1024) / 8192); + } + else if (pg_strcasecmp(endptr,"GB") == 0) + { + /* convert gigabytes to buffers */ + bufs *= ((1024 * 1024 * 1024) / 8192); + printf("endptr: '%s' bufs = %ld\n",endptr,bufs); + } + else if (*endptr != '\0') + { + /* no other specified units allowed */ + fprintf(stderr, _("Invalid specification for chared buffers: '%s', only MB or GB allowed\n"), + arg); + exit(1); + } + max_shared_buffers = (int) bufs; +} + + int main(int argc, char *argv[]) { @@ -2828,6 +2891,7 @@ main(int argc, char *argv[]) {"lc-time", required_argument, NULL, 6}, {"lc-messages", required_argument, NULL, 7}, {"no-locale", no_argument, NULL, 8}, + {"max-shared-buffers", required_argument, NULL, 12}, {"text-search-config", required_argument, NULL, 'T'}, {"auth", required_argument, NULL, 'A'}, {"auth-local", required_argument, NULL, 10}, @@ -2972,6 +3036,9 @@ main(int argc, char *argv[]) case 9: pwfilename = xstrdup(optarg); break; + case 12: + set_max_shared_buffers(optarg); + break; case 's': show_setting = true; break; diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index 7d89318..d0f2622 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -2150,7 +2150,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc /* initdb */ header(_("initializing database system")); snprintf(buf, sizeof(buf), - SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --noclean%s%s > \"%s/log/initdb.log\" 2>&1" SYSTEMQUOTE, + SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --max-shared-buffers=32mb --noclean%s%s > \"%s/log/initdb.log\" 2>&1" SYSTEMQUOTE, bindir, temp_install, datadir, debug ? " --debug" : "", nolocale ? " --no-locale" : "",