On 07/19/2012 10:32 AM, Andrew Dunstan wrote:

On 07/19/2012 10:12 AM, Tom Lane wrote:
Robert Haas <robertmh...@gmail.com> writes:
On Wed, Jul 18, 2012 at 5:30 PM, Andrew Dunstan <and...@dunslane.net> wrote:
Or we could provide an initdb flag which would set an upper bound on
shared_buffers, and have make check (at least) use it.
How about a flag that sets the exact value for shared_buffers, rather
than a maximum?  I think a lot of users would like initdb
--shared-buffers=8GB or whatever.
That would be significantly harder to deploy in the buildfarm context.
We don't know that all the animals are capable of coping with 16MB
(or whatever target we settle on for make check) today.



Yeah - unless we allow some fallback things could get ugly. I do like the idea of allowing a settable ceiling on shared_buffers instead of having it completely hardcoded as now.




Here's a draft patch.

cheers

andrew


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
      </varlistentry>
 
      <varlistentry>
+      <term><option>--max-shared-buffers=<replaceable>memory</replaceable></option></term>
+      <listitem>
+       <para>
+        Specify the maximum amount of memory to try for setting <option>shared_buffers</option>.
+        The default is 128Mb. It can be specified in Gigabytes (e.g. 8Gb), 
+        Megabytes (e.g. 32Mb) or blocks (with no suffix).
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><option>-N</option></term>
       <term><option>--nosync</option></term>
       <listitem>
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" : "",
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to