Apply patches from Neil Conway.
> Hi Tatsuo, > > I've attached a patch for the version of pgbench in CVS. It includes the > following changes: > > - fix some spelling mistakes, indentation stuff, etc. > > - minor code cleanup -- (void) args instead of (), etc. > > - allocate the state array dynamically, so that it is only as > large as needed. This reduces the memory consumption of pgbench > slightly, and makes a larger MAXCLIENTS setting possible > > - (the only controversial change) add an option "-l" to log > transaction latencies to a file. The "transaction latency" > is the time between when the BEGIN is issued and the transaction > commits. This is written to a file, along with the client # > and the transaction #. The data in the file can then be used > for things like: > > - consistency analysis: is the TPS the same through the > entire run of pgbench, or does it change? > > - more detailed stats: what is the average latency, worse-case > latency, best-case latency? > > - graphs: feed the data to gnuplot, graph latency versus. time > > - etc. > > I was going to store this data in memory and write it to disk > at the end of the pgbench run, but that isn't feasible because > the data can be very large: for example, ~70MB if benchmarking > 128 clients doing 100,000 transactions each. > > Cheers, > > Neil
This commit is contained in:
parent
009d593c48
commit
cdf4b9aff2
3 changed files with 100 additions and 40 deletions
|
@ -1,4 +1,4 @@
|
||||||
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?
|
o What is pgbench?
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ o options
|
||||||
(10,000,000) tuples in the accounts table.
|
(10,000,000) tuples in the accounts table.
|
||||||
default is 1.
|
default is 1.
|
||||||
|
|
||||||
-U login
|
-U login
|
||||||
Specify db user's login name if it is different from
|
Specify db user's login name if it is different from
|
||||||
the Unix login name.
|
the Unix login name.
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ o options
|
||||||
show the password. Use this for TESTING PURPOSE ONLY.
|
show the password. Use this for TESTING PURPOSE ONLY.
|
||||||
|
|
||||||
-n
|
-n
|
||||||
No vacuuming and cleaning the history table prior the
|
No vacuuming and cleaning the history table prior to the
|
||||||
test is performed.
|
test is performed.
|
||||||
|
|
||||||
-v
|
-v
|
||||||
|
@ -122,10 +122,19 @@ o options
|
||||||
-S
|
-S
|
||||||
Perform select only transactions instead of TPC-B.
|
Perform select only transactions instead of TPC-B.
|
||||||
|
|
||||||
-C
|
-C
|
||||||
Establish connection for each transaction, rather than
|
Establish connection for each transaction, rather than
|
||||||
doing it just once at begining of pgbench in the normal
|
doing it just once at beginning of pgbench in the normal
|
||||||
mode. This is usefull to measure the connection overhead.
|
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
|
-d
|
||||||
debug option.
|
debug option.
|
||||||
|
@ -153,6 +162,14 @@ Basically it is same as BSD license. See pgbench.c for more details.
|
||||||
|
|
||||||
o History
|
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
|
2001/10/24
|
||||||
* "time"->"mtime"
|
* "time"->"mtime"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pgbench README 2002/02/24 Tatsuo Ishii (t-ishii@sra.co.jp)
|
pgbench README 2002/07/20 Tatsuo Ishii (t-ishii@sra.co.jp)
|
||||||
|
|
||||||
$B"#(Bpgbench $B$H$O!)(B
|
$B"#(Bpgbench $B$H$O!)(B
|
||||||
|
|
||||||
|
@ -104,18 +104,19 @@ pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B
|
||||||
$B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=<BE*$JIi2Y$r%F%9%H$9$k$3(B
|
$B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=<BE*$JIi2Y$r%F%9%H$9$k$3(B
|
||||||
$B$H$,$G$-$^$9!%(B
|
$B$H$,$G$-$^$9!%(B
|
||||||
|
|
||||||
-N
|
|
||||||
"branches"$B$H(B"tellers"$B%F!<%V%k$N99?7$r9T$$$^$;$s!%$3$l(B
|
|
||||||
$B$K$h$C$F(B"branches"$B$H(B"tellers"$B$X$NBgNL$N99?7$N6%9g$N$J(B
|
|
||||||
$B$$>uBV$G$NB,Dj$r9T$$$^$9!%$7$?$,$C$F(BTPC-B$B$N%9%Z%C%/$K(B
|
|
||||||
$B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=<BE*$JIi2Y$r%F%9%H$9$k$3(B
|
|
||||||
$B$H$,$G$-$^$9!%(B
|
|
||||||
|
|
||||||
-C $B$3$N%*%W%7%g%s$r;XDj$9$k$H!$:G=i$K3NN)$7$?%3%M%/%7%g%s(B
|
-C $B$3$N%*%W%7%g%s$r;XDj$9$k$H!$:G=i$K3NN)$7$?%3%M%/%7%g%s(B
|
||||||
$B$r;H$$2s$9$N$G$O$J$/!$3F%H%i%s%6%/%7%g%s$4$H$K(BDB$B$X$N@\(B
|
$B$r;H$$2s$9$N$G$O$J$/!$3F%H%i%s%6%/%7%g%s$4$H$K(BDB$B$X$N@\(B
|
||||||
$BB3$r9T$$$^$9!%%3%M%/%7%g%s$N%*!<%P!<$X%C%I$rB,Dj$9$k$N(B
|
$BB3$r9T$$$^$9!%%3%M%/%7%g%s$N%*!<%P!<$X%C%I$rB,Dj$9$k$N(B
|
||||||
$B$KM-8z$G$9!%(B
|
$B$KM-8z$G$9!%(B
|
||||||
|
|
||||||
|
-l $B8D!9$N%H%i%s%6%/%7%g%s$N<B9T;~4V$r5-O?$7$^$9!%5-O?@h$O(B
|
||||||
|
$B%+%l%s%H%G%#%l%/%H%j0J2<$N(Bpgbench_log.xxx$B$H$$$&%U%!%$(B
|
||||||
|
$B%k$G$9!%%U%!%$%k$N%U%)!<%^%C%H$O!$(B
|
||||||
|
|
||||||
|
$B%/%i%$%"%s%H(BID $B%H%i%s%6%/%7%g%sHV9f(B $B;~4V(B
|
||||||
|
|
||||||
|
$B$H$J$C$F$$$^$9!%;~4V$O%^%$%/%mICC10L$G$9!%(B
|
||||||
|
|
||||||
-d $B%G%P%C%0%*%W%7%g%s!%MM!9$J>pJs$,I=<($5$l$^$9!%(B
|
-d $B%G%P%C%0%*%W%7%g%s!%MM!9$J>pJs$,I=<($5$l$^$9!%(B
|
||||||
|
|
||||||
$B"#%G!<%?%Y!<%9$N=i4|2=(B
|
$B"#%G!<%?%Y!<%9$N=i4|2=(B
|
||||||
|
@ -183,10 +184,9 @@ pgbench $B$O@P0f(B $BC#IW$K$h$C$F=q$+$l$^$7$?!%%i%$%;%s%9>r7o$O(B pgbench.c
|
||||||
|
|
||||||
$B"#2~DjMzNr(B
|
$B"#2~DjMzNr(B
|
||||||
|
|
||||||
2002/02/24
|
2002/07/20
|
||||||
* $B$3$3$+$i$O(B7.3$BMQ$NJQ99$G$9!%(B
|
* Nei Conway$B$5$s$N%Q%C%A$rE,MQ!%(B
|
||||||
* CHECKPOINT$B$NH/9T$r$d$a$^$7$?!%(B
|
* -l $B%*%W%7%g%s$NDI2C!%(B
|
||||||
* -N $B%*%W%7%g%s$rDI2C$7$^$7$?!%(B
|
|
||||||
|
|
||||||
2002/02/24
|
2002/02/24
|
||||||
* $B$3$3$+$i$O(B7.3$BMQ$NJQ99$G$9!%(B
|
* $B$3$3$+$i$O(B7.3$BMQ$NJQ99$G$9!%(B
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $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
|
* pgbench: a simple TPC-B like benchmark program for PostgreSQL
|
||||||
* written by Tatsuo Ishii
|
* written by Tatsuo Ishii
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
/* for getrlimit */
|
/* for getrlimit */
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif /* WIN32 */
|
#endif /* ! WIN32 */
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* some configurable parameters */
|
* some configurable parameters */
|
||||||
|
@ -64,10 +64,14 @@ int tps = 1;
|
||||||
#define ntellers 10
|
#define ntellers 10
|
||||||
#define naccounts 100000
|
#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
|
int is_connect; /* establish connection for each
|
||||||
* transactoin */
|
* transaction */
|
||||||
|
|
||||||
char *pghost = "";
|
char *pghost = "";
|
||||||
char *pgport = NULL;
|
char *pgport = NULL;
|
||||||
|
@ -80,22 +84,24 @@ char *dbName;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
PGconn *con; /* connection handle to DB */
|
PGconn *con; /* connection handle to DB */
|
||||||
|
int id; /* client No. */
|
||||||
int state; /* state No. */
|
int state; /* state No. */
|
||||||
int cnt; /* xacts count */
|
int cnt; /* xacts count */
|
||||||
int ecnt; /* error 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 */
|
* has been sent */
|
||||||
int aid; /* account id for this transaction */
|
int aid; /* account id for this transaction */
|
||||||
int bid; /* branch id for this transaction */
|
int bid; /* branch id for this transaction */
|
||||||
int tid; /* teller id for this transaction */
|
int tid; /* teller id for this transaction */
|
||||||
int delta;
|
int delta;
|
||||||
int abalance;
|
int abalance;
|
||||||
|
struct timeval txn_begin; /* used for measuring latencies */
|
||||||
} CState;
|
} CState;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage()
|
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");
|
fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-U login][-P password][-d][dbname]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +241,19 @@ doOne(CState * state, int n, int debug, int ttype)
|
||||||
discard_response(st);
|
discard_response(st);
|
||||||
break;
|
break;
|
||||||
case 6: /* response to "end" */
|
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);
|
res = PQgetResult(st->con);
|
||||||
if (check(state, res, n, PGRES_COMMAND_OK))
|
if (check(state, res, n, PGRES_COMMAND_OK))
|
||||||
return;
|
return;
|
||||||
|
@ -249,7 +268,7 @@ doOne(CState * state, int n, int debug, int ttype)
|
||||||
|
|
||||||
if (++st->cnt >= nxacts)
|
if (++st->cnt >= nxacts)
|
||||||
{
|
{
|
||||||
remains--; /* I've done */
|
remains--; /* I'm done */
|
||||||
if (st->con != NULL)
|
if (st->con != NULL)
|
||||||
{
|
{
|
||||||
PQfinish(st->con);
|
PQfinish(st->con);
|
||||||
|
@ -287,6 +306,8 @@ doOne(CState * state, int n, int debug, int ttype)
|
||||||
st->bid = getrand(1, nbranches * tps);
|
st->bid = getrand(1, nbranches * tps);
|
||||||
st->tid = getrand(1, ntellers * tps);
|
st->tid = getrand(1, ntellers * tps);
|
||||||
st->delta = getrand(1, 1000);
|
st->delta = getrand(1, 1000);
|
||||||
|
if (use_log)
|
||||||
|
gettimeofday(&(st->txn_begin), 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
sprintf(sql, "update accounts set abalance = abalance + %d where aid = %d\n", st->delta, st->aid);
|
sprintf(sql, "update accounts set abalance = abalance + %d where aid = %d\n", st->delta, st->aid);
|
||||||
|
@ -326,7 +347,7 @@ doOne(CState * state, int n, int debug, int ttype)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
st->listen++; /* flags that should be listned */
|
st->listen++; /* flags that should be listened */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +441,7 @@ doSelectOnly(CState * state, int n, int debug)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
st->listen++; /* flags that should be listned */
|
st->listen++; /* flags that should be listened */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +460,7 @@ disconnect_all(CState * state)
|
||||||
|
|
||||||
/* create tables and setup data */
|
/* create tables and setup data */
|
||||||
static void
|
static void
|
||||||
init()
|
init(void)
|
||||||
{
|
{
|
||||||
PGconn *con;
|
PGconn *con;
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
|
@ -616,8 +637,8 @@ printResults(
|
||||||
printf("number of clients: %d\n", nclients);
|
printf("number of clients: %d\n", nclients);
|
||||||
printf("number of transactions per client: %d\n", nxacts);
|
printf("number of transactions per client: %d\n", nxacts);
|
||||||
printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients);
|
printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients);
|
||||||
printf("tps = %f(including connections establishing)\n", t1);
|
printf("tps = %f (including connections establishing)\n", t1);
|
||||||
printf("tps = %f(excluding connections establishing)\n", t2);
|
printf("tps = %f (excluding connections establishing)\n", t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -634,11 +655,10 @@ main(int argc, char **argv)
|
||||||
* testing? */
|
* testing? */
|
||||||
int is_full_vacuum = 0; /* do full vacuum before testing? */
|
int is_full_vacuum = 0; /* do full vacuum before testing? */
|
||||||
int debug = 0; /* debug flag */
|
int debug = 0; /* debug flag */
|
||||||
int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT
|
int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT only,
|
||||||
* only
|
* 2: skip update of branches and tellers */
|
||||||
2: skip updation of branches and tellers */
|
|
||||||
|
|
||||||
static CState state[MAXCLIENTS]; /* clients status */
|
static CState *state; /* status of clients */
|
||||||
|
|
||||||
struct timeval tv1; /* start up time */
|
struct timeval tv1; /* start up time */
|
||||||
struct timeval tv2; /* after establishing all connections to
|
struct timeval tv2; /* after establishing all connections to
|
||||||
|
@ -658,7 +678,7 @@ main(int argc, char **argv)
|
||||||
PGconn *con;
|
PGconn *con;
|
||||||
PGresult *res;
|
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)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
@ -690,7 +710,7 @@ main(int argc, char **argv)
|
||||||
nclients = atoi(optarg);
|
nclients = atoi(optarg);
|
||||||
if (nclients <= 0 || nclients > MAXCLIENTS)
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
|
@ -719,7 +739,7 @@ main(int argc, char **argv)
|
||||||
tps = atoi(optarg);
|
tps = atoi(optarg);
|
||||||
if (tps <= 0)
|
if (tps <= 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "wrong scaling factor: %d\n", tps);
|
fprintf(stderr, "invalid scaling factor: %d\n", tps);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -727,7 +747,7 @@ main(int argc, char **argv)
|
||||||
nxacts = atoi(optarg);
|
nxacts = atoi(optarg);
|
||||||
if (nxacts <= 0)
|
if (nxacts <= 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "wrong number of transactions: %d\n", nxacts);
|
fprintf(stderr, "invalid number of transactions: %d\n", nxacts);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -737,6 +757,9 @@ main(int argc, char **argv)
|
||||||
case 'P':
|
case 'P':
|
||||||
pwd = optarg;
|
pwd = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
use_log = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -761,6 +784,23 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
remains = nclients;
|
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)
|
if (debug)
|
||||||
{
|
{
|
||||||
printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n",
|
printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n",
|
||||||
|
@ -860,6 +900,7 @@ main(int argc, char **argv)
|
||||||
/* make connections to the database */
|
/* make connections to the database */
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
|
state[i].id = i;
|
||||||
if ((state[i].con = doConnect()) == NULL)
|
if ((state[i].con = doConnect()) == NULL)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -868,7 +909,7 @@ main(int argc, char **argv)
|
||||||
/* time after connections set up */
|
/* time after connections set up */
|
||||||
gettimeofday(&tv2, 0);
|
gettimeofday(&tv2, 0);
|
||||||
|
|
||||||
/* send start up quries in async manner */
|
/* send start up queries in async manner */
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
if (ttype == 0 || ttype == 2)
|
if (ttype == 0 || ttype == 2)
|
||||||
|
@ -885,6 +926,8 @@ main(int argc, char **argv)
|
||||||
/* get end time */
|
/* get end time */
|
||||||
gettimeofday(&tv3, 0);
|
gettimeofday(&tv3, 0);
|
||||||
printResults(ttype, state, &tv1, &tv2, &tv3);
|
printResults(ttype, state, &tv1, &tv2, &tv3);
|
||||||
|
if (LOGFILE)
|
||||||
|
fclose(LOGFILE);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,7 +942,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Client %d: PQsock failed\n", i);
|
fprintf(stderr, "Client %d: PQsocket failed\n", i);
|
||||||
disconnect_all(state);
|
disconnect_all(state);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue