Each worker thread will have its own log file in pgbench to avoid interleaved
authorItagaki Takahiro
Tue, 23 Mar 2010 01:29:22 +0000 (01:29 +0000)
committerItagaki Takahiro
Tue, 23 Mar 2010 01:29:22 +0000 (01:29 +0000)
writes. The first worker still uses "pgbench_log." for the name, but
additional workers use "pgbench_log.." instead.

Reported by Greg Smith.

contrib/pgbench/pgbench.c
doc/src/sgml/pgbench.sgml

index b290b7477b1db005fd3f37185cff6caf198b2e57..47a1493c7aaf7840a5669f6d771540aadd51c75f 100644 (file)
@@ -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;
 }
 
index fc967b59a650a2f6441a7c8f687690ca1c248453..cb94e30c01c7f2a156ea50bfbd9d8fce8c44c86c 100644 (file)
-
-
-
pgbench
-
-  pgbench
-
-  pgbench is a simple program for running benchmark
-  tests on 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, pgbench tests a scenario that is
-  loosely based on TPC-B, involving five SELECT,
-  UPDATE, and INSERT commands per transaction.
-  However, it is easy to test other cases by writing your own transaction
-  script files.
-
-  Typical output from pgbench looks like:
-
-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)
-
-  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.
-
-  Overview
-
-  
-   The default TPC-B-like transaction test requires specific tables to be
-   set up beforehand.  pgbench should be invoked with
-   the -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:
-
-   
-pgbench -i  other-options  dbname
-   
-
-   where dbname is the name of the already-created
-   database to test in.  (You may also need -h,
-   -p, and/or -U options to specify how to
-   connect to the database server.)
-  
-
-  
-   
-    pgbench -i creates four tables pgbench_accounts,
-    pgbench_branches, pgbench_history, and
-    pgbench_tellers,
-    destroying any existing tables of these names.
-    Be very careful to use another database if you have tables having these
-    names!
-   
-  
-
-  
-   At the default scale factor of 1, the tables initially
-   contain this many rows:
-  
-  
-table                   # of rows
----------------------------------
-pgbench_branches        1
-pgbench_tellers         10
-pgbench_accounts        100000
-pgbench_history         0
-  
-  
-   You can (and, for most purposes, probably should) increase the number
-   of rows by using the -s (scale factor) option.  The
-   -F (fillfactor) option might also be used at this point.
-  
-
-  
-   Once you have done the necessary setup, you can run your benchmark
-   with a command that doesn't include -i, that is
-
-   
-pgbench  options  dbname
-   
-
-   In nearly all cases, you'll need some options to make a useful test.
-   The most important options are -c (number of clients),
-   -t (number of transactions), -T (time limit),
-   and -f (specify a custom script file).
-   See below for a full list.
-  
-
-  
-    shows options that are used
-   during database initialization, while
-    shows options that are used
-   while running benchmarks, and
-    shows options that are useful
-   in both cases.
-  
-
-  
-   <application>pgbench</application> initialization options
-   
-    
-     
-      Option
-      Description
-     
-    
-
-    
-     
-      -i
-      
-       Required to invoke initialization mode.
-      
-     
-     
-      -s scale_factor
-      
-       Multiply the number of rows generated by the scale factor.
-       For example, -s 100 will create 10,000,000 rows
-       in the pgbench_accounts table. Default is 1.
-      
-     
-     
-      -F fillfactor
-      
-       Create the pgbench_accounts,
-       pgbench_tellers and
-       pgbench_branches tables with the given fillfactor.
-       Default is 100.
-      
-     
-    
-   
-  
-
-  
-   <application>pgbench</application> benchmarking options
-   
-    
-     
-      Option
-      Description
-     
-    
-
-    
-     
-      -c clients
-      
-       Number of clients simulated, that is, number of concurrent database
-       sessions.  Default is 1.
-      
-     
-     
-      -j threads
-      
-       Number of worker threads within pgbench.
-       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.
-      
-     
-     
-      -t transactions
-      
-       Number of transactions each client runs.  Default is 10.
-      
-     
-     
-      -T seconds
-      
-       Run the test for this many seconds, rather than a fixed number of
-       transactions per client. -t and
-       -T are mutually exclusive.
-      
-     
-     
-      -M querymode
-      
-       Protocol to use for submitting queries to the server:
-         
-          
-           simple: use simple query protocol.
-          
-          
-           extended: use extended query protocol.
-          
-          
-           prepared: use extended query protocol with prepared statements.
-          
-         
-       The default is simple query protocol.  (See 
-       for more information.)
-      
-     
-     
-      -N
-      
-       Do not update pgbench_tellers and
-       pgbench_branches.
-       This will avoid update contention on these tables, but
-       it makes the test case even less like TPC-B.
-      
-     
-     
-      -S
-      
-       Perform select-only transactions instead of TPC-B-like test.
-      
-     
-     
-      -f filename
-      
-       Read transaction script from filename.
-       See below for details.
-       -N-S, and -f
-       are mutually exclusive.
-      
-     
-     
-      -n
-      
-       Perform no vacuuming before running the test.
-       This option is necessary
-       if you are running a custom test scenario that does not include
-       the standard tables pgbench_accounts,
-       pgbench_branches, pgbench_history, and
-       pgbench_tellers.
-      
-     
-     
-      -v
-      
-       Vacuum all four standard tables before running the test.
-       With neither -n nor -v, pgbench will vacuum the
-       pgbench_tellers and pgbench_branches
-       tables, and will truncate pgbench_history.
-      
-     
-     
-      -D varname=value
-      
-       Define a variable for use by a custom script (see below).
-       Multiple -D options are allowed.
-      
-     
-     
-      -C
-      
-       Establish a new connection for each transaction, rather than
-       doing it just once per client session.
-       This is useful to measure the connection overhead.
-      
-     
-     
-      -l
-      
-       Write the time taken by each transaction to a logfile.
-       See below for details.
-      
-     
-     
-      -s scale_factor
-      
-       Report the specified scale factor in 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 pgbench_branches table.  However, when testing
-       custom benchmarks (-f option), the scale factor
-       will be reported as 1 unless this option is used.
-      
-     
-     
-      -d
-      
-       Print debugging output.
-      
-     
-    
-   
-  
-
-  
-   <application>pgbench</application> common options
-   
-    
-     
-      Option
-      Description
-     
-    
-
-    
-     
-      -h hostname
-      database server's host
-     
-     
-      -p port
-      database server's port
-     
-     
-      -U login
-      username to connect as
-     
-    
-   
-  
-
-  What is the <quote>transaction</> actually performed in pgbench?
-
-  
-   The default transaction script issues seven commands per transaction:
-  
-
-  
-   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;
-  
-
-  
-   If you specify -N, steps 4 and 5 aren't included in the
-   transaction.  If you specify -S, only the SELECT is
-   issued.
-  
-
-  Custom Scripts
-
-  
-   pgbench has support for running custom
-   benchmark scenarios by replacing the default transaction script
-   (described above) with a transaction script read from a file
-   (-f option).  In this case a transaction
-   counts as one execution of a script file.  You can even specify
-   multiple scripts (multiple -f options), in which
-   case a random one of the scripts is chosen each time a client session
-   starts a new transaction.
-  
-
-  
-   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
-   -- are ignored.  Script file lines can also be
-   meta commands, which are interpreted by pgbench
-   itself, as described below.
-  
-
-  
-   There is a simple variable-substitution facility for script files.
-   Variables can be set by the command-line -D option,
-   explained above, or by the meta commands explained below.
-   In addition to any variables preset by -D command-line options,
-   the variable scale is preset to the current scale factor.
-   Once set, a variable's
-   value can be inserted into a SQL command by writing
-   :variablename.  When running more than
-   one client session, each session has its own set of variables.
-  
-
-  
-   Script file meta commands begin with a backslash (\).
-   Arguments to a meta command are separated by white space.
-   These meta commands are supported:
-  
-
-  
-   
-    
-     \set varname operand1 [ operator operand2 ]
-    
-
-    
-     
-      Sets variable varname to a calculated integer value.
-      Each operand is either an integer constant or a
-      :variablename reference to a variable
-      having an integer value.  The operator can be
-      +, -, *, or /.
-     
-
-     
-      Example:
-      
-\set ntellers 10 * :scale
-      
-     
-    
-   
-
-   
-    
-     \setrandom varname min max
-    
-
-    
-     
-      Sets variable varname to a random integer value
-      between the limits min and max inclusive.
-      Each limit can be either an integer constant or a
-      :variablename reference to a variable
-      having an integer value.
-     
-
-     
-      Example:
-      
-\setrandom aid 1 :naccounts
-      
-     
-    
-   
-
-   
-    
-     \sleep number [ us | ms | s ]
-    
-
-    
-     
-      Causes script execution to sleep for the specified duration in
-      microseconds (us), milliseconds (ms) or seconds
-      (s).  If the unit is omitted then seconds are the default.
-      number can be either an integer constant or a
-      :variablename reference to a variable
-      having an integer value.
-     
-
-     
-      Example:
-      
-\sleep 10 ms
-      
-     
-    
-   
-
-   
-    
-     \setshell varname command [ argument ... ]
-    
-
-    
-     
-      Sets variable varname to the result of the shell command
-      command. The command must return an integer value
-      through its standard output.
-     
-
-     
-      argument can be either a text constant or a
-      :variablename reference to a variable of
-      any types. If you want to use argument starting with
-      colons, you need to add an additional colon at the beginning of
-      argument.
-     
-
-     
-      Example:
-      
-\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
-      
-     
-    
-   
-
-   
-    
-     \shell command [ argument ... ]
-    
-
-    
-     
-      Same as \setshell, but the result is ignored.
-     
-
-     
-      Example:
-      
-\shell command literal_argument :variable ::literal_starting_with_colon
-      
-     
-    
-   
-  
-
-  
-   As an example, the full definition of the built-in TPC-B-like
-   transaction is:
-
-   
-\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;
-   
-
-   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 —
-   otherwise they'd not be independently touching different rows.)
-  
-
-
-  Per-transaction logging
-
-  
-   With the -l option, pgbench writes the time
-   taken by each transaction to a logfile.  The logfile will be named
-   pgbench_log.nnn, where
-   nnn is the PID of the pgbench process.
-   The format of the log is:
-
-   
-    client_id transaction_no time file_no time_epoch time_us
-   
-
-   where time is the elapsed transaction time in microseconds,
-   file_no identifies which script file was used
-   (useful when multiple scripts were specified with -f),
-   and time_epoch/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.
-  
-
-  
-   Here are example outputs:
-   
- 0 199 2241 0 1175850568 995598
- 0 200 2465 0 1175850568 998079
- 0 201 2513 0 1175850569 608
- 0 202 2038 0 1175850569 2663
-   
-  
-
-  Good Practices
-
-  
-   It is very easy to use pgbench to produce completely
-   meaningless numbers.  Here are some guidelines to help you get useful
-   results.
-  
-
-  
-   In the first place, never believe any test that runs
-   for only a few seconds.  Use the -t or -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.
-  
-
-  
-   For the default TPC-B-like test scenario, the initialization scale factor
-   (-s) should be at least as large as the largest number of
-   clients you intend to test (-c); else you'll mostly be
-   measuring update contention.  There are only -s rows in
-   the pgbench_branches table, and every transaction wants to
-   update one of them, so -c values in excess of -s
-   will undoubtedly result in lots of transactions blocked waiting for
-   other transactions.
-  
-
-  
-   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.
-  
-
-  
-   A limitation of 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 pgbench on a different
-   machine from the database server, although low network latency will be
-   essential.  It might even be useful to run several pgbench
-   instances concurrently, on several client machines, against the same
-   database server.
-  
-
-
+\r
+\r
+\r
pgbench\r
+\r
\r
+  pgbench\r
\r
+\r
\r
+  pgbench is a simple program for running benchmark\r
+  tests on PostgreSQL.  It runs the same sequence of SQL\r
+  commands over and over, possibly in multiple concurrent database sessions,\r
+  and then calculates the average transaction rate (transactions per second).\r
+  By default, pgbench tests a scenario that is\r
+  loosely based on TPC-B, involving five SELECT,\r
+  UPDATE, and INSERT commands per transaction.\r
+  However, it is easy to test other cases by writing your own transaction\r
+  script files.\r
\r
+\r
\r
+  Typical output from pgbench looks like:\r
+\r
\r
+transaction type: TPC-B (sort of)\r
+scaling factor: 10\r
+query mode: simple\r
+number of clients: 10\r
+number of threads: 1\r
+number of transactions per client: 1000\r
+number of transactions actually processed: 10000/10000\r
+tps = 85.184871 (including connections establishing)\r
+tps = 85.296346 (excluding connections establishing)\r
\r
+\r
+  The first six lines report some of the most important parameter\r
+  settings.  The next line reports the number of transactions completed\r
+  and intended (the latter being just the product of number of clients\r
+  and number of transactions per client); these will be equal unless the run\r
+  failed before completion.  The last two lines report the TPS rate,\r
+  figured with and without counting the time to start database sessions.\r
\r
+\r
\r
+  Overview\r
+\r
+  \r
+   The default TPC-B-like transaction test requires specific tables to be\r
+   set up beforehand.  pgbench should be invoked with\r
+   the -i (initialize) option to create and populate these\r
+   tables.  (When you are testing a custom script, you don't need this\r
+   step, but will instead need to do whatever setup your test needs.)\r
+   Initialization looks like:\r
+\r
+   \r
+pgbench -i  other-options  dbname\r
+   \r
+\r
+   where dbname is the name of the already-created\r
+   database to test in.  (You may also need -h,\r
+   -p, and/or -U options to specify how to\r
+   connect to the database server.)\r
+  \r
+\r
+  \r
+   \r
+    pgbench -i creates four tables pgbench_accounts,\r
+    pgbench_branches, pgbench_history, and\r
+    pgbench_tellers,\r
+    destroying any existing tables of these names.\r
+    Be very careful to use another database if you have tables having these\r
+    names!\r
+   \r
+  \r
+\r
+  \r
+   At the default scale factor of 1, the tables initially\r
+   contain this many rows:\r
+  \r
+  \r
+table                   # of rows\r
+---------------------------------\r
+pgbench_branches        1\r
+pgbench_tellers         10\r
+pgbench_accounts        100000\r
+pgbench_history         0\r
+  \r
+  \r
+   You can (and, for most purposes, probably should) increase the number\r
+   of rows by using the -s (scale factor) option.  The\r
+   -F (fillfactor) option might also be used at this point.\r
+  \r
+\r
+  \r
+   Once you have done the necessary setup, you can run your benchmark\r
+   with a command that doesn't include -i, that is\r
+\r
+   \r
+pgbench  options  dbname\r
+   \r
+\r
+   In nearly all cases, you'll need some options to make a useful test.\r
+   The most important options are -c (number of clients),\r
+   -t (number of transactions), -T (time limit),\r
+   and -f (specify a custom script file).\r
+   See below for a full list.\r
+  \r
+\r
+  \r
+    shows options that are used\r
+   during database initialization, while\r
+    shows options that are used\r
+   while running benchmarks, and\r
+    shows options that are useful\r
+   in both cases.\r
+  \r
+\r
+  \r
+   <application>pgbench</application> initialization options\r
+   \r
+    \r
+     \r
+      Option\r
+      Description\r
+     \r
+    \r
+\r
+    \r
+     \r
+      -i\r
+      \r
+       Required to invoke initialization mode.\r
+      \r
+     \r
+     \r
+      -s scale_factor\r
+      \r
+       Multiply the number of rows generated by the scale factor.\r
+       For example, -s 100 will create 10,000,000 rows\r
+       in the pgbench_accounts table. Default is 1.\r
+      \r
+     \r
+     \r
+      -F fillfactor\r
+      \r
+       Create the pgbench_accounts,\r
+       pgbench_tellers and\r
+       pgbench_branches tables with the given fillfactor.\r
+       Default is 100.\r
+      \r
+     \r
+    \r
+   \r
+  \r
+\r
+  \r
+   <application>pgbench</application> benchmarking options\r
+   \r
+    \r
+     \r
+      Option\r
+      Description\r
+     \r
+    \r
+\r
+    \r
+     \r
+      -c clients\r
+      \r
+       Number of clients simulated, that is, number of concurrent database\r
+       sessions.  Default is 1.\r
+      \r
+     \r
+     \r
+      -j threads\r
+      \r
+       Number of worker threads within pgbench.\r
+       Using more than one thread can be helpful on multi-CPU machines.\r
+       The number of clients must be a multiple of the number of threads,\r
+       since each thread is given the same number of client sessions to manage.\r
+       Default is 1.\r
+      \r
+     \r
+     \r
+      -t transactions\r
+      \r
+       Number of transactions each client runs.  Default is 10.\r
+      \r
+     \r
+     \r
+      -T seconds\r
+      \r
+       Run the test for this many seconds, rather than a fixed number of\r
+       transactions per client. -t and\r
+       -T are mutually exclusive.\r
+      \r
+     \r
+     \r
+      -M querymode\r
+      \r
+       Protocol to use for submitting queries to the server:\r
+         \r
+          \r
+           simple: use simple query protocol.\r
+          \r
+          \r
+           extended: use extended query protocol.\r
+          \r
+          \r
+           prepared: use extended query protocol with prepared statements.\r
+          \r
+         \r
+       The default is simple query protocol.  (See \r
+       for more information.)\r
+      \r
+     \r
+     \r
+      -N\r
+      \r
+       Do not update pgbench_tellers and\r
+       pgbench_branches.\r
+       This will avoid update contention on these tables, but\r
+       it makes the test case even less like TPC-B.\r
+      \r
+     \r
+     \r
+      -S\r
+      \r
+       Perform select-only transactions instead of TPC-B-like test.\r
+      \r
+     \r
+     \r
+      -f filename\r
+      \r
+       Read transaction script from filename.\r
+       See below for details.\r
+       -N-S, and -f\r
+       are mutually exclusive.\r
+      \r
+     \r
+     \r
+      -n\r
+      \r
+       Perform no vacuuming before running the test.\r
+       This option is necessary\r
+       if you are running a custom test scenario that does not include\r
+       the standard tables pgbench_accounts,\r
+       pgbench_branches, pgbench_history, and\r
+       pgbench_tellers.\r
+      \r
+     \r
+     \r
+      -v\r
+      \r
+       Vacuum all four standard tables before running the test.\r
+       With neither -n nor -v, pgbench will vacuum the\r
+       pgbench_tellers and pgbench_branches\r
+       tables, and will truncate pgbench_history.\r
+      \r
+     \r
+     \r
+      -D varname=value\r
+      \r
+       Define a variable for use by a custom script (see below).\r
+       Multiple -D options are allowed.\r
+      \r
+     \r
+     \r
+      -C\r
+      \r
+       Establish a new connection for each transaction, rather than\r
+       doing it just once per client session.\r
+       This is useful to measure the connection overhead.\r
+      \r
+     \r
+     \r
+      -l\r
+      \r
+       Write the time taken by each transaction to a logfile.\r
+       See below for details.\r
+      \r
+     \r
+     \r
+      -s scale_factor\r
+      \r
+       Report the specified scale factor in pgbench's\r
+       output.  With the built-in tests, this is not necessary; the\r
+       correct scale factor will be detected by counting the number of\r
+       rows in the pgbench_branches table.  However, when testing\r
+       custom benchmarks (-f option), the scale factor\r
+       will be reported as 1 unless this option is used.\r
+      \r
+     \r
+     \r
+      -d\r
+      \r
+       Print debugging output.\r
+      \r
+     \r
+    \r
+   \r
+  \r
+\r
+  \r
+   <application>pgbench</application> common options\r
+   \r
+    \r
+     \r
+      Option\r
+      Description\r
+     \r
+    \r
+\r
+    \r
+     \r
+      -h hostname\r
+      database server's host\r
+     \r
+     \r
+      -p port\r
+      database server's port\r
+     \r
+     \r
+      -U login\r
+      username to connect as\r
+     \r
+    \r
+   \r
+  \r
\r
+\r
\r
+  What is the <quote>transaction</> actually performed in pgbench?\r
+\r
+  \r
+   The default transaction script issues seven commands per transaction:\r
+  \r
+\r
+  \r
+   BEGIN;\r
+   UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\r
+   SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\r
+   UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\r
+   UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\r
+   INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\r
+   END;\r
+  \r
+\r
+  \r
+   If you specify -N, steps 4 and 5 aren't included in the\r
+   transaction.  If you specify -S, only the SELECT is\r
+   issued.\r
+  \r
\r
+\r
\r
+  Custom Scripts\r
+\r
+  \r
+   pgbench has support for running custom\r
+   benchmark scenarios by replacing the default transaction script\r
+   (described above) with a transaction script read from a file\r
+   (-f option).  In this case a transaction\r
+   counts as one execution of a script file.  You can even specify\r
+   multiple scripts (multiple -f options), in which\r
+   case a random one of the scripts is chosen each time a client session\r
+   starts a new transaction.\r
+  \r
+\r
+  \r
+   The format of a script file is one SQL command per line; multi-line\r
+   SQL commands are not supported.  Empty lines and lines beginning with\r
+   -- are ignored.  Script file lines can also be\r
+   meta commands, which are interpreted by pgbench\r
+   itself, as described below.\r
+  \r
+\r
+  \r
+   There is a simple variable-substitution facility for script files.\r
+   Variables can be set by the command-line -D option,\r
+   explained above, or by the meta commands explained below.\r
+   In addition to any variables preset by -D command-line options,\r
+   the variable scale is preset to the current scale factor.\r
+   Once set, a variable's\r
+   value can be inserted into a SQL command by writing\r
+   :variablename.  When running more than\r
+   one client session, each session has its own set of variables.\r
+  \r
+\r
+  \r
+   Script file meta commands begin with a backslash (\).\r
+   Arguments to a meta command are separated by white space.\r
+   These meta commands are supported:\r
+  \r
+\r
+  \r
+   \r
+    \r
+     \set varname operand1 [ operator operand2 ]\r
+    \r
+\r
+    \r
+     \r
+      Sets variable varname to a calculated integer value.\r
+      Each operand is either an integer constant or a\r
+      :variablename reference to a variable\r
+      having an integer value.  The operator can be\r
+      +, -, *, or /.\r
+     \r
+\r
+     \r
+      Example:\r
+      \r
+\set ntellers 10 * :scale\r
+      \r
+     \r
+    \r
+   \r
+\r
+   \r
+    \r
+     \setrandom varname min max\r
+    \r
+\r
+    \r
+     \r
+      Sets variable varname to a random integer value\r
+      between the limits min and max inclusive.\r
+      Each limit can be either an integer constant or a\r
+      :variablename reference to a variable\r
+      having an integer value.\r
+     \r
+\r
+     \r
+      Example:\r
+      \r
+\setrandom aid 1 :naccounts\r
+      \r
+     \r
+    \r
+   \r
+\r
+   \r
+    \r
+     \sleep number [ us | ms | s ]\r
+    \r
+\r
+    \r
+     \r
+      Causes script execution to sleep for the specified duration in\r
+      microseconds (us), milliseconds (ms) or seconds\r
+      (s).  If the unit is omitted then seconds are the default.\r
+      number can be either an integer constant or a\r
+      :variablename reference to a variable\r
+      having an integer value.\r
+     \r
+\r
+     \r
+      Example:\r
+      \r
+\sleep 10 ms\r
+      \r
+     \r
+    \r
+   \r
+\r
+   \r
+    \r
+     \setshell varname command [ argument ... ]\r
+    \r
+\r
+    \r
+     \r
+      Sets variable varname to the result of the shell command\r
+      command. The command must return an integer value\r
+      through its standard output.\r
+     \r
+\r
+     \r
+      argument can be either a text constant or a\r
+      :variablename reference to a variable of\r
+      any types. If you want to use argument starting with\r
+      colons, you need to add an additional colon at the beginning of\r
+      argument.\r
+     \r
+\r
+     \r
+      Example:\r
+      \r
+\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon\r
+      \r
+     \r
+    \r
+   \r
+\r
+   \r
+    \r
+     \shell command [ argument ... ]\r
+    \r
+\r
+    \r
+     \r
+      Same as \setshell, but the result is ignored.\r
+     \r
+\r
+     \r
+      Example:\r
+      \r
+\shell command literal_argument :variable ::literal_starting_with_colon\r
+      \r
+     \r
+    \r
+   \r
+  \r
+\r
+  \r
+   As an example, the full definition of the built-in TPC-B-like\r
+   transaction is:\r
+\r
+   \r
+\set nbranches :scale\r
+\set ntellers 10 * :scale\r
+\set naccounts 100000 * :scale\r
+\setrandom aid 1 :naccounts\r
+\setrandom bid 1 :nbranches\r
+\setrandom tid 1 :ntellers\r
+\setrandom delta -5000 5000\r
+BEGIN;\r
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\r
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\r
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\r
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\r
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\r
+END;\r
+   \r
+\r
+   This script allows each iteration of the transaction to reference\r
+   different, randomly-chosen rows.  (This example also shows why it's\r
+   important for each client session to have its own variables —\r
+   otherwise they'd not be independently touching different rows.)\r
+  \r
+\r
\r
+\r
\r
+  Per-transaction logging\r
+\r
+  \r
+   With the -l option, pgbench writes the time\r
+   taken by each transaction to a logfile.  The logfile will be named\r
+   pgbench_log.nnn, where\r
+   nnn is the PID of the pgbench process.\r
+   If the -j option is 2 or higher, creating multiple worker\r
+   threads, each will have its own log file. The first worker will use the\r
+   the same name for its log file as in the standard single worker case.  \r
+   The additional log files for the other workers will be named\r
+   pgbench_log.nnn.mmm,\r
+   where mmm is a sequential number for each worker starting\r
+   with 1.\r
+  \r
+\r
+  \r
+   The format of the log is:\r
+\r
+   \r
+    client_id transaction_no time file_no time_epoch time_us\r
+   \r
+\r
+   where time is the elapsed transaction time in microseconds,\r
+   file_no identifies which script file was used\r
+   (useful when multiple scripts were specified with -f),\r
+   and time_epoch/time_us are a\r
+   UNIX epoch format timestamp and an offset\r
+   in microseconds (suitable for creating a ISO 8601\r
+   timestamp with fractional seconds) showing when\r
+   the transaction completed.\r
+  \r
+\r
+  \r
+   Here are example outputs:\r
+   \r
+ 0 199 2241 0 1175850568 995598\r
+ 0 200 2465 0 1175850568 998079\r
+ 0 201 2513 0 1175850569 608\r
+ 0 202 2038 0 1175850569 2663\r
+   \r
+  \r
\r
+\r
\r
+  Good Practices\r
+\r
+  \r
+   It is very easy to use pgbench to produce completely\r
+   meaningless numbers.  Here are some guidelines to help you get useful\r
+   results.\r
+  \r
+\r
+  \r
+   In the first place, never believe any test that runs\r
+   for only a few seconds.  Use the -t or -T option\r
+   to make the run last at least a few minutes, so as to average out noise.\r
+   In some cases you could need hours to get numbers that are reproducible.\r
+   It's a good idea to try the test run a few times, to find out if your\r
+   numbers are reproducible or not.\r
+  \r
+\r
+  \r
+   For the default TPC-B-like test scenario, the initialization scale factor\r
+   (-s) should be at least as large as the largest number of\r
+   clients you intend to test (-c); else you'll mostly be\r
+   measuring update contention.  There are only -s rows in\r
+   the pgbench_branches table, and every transaction wants to\r
+   update one of them, so -c values in excess of -s\r
+   will undoubtedly result in lots of transactions blocked waiting for\r
+   other transactions.\r
+  \r
+\r
+  \r
+   The default test scenario is also quite sensitive to how long it's been\r
+   since the tables were initialized: accumulation of dead rows and dead space\r
+   in the tables changes the results.  To understand the results you must keep\r
+   track of the total number of updates and when vacuuming happens.  If\r
+   autovacuum is enabled it can result in unpredictable changes in measured\r
+   performance.\r
+  \r
+\r
+  \r
+   A limitation of pgbench is that it can itself become\r
+   the bottleneck when trying to test a large number of client sessions.\r
+   This can be alleviated by running pgbench on a different\r
+   machine from the database server, although low network latency will be\r
+   essential.  It might even be useful to run several pgbench\r
+   instances concurrently, on several client machines, against the same\r
+   database server.\r
+  \r
\r
+\r
+\r