While looking at some proposed patches and pondering some questions on
performance, I realized I desperately needed ways to run benchmarks with
different settings without needing to edit postgresql.conf and
restart/reload the server each time.

Most commonly, I want to run with synchronous_commit on or off at whim.  I
thought of writing a patch specifically for that, but decided a more
general approach would be better.  The attached patch allows any arbitrary
command to be executed upon the start up of each connection intended for
benchmarking (as opposed to utility connections, intended for either -i or
for counting the rows in in pgbench_branches and for vacuuming), and so
covers the need for changing any session-changeable GUCs, plus doing other
things as well.

I created doBenchMarkConnect() to segregate bench-marking connections from
utility connections.  At first I thought of adding the startup code to only
the normal path and leaving support for -C in the wind, but decided that
was just lazy.

Will add to commitfest-next.

Cheers,

Jeff
diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
new file mode 100644
index 11c0062..3a00127
*** a/contrib/pgbench/pgbench.c
--- b/contrib/pgbench/pgbench.c
*************** double		sample_rate = 0.0;
*** 142,147 ****
--- 142,148 ----
  char	   *tablespace = NULL;
  char	   *index_tablespace = NULL;
  
+ char	   *startup = NULL;
  /*
   * end of configurable parameters
   *********************************************************************/
*************** usage(void)
*** 394,400 ****
  		   "  --unlogged-tables\n"
  		   "               create tables as unlogged tables\n"
  		   "\nBenchmarking options:\n"
! 		"  -c NUM       number of concurrent database clients (default: 1)\n"
  		   "  -C           establish new connection for each transaction\n"
  		   "  -D VARNAME=VALUE\n"
  		   "               define variable for use by custom script\n"
--- 395,401 ----
  		   "  --unlogged-tables\n"
  		   "               create tables as unlogged tables\n"
  		   "\nBenchmarking options:\n"
! 		   "  -c NUM       number of concurrent database clients (default: 1)\n"
  		   "  -C           establish new connection for each transaction\n"
  		   "  -D VARNAME=VALUE\n"
  		   "               define variable for use by custom script\n"
*************** usage(void)
*** 412,420 ****
  		   "  -r           report average latency per command\n"
  		   "  -s NUM       report this scale factor in output\n"
  		   "  -S           perform SELECT-only transactions\n"
! 	 "  -t NUM       number of transactions each client runs (default: 10)\n"
  		   "  -T NUM       duration of benchmark test in seconds\n"
  		   "  -v           vacuum all four standard tables before tests\n"
  		   "\nCommon options:\n"
  		   "  -d             print debugging output\n"
  		   "  -h HOSTNAME    database server host or socket directory\n"
--- 413,423 ----
  		   "  -r           report average latency per command\n"
  		   "  -s NUM       report this scale factor in output\n"
  		   "  -S           perform SELECT-only transactions\n"
! 		   "  -t NUM       number of transactions each client runs (default: 10)\n"
  		   "  -T NUM       duration of benchmark test in seconds\n"
  		   "  -v           vacuum all four standard tables before tests\n"
+  		   "  --startup=COMMAND\n"
+ 		   "               Run COMMAND upon creating each benchmarking connection\n"
  		   "\nCommon options:\n"
  		   "  -d             print debugging output\n"
  		   "  -h HOSTNAME    database server host or socket directory\n"
*************** executeStatement(PGconn *con, const char
*** 520,526 ****
  	res = PQexec(con, sql);
  	if (PQresultStatus(res) != PGRES_COMMAND_OK)
  	{
! 		fprintf(stderr, "%s", PQerrorMessage(con));
  		exit(1);
  	}
  	PQclear(res);
--- 523,529 ----
  	res = PQexec(con, sql);
  	if (PQresultStatus(res) != PGRES_COMMAND_OK)
  	{
! 		fprintf(stderr, "Command failed with %s", PQerrorMessage(con));
  		exit(1);
  	}
  	PQclear(res);
*************** doConnect(void)
*** 593,598 ****
--- 596,613 ----
  	return conn;
  }
  
+ /* set up a connection to the backend intended for benchmarking */
+ static PGconn *
+ doBenchMarkConnect(void)
+ {
+ 	static PGconn * conn;
+ 	conn = doConnect();
+ 	if (startup != NULL) {
+ 		executeStatement(conn, startup);
+ 	};
+ 	return conn;
+ };
+ 
  /* throw away response from backend */
  static void
  discard_response(CState *state)
*************** top:
*** 1131,1137 ****
  					end;
  
  		INSTR_TIME_SET_CURRENT(start);
! 		if ((st->con = doConnect()) == NULL)
  		{
  			fprintf(stderr, "Client %d aborted in establishing connection.\n", st->id);
  			return clientDone(st, false);
--- 1146,1152 ----
  					end;
  
  		INSTR_TIME_SET_CURRENT(start);
! 		if ((st->con = doBenchMarkConnect()) == NULL)
  		{
  			fprintf(stderr, "Client %d aborted in establishing connection.\n", st->id);
  			return clientDone(st, false);
*************** main(int argc, char **argv)
*** 2139,2144 ****
--- 2154,2160 ----
  		{"unlogged-tables", no_argument, &unlogged_tables, 1},
  		{"sampling-rate", required_argument, NULL, 4},
  		{"aggregate-interval", required_argument, NULL, 5},
+   		{"startup", required_argument, NULL, 6},
  		{NULL, 0, NULL, 0}
  	};
  
*************** main(int argc, char **argv)
*** 2366,2371 ****
--- 2382,2390 ----
  			case 2:				/* tablespace */
  				tablespace = pg_strdup(optarg);
  				break;
+ 			case 6:				/* tablespace */
+ 				startup = pg_strdup(optarg);
+ 				break;
  			case 3:				/* index-tablespace */
  				index_tablespace = pg_strdup(optarg);
  				break;
*************** threadRun(void *arg)
*** 2749,2755 ****
  		/* make connections to the database */
  		for (i = 0; i < nstate; i++)
  		{
! 			if ((state[i].con = doConnect()) == NULL)
  				goto done;
  		}
  	}
--- 2768,2774 ----
  		/* make connections to the database */
  		for (i = 0; i < nstate; i++)
  		{
! 			if ((state[i].con = doBenchMarkConnect()) == NULL)
  				goto done;
  		}
  	}
diff --git a/doc/src/sgml/pgbench.sgml b/doc/src/sgml/pgbench.sgml
new file mode 100644
index 79b4baf..a4324f1
*** a/doc/src/sgml/pgbench.sgml
--- b/doc/src/sgml/pgbench.sgml
*************** pgbench <optional> <replaceable>options<
*** 479,484 ****
--- 479,499 ----
        </listitem>
       </varlistentry>
  
+      <varlistentry>
+       <term><option>--startup=<replaceable>COMMAND</replaceable></option></term>
+       <listitem>
+        <para>
+        	Execute the <replaceable>COMMAND</replaceable> upon the establishment
+ 		of each connection intended for receipt of benchmarking queries.
+        </para>
+        <para>
+        	For example <literal>--startup="set synchronous_commit=off"</> will cause benchmarking 
+ 		to be done without fsyncing the WAL for every transaction, regardless of the default 
+ 		server settings.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
      </variablelist>
     </para>
  
-- 
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