-pgbench README 2001/10/24 Tatsuo Ishii (t-ishii@sra.co.jp)
+pgbench README 2002/07/20 Tatsuo Ishii (t-ishii@sra.co.jp)
o What is pgbench?
(10,000,000) tuples in the accounts table.
default is 1.
- -U login
+ -U login
Specify db user's login name if it is different from
the Unix login name.
show the password. Use this for TESTING PURPOSE ONLY.
-n
- No vacuuming and cleaning the history table prior the
+ No vacuuming and cleaning the history table prior to the
test is performed.
-v
-S
Perform select only transactions instead of TPC-B.
- -C
+ -C
Establish connection for each transaction, rather than
- doing it just once at begining of pgbench in the normal
- mode. This is usefull to measure the connection overhead.
+ doing it just once at beginning of pgbench in the normal
+ mode. This is useful to measure the connection overhead.
+
+ -l
+ Write the time taken by each transaction to a logfile,
+ with the name "pgbench_log.xxx", where xxx is the PID
+ of the pgbench process. The format of the log is:
+
+ client_id transaction_no time
+
+ where time is measured in microseconds.
-d
debug option.
o History
+2002/07/20
+ * patch contributed by Neil Conway.
+ * code/document clean up and add -l option.
+
+2002/02/24
+ * do not CHECKPOINT anymore while initializing benchmark
+ * database. Add -N option.
+
2001/10/24
* "time"->"mtime"
-pgbench README 2002/02/24 Tatsuo Ishii (t-ishii@sra.co.jp)
+pgbench README 2002/07/20 Tatsuo Ishii (t-ishii@sra.co.jp)
\e$B"#\e(Bpgbench \e$B$H$O!)\e(B
\e$B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=<BE*$JIi2Y$r%F%9%H$9$k$3\e(B
\e$B$H$,$G$-$^$9!%\e(B
--N
- "branches"\e$B$H\e(B"tellers"\e$B%F!<%V%k$N99?7$r9T$$$^$;$s!%$3$l\e(B
- \e$B$K$h$C$F\e(B"branches"\e$B$H\e(B"tellers"\e$B$X$NBgNL$N99?7$N6%9g$N$J\e(B
- \e$B$$>uBV$G$NB,Dj$r9T$$$^$9!%$7$?$,$C$F\e(BTPC-B\e$B$N%9%Z%C%/$K\e(B
- \e$B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=<BE*$JIi2Y$r%F%9%H$9$k$3\e(B
- \e$B$H$,$G$-$^$9!%\e(B
-
-C \e$B$3$N%*%W%7%g%s$r;XDj$9$k$H!$:G=i$K3NN)$7$?%3%M%/%7%g%s\e(B
\e$B$r;H$$2s$9$N$G$O$J$/!$3F%H%i%s%6%/%7%g%s$4$H$K\e(BDB\e$B$X$N@\\e(B
\e$BB3$r9T$$$^$9!%%3%M%/%7%g%s$N%*!<%P!<$X%C%I$rB,Dj$9$k$N\e(B
\e$B$KM-8z$G$9!%\e(B
+-l \e$B8D!9$N%H%i%s%6%/%7%g%s$N<B9T;~4V$r5-O?$7$^$9!%5-O?@h$O\e(B
+ \e$B%+%l%s%H%G%#%l%/%H%j0J2<$N\e(Bpgbench_log.xxx\e$B$H$$$&%U%!%$\e(B
+ \e$B%k$G$9!%%U%!%$%k$N%U%)!<%^%C%H$O!$\e(B
+
+ \e$B%/%i%$%"%s%H\e(BID \e$B%H%i%s%6%/%7%g%sHV9f\e(B \e$B;~4V\e(B
+
+ \e$B$H$J$C$F$$$^$9!%;~4V$O%^%$%/%mICC10L$G$9!%\e(B
+
-d \e$B%G%P%C%0%*%W%7%g%s!%MM!9$J>pJs$,I=<($5$l$^$9!%\e(B
\e$B"#%G!<%?%Y!<%9$N=i4|2=\e(B
\e$B"#2~DjMzNr\e(B
-2002/02/24
- * \e$B$3$3$+$i$O\e(B7.3\e$BMQ$NJQ99$G$9!%\e(B
- * CHECKPOINT\e$B$NH/9T$r$d$a$^$7$?!%\e(B
- * -N \e$B%*%W%7%g%s$rDI2C$7$^$7$?!%\e(B
+2002/07/20
+ * Nei Conway\e$B$5$s$N%Q%C%A$rE,MQ!%\e(B
+ * -l \e$B%*%W%7%g%s$NDI2C!%\e(B
2002/02/24
* \e$B$3$3$+$i$O\e(B7.3\e$BMQ$NJQ99$G$9!%\e(B
/*
- * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.16 2002/02/24 00:17:57 ishii Exp $
+ * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.17 2002/07/20 03:02:01 ishii Exp $
*
* pgbench: a simple TPC-B like benchmark program for PostgreSQL
* written by Tatsuo Ishii
/* for getrlimit */
#include <sys/resource.h>
-#endif /* WIN32 */
+#endif /* ! WIN32 */
/********************************************************************
* some configurable parameters */
#define ntellers 10
#define naccounts 100000
-int remains; /* number of remained clients */
+FILE *LOGFILE = NULL;
+
+bool use_log; /* log transaction latencies to a file */
+
+int remains; /* number of remaining clients */
int is_connect; /* establish connection for each
- * transactoin */
+ * transaction */
char *pghost = "";
char *pgport = NULL;
typedef struct
{
PGconn *con; /* connection handle to DB */
+ int id; /* client No. */
int state; /* state No. */
int cnt; /* xacts count */
int ecnt; /* error count */
- int listen; /* none 0 indicates that an async query
+ int listen; /* 0 indicates that an async query
* has been sent */
int aid; /* account id for this transaction */
int bid; /* branch id for this transaction */
int tid; /* teller id for this transaction */
int delta;
int abalance;
+ struct timeval txn_begin; /* used for measuring latencies */
} CState;
static void
usage()
{
- fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-U login][-P password][-d][dbname]\n");
+ fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-l][-U login][-P password][-d][dbname]\n");
fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-U login][-P password][-d][dbname]\n");
}
discard_response(st);
break;
case 6: /* response to "end" */
+ /* transaction finished: record the time it took in the log */
+ if (use_log)
+ {
+ long long diff;
+ struct timeval now;
+
+ gettimeofday(&now, 0);
+ diff = (now.tv_sec - st->txn_begin.tv_sec) * 1000000 +
+ (now.tv_usec - st->txn_begin.tv_usec);
+
+ fprintf(LOGFILE, "%d %d %lld\n", st->id, st->cnt, diff);
+ }
+
res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK))
return;
if (++st->cnt >= nxacts)
{
- remains--; /* I've done */
+ remains--; /* I'm done */
if (st->con != NULL)
{
PQfinish(st->con);
st->bid = getrand(1, nbranches * tps);
st->tid = getrand(1, ntellers * tps);
st->delta = getrand(1, 1000);
+ if (use_log)
+ gettimeofday(&(st->txn_begin), 0);
break;
case 1:
sprintf(sql, "update accounts set abalance = abalance + %d where aid = %d\n", st->delta, st->aid);
}
else
{
- st->listen++; /* flags that should be listned */
+ st->listen++; /* flags that should be listened */
}
}
}
else
{
- st->listen++; /* flags that should be listned */
+ st->listen++; /* flags that should be listened */
}
}
/* create tables and setup data */
static void
-init()
+init(void)
{
PGconn *con;
PGresult *res;
printf("number of clients: %d\n", nclients);
printf("number of transactions per client: %d\n", nxacts);
printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients);
- printf("tps = %f(including connections establishing)\n", t1);
- printf("tps = %f(excluding connections establishing)\n", t2);
+ printf("tps = %f (including connections establishing)\n", t1);
+ printf("tps = %f (excluding connections establishing)\n", t2);
}
* testing? */
int is_full_vacuum = 0; /* do full vacuum before testing? */
int debug = 0; /* debug flag */
- int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT
- * only
- 2: skip updation of branches and tellers */
+ int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT only,
+ * 2: skip update of branches and tellers */
- static CState state[MAXCLIENTS]; /* clients status */
+ static CState *state; /* status of clients */
struct timeval tv1; /* start up time */
struct timeval tv2; /* after establishing all connections to
PGconn *con;
PGresult *res;
- while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNS")) != -1)
+ while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSl")) != -1)
{
switch (c)
{
nclients = atoi(optarg);
if (nclients <= 0 || nclients > MAXCLIENTS)
{
- fprintf(stderr, "wrong number of clients: %d\n", nclients);
+ fprintf(stderr, "invalid number of clients: %d\n", nclients);
exit(1);
}
#ifndef __CYGWIN__
tps = atoi(optarg);
if (tps <= 0)
{
- fprintf(stderr, "wrong scaling factor: %d\n", tps);
+ fprintf(stderr, "invalid scaling factor: %d\n", tps);
exit(1);
}
break;
nxacts = atoi(optarg);
if (nxacts <= 0)
{
- fprintf(stderr, "wrong number of transactions: %d\n", nxacts);
+ fprintf(stderr, "invalid number of transactions: %d\n", nxacts);
exit(1);
}
break;
case 'P':
pwd = optarg;
break;
+ case 'l':
+ use_log = true;
+ break;
default:
usage();
exit(1);
remains = nclients;
+ state = (CState *) malloc(sizeof(*state) * nclients);
+ memset(state, 0, sizeof(*state));
+
+ if (use_log)
+ {
+ char logpath[64];
+
+ snprintf(logpath, 64, "pgbench_log.%d", getpid());
+ LOGFILE = fopen(logpath, "w");
+
+ if (LOGFILE == NULL)
+ {
+ fprintf(stderr, "Couldn't open logfile \"%s\": %s", logpath, strerror(errno));
+ exit(1);
+ }
+ }
+
if (debug)
{
printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n",
/* make connections to the database */
for (i = 0; i < nclients; i++)
{
+ state[i].id = i;
if ((state[i].con = doConnect()) == NULL)
exit(1);
}
/* time after connections set up */
gettimeofday(&tv2, 0);
- /* send start up quries in async manner */
+ /* send start up queries in async manner */
for (i = 0; i < nclients; i++)
{
if (ttype == 0 || ttype == 2)
/* get end time */
gettimeofday(&tv3, 0);
printResults(ttype, state, &tv1, &tv2, &tv3);
+ if (LOGFILE)
+ fclose(LOGFILE);
exit(0);
}
if (sock < 0)
{
- fprintf(stderr, "Client %d: PQsock failed\n", i);
+ fprintf(stderr, "Client %d: PQsocket failed\n", i);
disconnect_all(state);
exit(1);
}