diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index b290b7477b1db005fd3f37185cff6caf198b2e57..47a1493c7aaf7840a5669f6d771540aadd51c75f 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -4,7 +4,7 @@
  * A simple benchmark program for PostgreSQL
  * Originally written by Tatsuo Ishii and enhanced by many contributors.
  *
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.97 2010/02/26 02:00:32 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.98 2010/03/23 01:29:22 itagaki Exp $
  * Copyright (c) 2000-2010, PostgreSQL Global Development Group
  * ALL RIGHTS RESERVED;
  *
@@ -131,11 +131,9 @@ int			fillfactor = 100;
 #define ntellers	10
 #define naccounts	100000
 
-FILE	   *LOGFILE = NULL;
-
 bool		use_log;			/* log transaction latencies to a file */
-
-int			is_connect;			/* establish connection for each transaction */
+bool		is_connect;			/* establish connection for each transaction */
+int			main_pid;			/* main process id used in log filename */
 
 char	   *pghost = "";
 char	   *pgport = "";
@@ -183,6 +181,7 @@ typedef struct
  */
 typedef struct
 {
+	int			tid;			/* thread id */
 	pthread_t	thread;			/* thread handle */
 	CState	   *state;			/* array of CState */
 	int			nstate;			/* length of state[] */
@@ -741,7 +740,7 @@ clientDone(CState *st, bool ok)
 
 /* return false iff client should be disconnected */
 static bool
-doCustom(CState *st, instr_time *conn_time)
+doCustom(CState *st, instr_time *conn_time, FILE *logfile)
 {
 	PGresult   *res;
 	Command   **commands;
@@ -778,7 +777,7 @@ top:
 		/*
 		 * transaction finished: record the time it took in the log
 		 */
-		if (use_log && commands[st->state + 1] == NULL)
+		if (logfile && commands[st->state + 1] == NULL)
 		{
 			instr_time	now;
 			instr_time	diff;
@@ -791,12 +790,12 @@ top:
 
 #ifndef WIN32
 			/* This is more than we really ought to know about instr_time */
-			fprintf(LOGFILE, "%d %d %.0f %d %ld %ld\n",
+			fprintf(logfile, "%d %d %.0f %d %ld %ld\n",
 					st->id, st->cnt, usec, st->use_file,
 					(long) now.tv_sec, (long) now.tv_usec);
 #else
 			/* On Windows, instr_time doesn't provide a timestamp anyway */
-			fprintf(LOGFILE, "%d %d %.0f %d 0 0\n",
+			fprintf(logfile, "%d %d %.0f %d 0 0\n",
 					st->id, st->cnt, usec, st->use_file);
 #endif
 		}
@@ -857,7 +856,7 @@ top:
 		INSTR_TIME_ACCUM_DIFF(*conn_time, end, start);
 	}
 
-	if (use_log && st->state == 0)
+	if (logfile && st->state == 0)
 		INSTR_TIME_SET_CURRENT(st->txn_begin);
 
 	if (commands[st->state]->type == SQL_COMMAND)
@@ -1833,7 +1832,7 @@ main(int argc, char **argv)
 				}
 				break;
 			case 'C':
-				is_connect = 1;
+				is_connect = true;
 				break;
 			case 's':
 				scale_given = true;
@@ -1955,6 +1954,12 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+	/*
+	 * save main process id in the global variable because process id will be
+	 * changed after fork.
+	 */
+	main_pid = (int) getpid();
+
 	if (nclients > 1)
 	{
 		state = (CState *) realloc(state, sizeof(CState) * nclients);
@@ -1980,20 +1985,6 @@ main(int argc, char **argv)
 		}
 	}
 
-	if (use_log)
-	{
-		char		logpath[64];
-
-		snprintf(logpath, 64, "pgbench_log.%d", (int) getpid());
-		LOGFILE = fopen(logpath, "w");
-
-		if (LOGFILE == NULL)
-		{
-			fprintf(stderr, "Couldn't open logfile \"%s\": %s", logpath, strerror(errno));
-			exit(1);
-		}
-	}
-
 	if (debug)
 	{
 		if (duration <= 0)
@@ -2111,6 +2102,7 @@ main(int argc, char **argv)
 	threads = (TState *) malloc(sizeof(TState) * nthreads);
 	for (i = 0; i < nthreads; i++)
 	{
+		threads[i].tid = i;
 		threads[i].state = &state[nclients / nthreads * i];
 		threads[i].nstate = nclients / nthreads;
 		INSTR_TIME_SET_CURRENT(threads[i].start_time);
@@ -2159,8 +2151,6 @@ main(int argc, char **argv)
 	INSTR_TIME_SET_CURRENT(total_time);
 	INSTR_TIME_SUBTRACT(total_time, start_time);
 	printResults(ttype, total_xacts, nclients, nthreads, total_time, conn_total_time);
-	if (LOGFILE)
-		fclose(LOGFILE);
 
 	return 0;
 }
@@ -2171,6 +2161,7 @@ threadRun(void *arg)
 	TState	   *thread = (TState *) arg;
 	CState	   *state = thread->state;
 	TResult    *result;
+	FILE	   *logfile = NULL;		/* per-thread log file */
 	instr_time	start,
 				end;
 	int			nstate = thread->nstate;
@@ -2180,7 +2171,25 @@ threadRun(void *arg)
 	result = malloc(sizeof(TResult));
 	INSTR_TIME_SET_ZERO(result->conn_time);
 
-	if (is_connect == 0)
+	/* open log file if requested */
+	if (use_log)
+	{
+		char		logpath[64];
+
+		if (thread->tid == 0)
+			snprintf(logpath, sizeof(logpath), "pgbench_log.%d", main_pid);
+		else
+			snprintf(logpath, sizeof(logpath), "pgbench_log.%d.%d", main_pid, thread->tid);
+		logfile = fopen(logpath, "w");
+
+		if (logfile == NULL)
+		{
+			fprintf(stderr, "Couldn't open logfile \"%s\": %s", logpath, strerror(errno));
+			goto done;
+		}
+	}
+
+	if (!is_connect)
 	{
 		/* make connections to the database */
 		for (i = 0; i < nstate; i++)
@@ -2202,7 +2211,7 @@ threadRun(void *arg)
 		int			prev_ecnt = st->ecnt;
 
 		st->use_file = getrand(0, num_files - 1);
-		if (!doCustom(st, &result->conn_time))
+		if (!doCustom(st, &result->conn_time, logfile))
 			remains--;			/* I've aborted */
 
 		if (st->ecnt > prev_ecnt && commands[st->state]->type == META_COMMAND)
@@ -2304,7 +2313,7 @@ threadRun(void *arg)
 			if (st->con && (FD_ISSET(PQsocket(st->con), &input_mask)
 							|| commands[st->state]->type == META_COMMAND))
 			{
-				if (!doCustom(st, &result->conn_time))
+				if (!doCustom(st, &result->conn_time, logfile))
 					remains--;	/* I've aborted */
 			}
 
@@ -2326,6 +2335,8 @@ done:
 		result->xacts += state[i].cnt;
 	INSTR_TIME_SET_CURRENT(end);
 	INSTR_TIME_ACCUM_DIFF(result->conn_time, end, start);
+	if (logfile)
+		fclose(logfile);
 	return result;
 }
 
diff --git a/doc/src/sgml/pgbench.sgml b/doc/src/sgml/pgbench.sgml
index fc967b59a650a2f6441a7c8f687690ca1c248453..cb94e30c01c7f2a156ea50bfbd9d8fce8c44c86c 100644
--- a/doc/src/sgml/pgbench.sgml
+++ b/doc/src/sgml/pgbench.sgml
@@ -1,630 +1,640 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.12 2009/12/15 15:59:57 tgl Exp $ -->
-
-<sect1 id="pgbench">
- <title>pgbench</title>
-
- <indexterm zone="pgbench">
-  <primary>pgbench</primary>
- </indexterm>
-
- <para>
-  <application>pgbench</application> is a simple program for running benchmark
-  tests on <productname>PostgreSQL</>.  It runs the same sequence of SQL
-  commands over and over, possibly in multiple concurrent database sessions,
-  and then calculates the average transaction rate (transactions per second).
-  By default, <application>pgbench</application> tests a scenario that is
-  loosely based on TPC-B, involving five <command>SELECT</>,
-  <command>UPDATE</>, and <command>INSERT</> commands per transaction.
-  However, it is easy to test other cases by writing your own transaction
-  script files.
- </para>
-
- <para>
-  Typical output from pgbench looks like:
-
- <programlisting>
-transaction type: TPC-B (sort of)
-scaling factor: 10
-query mode: simple
-number of clients: 10
-number of threads: 1
-number of transactions per client: 1000
-number of transactions actually processed: 10000/10000
-tps = 85.184871 (including connections establishing)
-tps = 85.296346 (excluding connections establishing)
- </programlisting>
-
-  The first six lines report some of the most important parameter
-  settings.  The next line reports the number of transactions completed
-  and intended (the latter being just the product of number of clients
-  and number of transactions per client); these will be equal unless the run
-  failed before completion.  The last two lines report the TPS rate,
-  figured with and without counting the time to start database sessions.
- </para>
-
- <sect2>
-  <title>Overview</title>
-
-  <para>
-   The default TPC-B-like transaction test requires specific tables to be
-   set up beforehand.  <application>pgbench</> should be invoked with
-   the <literal>-i</> (initialize) option to create and populate these
-   tables.  (When you are testing a custom script, you don't need this
-   step, but will instead need to do whatever setup your test needs.)
-   Initialization looks like:
-
-   <programlisting>
-pgbench -i <optional> <replaceable>other-options</> </optional> <replaceable>dbname</>
-   </programlisting>
-
-   where <replaceable>dbname</> is the name of the already-created
-   database to test in.  (You may also need <literal>-h</>,
-   <literal>-p</>, and/or <literal>-U</> options to specify how to
-   connect to the database server.)
-  </para>
-
-  <caution>
-   <para>
-    <literal>pgbench -i</> creates four tables <structname>pgbench_accounts</>,
-    <structname>pgbench_branches</>, <structname>pgbench_history</>, and
-    <structname>pgbench_tellers</>,
-    destroying any existing tables of these names.
-    Be very careful to use another database if you have tables having these
-    names!
-   </para>
-  </caution>
-
-  <para>
-   At the default <quote>scale factor</> of 1, the tables initially
-   contain this many rows:
-  </para>
-  <programlisting>
-table                   # of rows
----------------------------------
-pgbench_branches        1
-pgbench_tellers         10
-pgbench_accounts        100000
-pgbench_history         0
-  </programlisting>
-  <para>
-   You can (and, for most purposes, probably should) increase the number
-   of rows by using the <literal>-s</> (scale factor) option.  The
-   <literal>-F</> (fillfactor) option might also be used at this point.
-  </para>
-
-  <para>
-   Once you have done the necessary setup, you can run your benchmark
-   with a command that doesn't include <literal>-i</>, that is
-
-   <programlisting>
-pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
-   </programlisting>
-
-   In nearly all cases, you'll need some options to make a useful test.
-   The most important options are <literal>-c</> (number of clients),
-   <literal>-t</> (number of transactions), <literal>-T</> (time limit),
-   and <literal>-f</> (specify a custom script file).
-   See below for a full list.
-  </para>
-
-  <para>
-   <xref linkend="pgbench-init-options"> shows options that are used
-   during database initialization, while
-   <xref linkend="pgbench-run-options"> shows options that are used
-   while running benchmarks, and
-   <xref linkend="pgbench-common-options"> shows options that are useful
-   in both cases.
-  </para>
-
-  <table id="pgbench-init-options">
-   <title><application>pgbench</application> initialization options</title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry>Option</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>-i</literal></entry>
-      <entry>
-       Required to invoke initialization mode.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-s</literal> <replaceable>scale_factor</></entry>
-      <entry>
-       Multiply the number of rows generated by the scale factor.
-       For example, <literal>-s 100</> will create 10,000,000 rows
-       in the <structname>pgbench_accounts</> table. Default is 1.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-F</literal> <replaceable>fillfactor</></entry>
-      <entry>
-       Create the <structname>pgbench_accounts</>,
-       <structname>pgbench_tellers</> and
-       <structname>pgbench_branches</> tables with the given fillfactor.
-       Default is 100.
-      </entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="pgbench-run-options">
-   <title><application>pgbench</application> benchmarking options</title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry>Option</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>-c</literal> <replaceable>clients</></entry>
-      <entry>
-       Number of clients simulated, that is, number of concurrent database
-       sessions.  Default is 1.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-j</literal> <replaceable>threads</></entry>
-      <entry>
-       Number of worker threads within <application>pgbench</application>.
-       Using more than one thread can be helpful on multi-CPU machines.
-       The number of clients must be a multiple of the number of threads,
-       since each thread is given the same number of client sessions to manage.
-       Default is 1.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-t</literal> <replaceable>transactions</></entry>
-      <entry>
-       Number of transactions each client runs.  Default is 10.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-T</literal> <replaceable>seconds</></entry>
-      <entry>
-       Run the test for this many seconds, rather than a fixed number of
-       transactions per client. <literal>-t</literal> and
-       <literal>-T</literal> are mutually exclusive.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-M</literal> <replaceable>querymode</></entry>
-      <entry>
-       Protocol to use for submitting queries to the server:
-         <itemizedlist>
-          <listitem>
-           <para><literal>simple</>: use simple query protocol.</para>
-          </listitem>
-          <listitem>
-           <para><literal>extended</>: use extended query protocol.</para>
-          </listitem>
-          <listitem>
-           <para><literal>prepared</>: use extended query protocol with prepared statements.</para>
-          </listitem>
-         </itemizedlist>
-       The default is simple query protocol.  (See <xref linkend="protocol">
-       for more information.)
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-N</literal></entry>
-      <entry>
-       Do not update <structname>pgbench_tellers</> and
-       <structname>pgbench_branches</>.
-       This will avoid update contention on these tables, but
-       it makes the test case even less like TPC-B.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-S</literal></entry>
-      <entry>
-       Perform select-only transactions instead of TPC-B-like test.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-f</literal> <replaceable>filename</></entry>
-      <entry>
-       Read transaction script from <replaceable>filename</>.
-       See below for details.
-       <literal>-N</literal>, <literal>-S</literal>, and <literal>-f</literal>
-       are mutually exclusive.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-n</literal></entry>
-      <entry>
-       Perform no vacuuming before running the test.
-       This option is <emphasis>necessary</>
-       if you are running a custom test scenario that does not include
-       the standard tables <structname>pgbench_accounts</>,
-       <structname>pgbench_branches</>, <structname>pgbench_history</>, and
-       <structname>pgbench_tellers</>.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-v</literal></entry>
-      <entry>
-       Vacuum all four standard tables before running the test.
-       With neither <literal>-n</> nor <literal>-v</>, pgbench will vacuum the
-       <structname>pgbench_tellers</> and <structname>pgbench_branches</>
-       tables, and will truncate <structname>pgbench_history</>.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-D</literal> <replaceable>varname</><literal>=</><replaceable>value</></entry>
-      <entry>
-       Define a variable for use by a custom script (see below).
-       Multiple <literal>-D</> options are allowed.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-C</literal></entry>
-      <entry>
-       Establish a new connection for each transaction, rather than
-       doing it just once per client session.
-       This is useful to measure the connection overhead.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-l</literal></entry>
-      <entry>
-       Write the time taken by each transaction to a logfile.
-       See below for details.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-s</literal> <replaceable>scale_factor</></entry>
-      <entry>
-       Report the specified scale factor in <application>pgbench</>'s
-       output.  With the built-in tests, this is not necessary; the
-       correct scale factor will be detected by counting the number of
-       rows in the <structname>pgbench_branches</> table.  However, when testing
-       custom benchmarks (<literal>-f</> option), the scale factor
-       will be reported as 1 unless this option is used.
-      </entry>
-     </row>
-     <row>
-      <entry><literal>-d</literal></entry>
-      <entry>
-       Print debugging output.
-      </entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="pgbench-common-options">
-   <title><application>pgbench</application> common options</title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry>Option</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>-h</literal> <replaceable>hostname</></entry>
-      <entry>database server's host</entry>
-     </row>
-     <row>
-      <entry><literal>-p</literal> <replaceable>port</></entry>
-      <entry>database server's port</entry>
-     </row>
-     <row>
-      <entry><literal>-U</literal> <replaceable>login</></entry>
-      <entry>username to connect as</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
- </sect2>
-
- <sect2>
-  <title>What is the <quote>transaction</> actually performed in pgbench?</title>
-
-  <para>
-   The default transaction script issues seven commands per transaction:
-  </para>
-
-  <orderedlist>
-   <listitem><para><literal>BEGIN;</literal></para></listitem>
-   <listitem><para><literal>UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;</literal></para></listitem>
-   <listitem><para><literal>SELECT abalance FROM pgbench_accounts WHERE aid = :aid;</literal></para></listitem>
-   <listitem><para><literal>UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;</literal></para></listitem>
-   <listitem><para><literal>UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;</literal></para></listitem>
-   <listitem><para><literal>INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);</literal></para></listitem>
-   <listitem><para><literal>END;</literal></para></listitem>
-  </orderedlist>
-
-  <para>
-   If you specify <literal>-N</>, steps 4 and 5 aren't included in the
-   transaction.  If you specify <literal>-S</>, only the <command>SELECT</> is
-   issued.
-  </para>
- </sect2>
-
- <sect2>
-  <title>Custom Scripts</title>
-
-  <para>
-   <application>pgbench</application> has support for running custom
-   benchmark scenarios by replacing the default transaction script
-   (described above) with a transaction script read from a file
-   (<literal>-f</literal> option).  In this case a <quote>transaction</>
-   counts as one execution of a script file.  You can even specify
-   multiple scripts (multiple <literal>-f</literal> options), in which
-   case a random one of the scripts is chosen each time a client session
-   starts a new transaction.
-  </para>
-
-  <para>
-   The format of a script file is one SQL command per line; multi-line
-   SQL commands are not supported.  Empty lines and lines beginning with
-   <literal>--</> are ignored.  Script file lines can also be
-   <quote>meta commands</>, which are interpreted by <application>pgbench</>
-   itself, as described below.
-  </para>
-
-  <para>
-   There is a simple variable-substitution facility for script files.
-   Variables can be set by the command-line <literal>-D</> option,
-   explained above, or by the meta commands explained below.
-   In addition to any variables preset by <literal>-D</> command-line options,
-   the variable <literal>scale</> is preset to the current scale factor.
-   Once set, a variable's
-   value can be inserted into a SQL command by writing
-   <literal>:</><replaceable>variablename</>.  When running more than
-   one client session, each session has its own set of variables.
-  </para>
-
-  <para>
-   Script file meta commands begin with a backslash (<literal>\</>).
-   Arguments to a meta command are separated by white space.
-   These meta commands are supported:
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <literal>\set <replaceable>varname</> <replaceable>operand1</> [ <replaceable>operator</> <replaceable>operand2</> ]</literal>
-    </term>
-
-    <listitem>
-     <para>
-      Sets variable <replaceable>varname</> to a calculated integer value.
-      Each <replaceable>operand</> is either an integer constant or a
-      <literal>:</><replaceable>variablename</> reference to a variable
-      having an integer value.  The <replaceable>operator</> can be
-      <literal>+</>, <literal>-</>, <literal>*</>, or <literal>/</>.
-     </para>
-
-     <para>
-      Example:
-      <programlisting>
-\set ntellers 10 * :scale
-      </programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>
-     <literal>\setrandom <replaceable>varname</> <replaceable>min</> <replaceable>max</></literal>
-    </term>
-
-    <listitem>
-     <para>
-      Sets variable <replaceable>varname</> to a random integer value
-      between the limits <replaceable>min</> and <replaceable>max</> inclusive.
-      Each limit can be either an integer constant or a
-      <literal>:</><replaceable>variablename</> reference to a variable
-      having an integer value.
-     </para>
-
-     <para>
-      Example:
-      <programlisting>
-\setrandom aid 1 :naccounts
-      </programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>
-     <literal>\sleep <replaceable>number</> [ us | ms | s ]</literal>
-    </term>
-
-    <listitem>
-     <para>
-      Causes script execution to sleep for the specified duration in
-      microseconds (<literal>us</>), milliseconds (<literal>ms</>) or seconds
-      (<literal>s</>).  If the unit is omitted then seconds are the default.
-      <replaceable>number</> can be either an integer constant or a
-      <literal>:</><replaceable>variablename</> reference to a variable
-      having an integer value.
-     </para>
-
-     <para>
-      Example:
-      <programlisting>
-\sleep 10 ms
-      </programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>
-     <literal>\setshell <replaceable>varname</> <replaceable>command</> [ <replaceable>argument</> ... ]</literal>
-    </term>
-
-    <listitem>
-     <para>
-      Sets variable <replaceable>varname</> to the result of the shell command
-      <replaceable>command</>. The command must return an integer value
-      through its standard output.
-     </para>
-
-     <para>
-      <replaceable>argument</> can be either a text constant or a
-      <literal>:</><replaceable>variablename</> reference to a variable of
-      any types. If you want to use <replaceable>argument</> starting with
-      colons, you need to add an additional colon at the beginning of
-      <replaceable>argument</>.
-     </para>
-
-     <para>
-      Example:
-      <programlisting>
-\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
-      </programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>
-     <literal>\shell <replaceable>command</> [ <replaceable>argument</> ... ]</literal>
-    </term>
-
-    <listitem>
-     <para>
-      Same as <literal>\setshell</literal>, but the result is ignored.
-     </para>
-
-     <para>
-      Example:
-      <programlisting>
-\shell command literal_argument :variable ::literal_starting_with_colon
-      </programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <para>
-   As an example, the full definition of the built-in TPC-B-like
-   transaction is:
-
-   <programlisting>
-\set nbranches :scale
-\set ntellers 10 * :scale
-\set naccounts 100000 * :scale
-\setrandom aid 1 :naccounts
-\setrandom bid 1 :nbranches
-\setrandom tid 1 :ntellers
-\setrandom delta -5000 5000
-BEGIN;
-UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
-SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
-UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
-UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
-INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
-END;
-   </programlisting>
-
-   This script allows each iteration of the transaction to reference
-   different, randomly-chosen rows.  (This example also shows why it's
-   important for each client session to have its own variables &mdash;
-   otherwise they'd not be independently touching different rows.)
-  </para>
-
- </sect2>
-
- <sect2>
-  <title>Per-transaction logging</title>
-
-  <para>
-   With the <literal>-l</> option, <application>pgbench</> writes the time
-   taken by each transaction to a logfile.  The logfile will be named
-   <filename>pgbench_log.<replaceable>nnn</></filename>, where
-   <replaceable>nnn</> is the PID of the pgbench process.
-   The format of the log is:
-
-   <programlisting>
-    <replaceable>client_id</> <replaceable>transaction_no</> <replaceable>time</> <replaceable>file_no</> <replaceable>time_epoch</> <replaceable>time_us</>
-   </programlisting>
-
-   where <replaceable>time</> is the elapsed transaction time in microseconds,
-   <replaceable>file_no</> identifies which script file was used
-   (useful when multiple scripts were specified with <literal>-f</>),
-   and <replaceable>time_epoch</>/<replaceable>time_us</> are a
-   UNIX epoch format timestamp and an offset
-   in microseconds (suitable for creating a ISO 8601
-   timestamp with fractional seconds) showing when
-   the transaction completed.
-  </para>
-
-  <para>
-   Here are example outputs:
-   <programlisting>
- 0 199 2241 0 1175850568 995598
- 0 200 2465 0 1175850568 998079
- 0 201 2513 0 1175850569 608
- 0 202 2038 0 1175850569 2663
-   </programlisting>
-  </para>
- </sect2>
-
- <sect2>
-  <title>Good Practices</title>
-
-  <para>
-   It is very easy to use <application>pgbench</> to produce completely
-   meaningless numbers.  Here are some guidelines to help you get useful
-   results.
-  </para>
-
-  <para>
-   In the first place, <emphasis>never</> believe any test that runs
-   for only a few seconds.  Use the <literal>-t</> or <literal>-T</> option
-   to make the run last at least a few minutes, so as to average out noise.
-   In some cases you could need hours to get numbers that are reproducible.
-   It's a good idea to try the test run a few times, to find out if your
-   numbers are reproducible or not.
-  </para>
-
-  <para>
-   For the default TPC-B-like test scenario, the initialization scale factor
-   (<literal>-s</>) should be at least as large as the largest number of
-   clients you intend to test (<literal>-c</>); else you'll mostly be
-   measuring update contention.  There are only <literal>-s</> rows in
-   the <structname>pgbench_branches</> table, and every transaction wants to
-   update one of them, so <literal>-c</> values in excess of <literal>-s</>
-   will undoubtedly result in lots of transactions blocked waiting for
-   other transactions.
-  </para>
-
-  <para>
-   The default test scenario is also quite sensitive to how long it's been
-   since the tables were initialized: accumulation of dead rows and dead space
-   in the tables changes the results.  To understand the results you must keep
-   track of the total number of updates and when vacuuming happens.  If
-   autovacuum is enabled it can result in unpredictable changes in measured
-   performance.
-  </para>
-
-  <para>
-   A limitation of <application>pgbench</> is that it can itself become
-   the bottleneck when trying to test a large number of client sessions.
-   This can be alleviated by running <application>pgbench</> on a different
-   machine from the database server, although low network latency will be
-   essential.  It might even be useful to run several <application>pgbench</>
-   instances concurrently, on several client machines, against the same
-   database server.
-  </para>
- </sect2>
-
-</sect1>
+<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.13 2010/03/23 01:29:22 itagaki Exp $ -->
+
+<sect1 id="pgbench">
+ <title>pgbench</title>
+
+ <indexterm zone="pgbench">
+  <primary>pgbench</primary>
+ </indexterm>
+
+ <para>
+  <application>pgbench</application> is a simple program for running benchmark
+  tests on <productname>PostgreSQL</>.  It runs the same sequence of SQL
+  commands over and over, possibly in multiple concurrent database sessions,
+  and then calculates the average transaction rate (transactions per second).
+  By default, <application>pgbench</application> tests a scenario that is
+  loosely based on TPC-B, involving five <command>SELECT</>,
+  <command>UPDATE</>, and <command>INSERT</> commands per transaction.
+  However, it is easy to test other cases by writing your own transaction
+  script files.
+ </para>
+
+ <para>
+  Typical output from pgbench looks like:
+
+ <programlisting>
+transaction type: TPC-B (sort of)
+scaling factor: 10
+query mode: simple
+number of clients: 10
+number of threads: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+tps = 85.184871 (including connections establishing)
+tps = 85.296346 (excluding connections establishing)
+ </programlisting>
+
+  The first six lines report some of the most important parameter
+  settings.  The next line reports the number of transactions completed
+  and intended (the latter being just the product of number of clients
+  and number of transactions per client); these will be equal unless the run
+  failed before completion.  The last two lines report the TPS rate,
+  figured with and without counting the time to start database sessions.
+ </para>
+
+ <sect2>
+  <title>Overview</title>
+
+  <para>
+   The default TPC-B-like transaction test requires specific tables to be
+   set up beforehand.  <application>pgbench</> should be invoked with
+   the <literal>-i</> (initialize) option to create and populate these
+   tables.  (When you are testing a custom script, you don't need this
+   step, but will instead need to do whatever setup your test needs.)
+   Initialization looks like:
+
+   <programlisting>
+pgbench -i <optional> <replaceable>other-options</> </optional> <replaceable>dbname</>
+   </programlisting>
+
+   where <replaceable>dbname</> is the name of the already-created
+   database to test in.  (You may also need <literal>-h</>,
+   <literal>-p</>, and/or <literal>-U</> options to specify how to
+   connect to the database server.)
+  </para>
+
+  <caution>
+   <para>
+    <literal>pgbench -i</> creates four tables <structname>pgbench_accounts</>,
+    <structname>pgbench_branches</>, <structname>pgbench_history</>, and
+    <structname>pgbench_tellers</>,
+    destroying any existing tables of these names.
+    Be very careful to use another database if you have tables having these
+    names!
+   </para>
+  </caution>
+
+  <para>
+   At the default <quote>scale factor</> of 1, the tables initially
+   contain this many rows:
+  </para>
+  <programlisting>
+table                   # of rows
+---------------------------------
+pgbench_branches        1
+pgbench_tellers         10
+pgbench_accounts        100000
+pgbench_history         0
+  </programlisting>
+  <para>
+   You can (and, for most purposes, probably should) increase the number
+   of rows by using the <literal>-s</> (scale factor) option.  The
+   <literal>-F</> (fillfactor) option might also be used at this point.
+  </para>
+
+  <para>
+   Once you have done the necessary setup, you can run your benchmark
+   with a command that doesn't include <literal>-i</>, that is
+
+   <programlisting>
+pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
+   </programlisting>
+
+   In nearly all cases, you'll need some options to make a useful test.
+   The most important options are <literal>-c</> (number of clients),
+   <literal>-t</> (number of transactions), <literal>-T</> (time limit),
+   and <literal>-f</> (specify a custom script file).
+   See below for a full list.
+  </para>
+
+  <para>
+   <xref linkend="pgbench-init-options"> shows options that are used
+   during database initialization, while
+   <xref linkend="pgbench-run-options"> shows options that are used
+   while running benchmarks, and
+   <xref linkend="pgbench-common-options"> shows options that are useful
+   in both cases.
+  </para>
+
+  <table id="pgbench-init-options">
+   <title><application>pgbench</application> initialization options</title>
+   <tgroup cols="2">
+    <thead>
+     <row>
+      <entry>Option</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry><literal>-i</literal></entry>
+      <entry>
+       Required to invoke initialization mode.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-s</literal> <replaceable>scale_factor</></entry>
+      <entry>
+       Multiply the number of rows generated by the scale factor.
+       For example, <literal>-s 100</> will create 10,000,000 rows
+       in the <structname>pgbench_accounts</> table. Default is 1.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-F</literal> <replaceable>fillfactor</></entry>
+      <entry>
+       Create the <structname>pgbench_accounts</>,
+       <structname>pgbench_tellers</> and
+       <structname>pgbench_branches</> tables with the given fillfactor.
+       Default is 100.
+      </entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+
+  <table id="pgbench-run-options">
+   <title><application>pgbench</application> benchmarking options</title>
+   <tgroup cols="2">
+    <thead>
+     <row>
+      <entry>Option</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry><literal>-c</literal> <replaceable>clients</></entry>
+      <entry>
+       Number of clients simulated, that is, number of concurrent database
+       sessions.  Default is 1.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-j</literal> <replaceable>threads</></entry>
+      <entry>
+       Number of worker threads within <application>pgbench</application>.
+       Using more than one thread can be helpful on multi-CPU machines.
+       The number of clients must be a multiple of the number of threads,
+       since each thread is given the same number of client sessions to manage.
+       Default is 1.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-t</literal> <replaceable>transactions</></entry>
+      <entry>
+       Number of transactions each client runs.  Default is 10.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-T</literal> <replaceable>seconds</></entry>
+      <entry>
+       Run the test for this many seconds, rather than a fixed number of
+       transactions per client. <literal>-t</literal> and
+       <literal>-T</literal> are mutually exclusive.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-M</literal> <replaceable>querymode</></entry>
+      <entry>
+       Protocol to use for submitting queries to the server:
+         <itemizedlist>
+          <listitem>
+           <para><literal>simple</>: use simple query protocol.</para>
+          </listitem>
+          <listitem>
+           <para><literal>extended</>: use extended query protocol.</para>
+          </listitem>
+          <listitem>
+           <para><literal>prepared</>: use extended query protocol with prepared statements.</para>
+          </listitem>
+         </itemizedlist>
+       The default is simple query protocol.  (See <xref linkend="protocol">
+       for more information.)
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-N</literal></entry>
+      <entry>
+       Do not update <structname>pgbench_tellers</> and
+       <structname>pgbench_branches</>.
+       This will avoid update contention on these tables, but
+       it makes the test case even less like TPC-B.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-S</literal></entry>
+      <entry>
+       Perform select-only transactions instead of TPC-B-like test.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-f</literal> <replaceable>filename</></entry>
+      <entry>
+       Read transaction script from <replaceable>filename</>.
+       See below for details.
+       <literal>-N</literal>, <literal>-S</literal>, and <literal>-f</literal>
+       are mutually exclusive.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-n</literal></entry>
+      <entry>
+       Perform no vacuuming before running the test.
+       This option is <emphasis>necessary</>
+       if you are running a custom test scenario that does not include
+       the standard tables <structname>pgbench_accounts</>,
+       <structname>pgbench_branches</>, <structname>pgbench_history</>, and
+       <structname>pgbench_tellers</>.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-v</literal></entry>
+      <entry>
+       Vacuum all four standard tables before running the test.
+       With neither <literal>-n</> nor <literal>-v</>, pgbench will vacuum the
+       <structname>pgbench_tellers</> and <structname>pgbench_branches</>
+       tables, and will truncate <structname>pgbench_history</>.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-D</literal> <replaceable>varname</><literal>=</><replaceable>value</></entry>
+      <entry>
+       Define a variable for use by a custom script (see below).
+       Multiple <literal>-D</> options are allowed.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-C</literal></entry>
+      <entry>
+       Establish a new connection for each transaction, rather than
+       doing it just once per client session.
+       This is useful to measure the connection overhead.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-l</literal></entry>
+      <entry>
+       Write the time taken by each transaction to a logfile.
+       See below for details.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-s</literal> <replaceable>scale_factor</></entry>
+      <entry>
+       Report the specified scale factor in <application>pgbench</>'s
+       output.  With the built-in tests, this is not necessary; the
+       correct scale factor will be detected by counting the number of
+       rows in the <structname>pgbench_branches</> table.  However, when testing
+       custom benchmarks (<literal>-f</> option), the scale factor
+       will be reported as 1 unless this option is used.
+      </entry>
+     </row>
+     <row>
+      <entry><literal>-d</literal></entry>
+      <entry>
+       Print debugging output.
+      </entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+
+  <table id="pgbench-common-options">
+   <title><application>pgbench</application> common options</title>
+   <tgroup cols="2">
+    <thead>
+     <row>
+      <entry>Option</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry><literal>-h</literal> <replaceable>hostname</></entry>
+      <entry>database server's host</entry>
+     </row>
+     <row>
+      <entry><literal>-p</literal> <replaceable>port</></entry>
+      <entry>database server's port</entry>
+     </row>
+     <row>
+      <entry><literal>-U</literal> <replaceable>login</></entry>
+      <entry>username to connect as</entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+ </sect2>
+
+ <sect2>
+  <title>What is the <quote>transaction</> actually performed in pgbench?</title>
+
+  <para>
+   The default transaction script issues seven commands per transaction:
+  </para>
+
+  <orderedlist>
+   <listitem><para><literal>BEGIN;</literal></para></listitem>
+   <listitem><para><literal>UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;</literal></para></listitem>
+   <listitem><para><literal>SELECT abalance FROM pgbench_accounts WHERE aid = :aid;</literal></para></listitem>
+   <listitem><para><literal>UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;</literal></para></listitem>
+   <listitem><para><literal>UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;</literal></para></listitem>
+   <listitem><para><literal>INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);</literal></para></listitem>
+   <listitem><para><literal>END;</literal></para></listitem>
+  </orderedlist>
+
+  <para>
+   If you specify <literal>-N</>, steps 4 and 5 aren't included in the
+   transaction.  If you specify <literal>-S</>, only the <command>SELECT</> is
+   issued.
+  </para>
+ </sect2>
+
+ <sect2>
+  <title>Custom Scripts</title>
+
+  <para>
+   <application>pgbench</application> has support for running custom
+   benchmark scenarios by replacing the default transaction script
+   (described above) with a transaction script read from a file
+   (<literal>-f</literal> option).  In this case a <quote>transaction</>
+   counts as one execution of a script file.  You can even specify
+   multiple scripts (multiple <literal>-f</literal> options), in which
+   case a random one of the scripts is chosen each time a client session
+   starts a new transaction.
+  </para>
+
+  <para>
+   The format of a script file is one SQL command per line; multi-line
+   SQL commands are not supported.  Empty lines and lines beginning with
+   <literal>--</> are ignored.  Script file lines can also be
+   <quote>meta commands</>, which are interpreted by <application>pgbench</>
+   itself, as described below.
+  </para>
+
+  <para>
+   There is a simple variable-substitution facility for script files.
+   Variables can be set by the command-line <literal>-D</> option,
+   explained above, or by the meta commands explained below.
+   In addition to any variables preset by <literal>-D</> command-line options,
+   the variable <literal>scale</> is preset to the current scale factor.
+   Once set, a variable's
+   value can be inserted into a SQL command by writing
+   <literal>:</><replaceable>variablename</>.  When running more than
+   one client session, each session has its own set of variables.
+  </para>
+
+  <para>
+   Script file meta commands begin with a backslash (<literal>\</>).
+   Arguments to a meta command are separated by white space.
+   These meta commands are supported:
+  </para>
+
+  <variablelist>
+   <varlistentry>
+    <term>
+     <literal>\set <replaceable>varname</> <replaceable>operand1</> [ <replaceable>operator</> <replaceable>operand2</> ]</literal>
+    </term>
+
+    <listitem>
+     <para>
+      Sets variable <replaceable>varname</> to a calculated integer value.
+      Each <replaceable>operand</> is either an integer constant or a
+      <literal>:</><replaceable>variablename</> reference to a variable
+      having an integer value.  The <replaceable>operator</> can be
+      <literal>+</>, <literal>-</>, <literal>*</>, or <literal>/</>.
+     </para>
+
+     <para>
+      Example:
+      <programlisting>
+\set ntellers 10 * :scale
+      </programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>
+     <literal>\setrandom <replaceable>varname</> <replaceable>min</> <replaceable>max</></literal>
+    </term>
+
+    <listitem>
+     <para>
+      Sets variable <replaceable>varname</> to a random integer value
+      between the limits <replaceable>min</> and <replaceable>max</> inclusive.
+      Each limit can be either an integer constant or a
+      <literal>:</><replaceable>variablename</> reference to a variable
+      having an integer value.
+     </para>
+
+     <para>
+      Example:
+      <programlisting>
+\setrandom aid 1 :naccounts
+      </programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>
+     <literal>\sleep <replaceable>number</> [ us | ms | s ]</literal>
+    </term>
+
+    <listitem>
+     <para>
+      Causes script execution to sleep for the specified duration in
+      microseconds (<literal>us</>), milliseconds (<literal>ms</>) or seconds
+      (<literal>s</>).  If the unit is omitted then seconds are the default.
+      <replaceable>number</> can be either an integer constant or a
+      <literal>:</><replaceable>variablename</> reference to a variable
+      having an integer value.
+     </para>
+
+     <para>
+      Example:
+      <programlisting>
+\sleep 10 ms
+      </programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>
+     <literal>\setshell <replaceable>varname</> <replaceable>command</> [ <replaceable>argument</> ... ]</literal>
+    </term>
+
+    <listitem>
+     <para>
+      Sets variable <replaceable>varname</> to the result of the shell command
+      <replaceable>command</>. The command must return an integer value
+      through its standard output.
+     </para>
+
+     <para>
+      <replaceable>argument</> can be either a text constant or a
+      <literal>:</><replaceable>variablename</> reference to a variable of
+      any types. If you want to use <replaceable>argument</> starting with
+      colons, you need to add an additional colon at the beginning of
+      <replaceable>argument</>.
+     </para>
+
+     <para>
+      Example:
+      <programlisting>
+\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
+      </programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>
+     <literal>\shell <replaceable>command</> [ <replaceable>argument</> ... ]</literal>
+    </term>
+
+    <listitem>
+     <para>
+      Same as <literal>\setshell</literal>, but the result is ignored.
+     </para>
+
+     <para>
+      Example:
+      <programlisting>
+\shell command literal_argument :variable ::literal_starting_with_colon
+      </programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+  <para>
+   As an example, the full definition of the built-in TPC-B-like
+   transaction is:
+
+   <programlisting>
+\set nbranches :scale
+\set ntellers 10 * :scale
+\set naccounts 100000 * :scale
+\setrandom aid 1 :naccounts
+\setrandom bid 1 :nbranches
+\setrandom tid 1 :ntellers
+\setrandom delta -5000 5000
+BEGIN;
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+END;
+   </programlisting>
+
+   This script allows each iteration of the transaction to reference
+   different, randomly-chosen rows.  (This example also shows why it's
+   important for each client session to have its own variables &mdash;
+   otherwise they'd not be independently touching different rows.)
+  </para>
+
+ </sect2>
+
+ <sect2>
+  <title>Per-transaction logging</title>
+
+  <para>
+   With the <literal>-l</> option, <application>pgbench</> writes the time
+   taken by each transaction to a logfile.  The logfile will be named
+   <filename>pgbench_log.<replaceable>nnn</></filename>, where
+   <replaceable>nnn</> is the PID of the pgbench process.
+   If the <literal>-j</> option is 2 or higher, creating multiple worker
+   threads, each will have its own log file. The first worker will use the
+   the same name for its log file as in the standard single worker case.  
+   The additional log files for the other workers will be named
+   <filename>pgbench_log.<replaceable>nnn</>.<replaceable>mmm</></filename>,
+   where <replaceable>mmm</> is a sequential number for each worker starting
+   with 1.
+  </para>
+
+  <para>
+   The format of the log is:
+
+   <programlisting>
+    <replaceable>client_id</> <replaceable>transaction_no</> <replaceable>time</> <replaceable>file_no</> <replaceable>time_epoch</> <replaceable>time_us</>
+   </programlisting>
+
+   where <replaceable>time</> is the elapsed transaction time in microseconds,
+   <replaceable>file_no</> identifies which script file was used
+   (useful when multiple scripts were specified with <literal>-f</>),
+   and <replaceable>time_epoch</>/<replaceable>time_us</> are a
+   UNIX epoch format timestamp and an offset
+   in microseconds (suitable for creating a ISO 8601
+   timestamp with fractional seconds) showing when
+   the transaction completed.
+  </para>
+
+  <para>
+   Here are example outputs:
+   <programlisting>
+ 0 199 2241 0 1175850568 995598
+ 0 200 2465 0 1175850568 998079
+ 0 201 2513 0 1175850569 608
+ 0 202 2038 0 1175850569 2663
+   </programlisting>
+  </para>
+ </sect2>
+
+ <sect2>
+  <title>Good Practices</title>
+
+  <para>
+   It is very easy to use <application>pgbench</> to produce completely
+   meaningless numbers.  Here are some guidelines to help you get useful
+   results.
+  </para>
+
+  <para>
+   In the first place, <emphasis>never</> believe any test that runs
+   for only a few seconds.  Use the <literal>-t</> or <literal>-T</> option
+   to make the run last at least a few minutes, so as to average out noise.
+   In some cases you could need hours to get numbers that are reproducible.
+   It's a good idea to try the test run a few times, to find out if your
+   numbers are reproducible or not.
+  </para>
+
+  <para>
+   For the default TPC-B-like test scenario, the initialization scale factor
+   (<literal>-s</>) should be at least as large as the largest number of
+   clients you intend to test (<literal>-c</>); else you'll mostly be
+   measuring update contention.  There are only <literal>-s</> rows in
+   the <structname>pgbench_branches</> table, and every transaction wants to
+   update one of them, so <literal>-c</> values in excess of <literal>-s</>
+   will undoubtedly result in lots of transactions blocked waiting for
+   other transactions.
+  </para>
+
+  <para>
+   The default test scenario is also quite sensitive to how long it's been
+   since the tables were initialized: accumulation of dead rows and dead space
+   in the tables changes the results.  To understand the results you must keep
+   track of the total number of updates and when vacuuming happens.  If
+   autovacuum is enabled it can result in unpredictable changes in measured
+   performance.
+  </para>
+
+  <para>
+   A limitation of <application>pgbench</> is that it can itself become
+   the bottleneck when trying to test a large number of client sessions.
+   This can be alleviated by running <application>pgbench</> on a different
+   machine from the database server, although low network latency will be
+   essential.  It might even be useful to run several <application>pgbench</>
+   instances concurrently, on several client machines, against the same
+   database server.
+  </para>
+ </sect2>
+
+</sect1>