mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
New features contributed by Tomoaki Sato.
- predefined variable "tps" The value of variable tps is taken from the scaling factor specified by -s option. - -D option Variable values can be defined by -D option. - \set command now allows arithmetic calculations.
This commit is contained in:
parent
88b39634cd
commit
0c57c832b9
@ -1,14 +1,14 @@
|
||||
pgbench README 2005/10/04 Tatsuo Ishii
|
||||
pgbench README 2006/07/26 Tatsuo Ishii
|
||||
|
||||
o What is pgbench?
|
||||
|
||||
pgbench is a simple program to run a benchmark test sort of
|
||||
"TPC-B". pgbench is a client application of PostgreSQL and runs
|
||||
with PostgreSQL only. It performs lots of small and simple
|
||||
transactions including select/update/insert operations then
|
||||
calculates number of transactions successfully completed within a
|
||||
second (transactions per second, tps). Targeting data includes a
|
||||
table with at least 100k tuples.
|
||||
pgbench is a simple program to run a benchmark test. pgbench is a
|
||||
client application of PostgreSQL and runs with PostgreSQL only. It
|
||||
performs lots of small and simple transactions including
|
||||
SELECT/UPDATE/INSERT operations then calculates number of
|
||||
transactions successfully completed within a second (transactions
|
||||
per second, tps). Targeting data includes a table with at least 100k
|
||||
tuples.
|
||||
|
||||
Example outputs from pgbench look like:
|
||||
|
||||
@ -39,7 +39,7 @@ o How to install pgbench
|
||||
|
||||
o How to use pgbench?
|
||||
|
||||
(1) Initialize database by:
|
||||
(1) (optional)Initialize database by:
|
||||
|
||||
pgbench -i <dbname>
|
||||
|
||||
@ -95,6 +95,10 @@ o options
|
||||
as large as the largest number of clients you intend
|
||||
to test; else you'll mostly be measuring update contention.
|
||||
|
||||
-D varname=value
|
||||
Define a variable. It can be refereed to by a script
|
||||
provided by using -f option. Multile -D options are allowed.
|
||||
|
||||
-U login
|
||||
Specify db user's login name if it is different from
|
||||
the Unix login name.
|
||||
@ -173,6 +177,15 @@ o -f option
|
||||
slash). A meta command takes some arguments separted by white
|
||||
spaces. Currently following meta command is supported:
|
||||
|
||||
\set name operand1 [ operator operand2 ]
|
||||
set the calculated value using "operand1" "operator"
|
||||
"operand2" to variable "name". If "operator" and "operand2"
|
||||
are omitted, the value of operand1 is set to variable "name".
|
||||
|
||||
example:
|
||||
|
||||
\set ntellers 10 * :tps
|
||||
|
||||
\setrandom name min max
|
||||
|
||||
assign random integer to name between min and max
|
||||
@ -188,12 +201,17 @@ o -f option
|
||||
|
||||
SELECT abalance FROM accounts WHERE aid = :aid
|
||||
|
||||
For example, TPC-B like benchmark can be defined as follows(scaling
|
||||
Variables can also be defined by using -D option.
|
||||
|
||||
Example, TPC-B like benchmark can be defined as follows(scaling
|
||||
factor = 1):
|
||||
|
||||
\setrandom aid 1 100000
|
||||
\setrandom bid 1 1
|
||||
\setrandom tid 1 10
|
||||
\set nbranches :tps
|
||||
\set ntellers 10 * :tps
|
||||
\set naccounts 100000 * :tps
|
||||
\setrandom aid 1 :naccounts
|
||||
\setrandom bid 1 :nbranches
|
||||
\setrandom tid 1 :ntellers
|
||||
\setrandom delta 1 10000
|
||||
BEGIN
|
||||
UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid
|
||||
@ -203,12 +221,30 @@ UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid
|
||||
INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, 'now')
|
||||
END
|
||||
|
||||
If you want to automatically set the scaling factor from the number of
|
||||
tuples in branches table, use -s option and shell command like this:
|
||||
|
||||
pgbench -s $(psql -At -c "SELECT count(*) FROM branches") -f tpc_b.sql
|
||||
|
||||
Notice that -f option does not execute vacuum and clearing history
|
||||
table before starting benchmark.
|
||||
|
||||
o License?
|
||||
|
||||
Basically it is same as BSD license. See pgbench.c for more details.
|
||||
|
||||
o History
|
||||
|
||||
2006/07/26
|
||||
* New features contributed by Tomoaki Sato.
|
||||
|
||||
* predefined variable "tps"
|
||||
The value of variable tps is taken from the scaling factor
|
||||
specified by -s option.
|
||||
* -D option
|
||||
Variable values can be defined by -D option.
|
||||
* \set command now allows arithmetic calculations.
|
||||
|
||||
2005/09/29
|
||||
* add -f option. contributed by Tomoaki Sato.
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
pgbench README 2005/09/29 Tatsuo Ishii
|
||||
pgbench README 2006/07/26 Tatsuo Ishii
|
||||
|
||||
$B"#(Bpgbench $B$H$O!)(B
|
||||
|
||||
pgbench $B$O%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!%:#$N$H$3$m(B
|
||||
PostgreSQL $B@lMQ$G$9!%(B
|
||||
pgbench $B$O(BPostgreSQL$B$N%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!%(B
|
||||
|
||||
pgbench $B$O(B select/update/insert $B$r4^$`%H%i%s%6%/%7%g%s$r<B9T$7!$A4BN$N(B
|
||||
pgbench $B$O(B SELECT/UPDATE/INSERT $B$r4^$`%H%i%s%6%/%7%g%s$r<B9T$7!$A4BN$N(B
|
||||
$B<B9T;~4V$H<B:]$K40N;$7$?%H%i%s%6%/%7%g%s$N?t$+$i(B 1 $BIC4V$K<B9T$G$-$?%H(B
|
||||
$B%i%s%6%/%7%g%s?t(B (tps) $B$rI=<($7$^$9!%=hM}$NBP>]$H$J$k%F!<%V%k$O%G%U%)(B
|
||||
$B%k%H$G$O(B 10$BK|%?%W%k$N%G!<%?$r4^$_$^$9!%(B
|
||||
@ -44,7 +43,8 @@ $ pgbench [$B%G!<%?%Y!<%9L>(B]
|
||||
|
||||
$B$G$9!%%G!<%?%Y!<%9L>$r>JN,$9$k$H!$%f!<%6L>$HF1$8%G!<%?%Y!<%9$r;XDj$7$?(B
|
||||
$B$b$N$H$_$J$7$^$9!%%G!<%?%Y!<%9$O8e=R$N(B -i $B%*%W%7%g%s$r;H$C$F$"$i$+$8$a(B
|
||||
$B=i4|2=$7$F$*$/I,MW$,$"$j$^$9!%(B
|
||||
$B=i4|2=$7$F$*$/$3$H$,$G$-$^$9!%(B-f$B%*%W%7%g%s$r;H$C$FFH<+$N%H%i%s%6%/%7%g(B
|
||||
$B%s$rDj5A$9$k>l9g$O!$<+J,$G%G!<%?%Y!<%9$N=i4|2=$r$7$F$*$/I,MW$,$"$j$^$9!%(B
|
||||
|
||||
pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B
|
||||
|
||||
@ -72,6 +72,14 @@ pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B
|
||||
$B%/%?!<$rJQ$($k$3$H$K$h$j!$%F%9%H$NBP>]$H$J$k%F!<%V%k$N(B
|
||||
$BBg$-$5$,(B 10$BK|(B x [$B%9%1!<%j%s%0%U%!%/%?!<(B]$B$K$J$j$^$9!%(B
|
||||
$B%G%U%)%k%H$N%9%1!<%j%s%0%U%!%/%?!<$O(B 1 $B$G$9!%(B
|
||||
-f $B%*%W%7%g%s$G;XDj$7$?%U%!%$%k$+$i%9%1!<%j%s%0%U%!%/(B
|
||||
$B%?!<$r;2>H$9$k$K$O(B tps $B$H$$$&JQ?tL>$r;HMQ$7$^$9!%(B
|
||||
|
||||
-D varname=value
|
||||
|
||||
$BJQ?t$rDj5A$7$^$9!%Dj5A$7$?JQ?t$O(B -f $B%*%W%7%g%s$G;XDj$7$?%U%!%$(B
|
||||
$B%k$+$i;2>H$G$-$^$9!%(B-D $B%*%W%7%g%s$G$OJQ?tL>$HCM$r(B = ($B%$%3!<%k(B)
|
||||
$B$G6h@Z$C$F;XDj$7$^$9!%(B-D $B%*%W%7%g%s$OJ#?t;XDj$G$-$^$9!%(B
|
||||
|
||||
-U login DB$B%f!<%6$N%m%0%$%sL>$r;XDj$7$^$9!%(B
|
||||
|
||||
@ -129,7 +137,9 @@ pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B
|
||||
$B"#%G!<%?%Y!<%9$N=i4|2=(B
|
||||
|
||||
pgbench $B$G%Y%s%A%^!<%/%F%9%H$r<B;\$9$k$?$a$K$O!$$"$i$+$8$a%G!<%?%Y!<%9(B
|
||||
$B$r=i4|2=$7!$%F%9%H%G!<%?$r:n$kI,MW$,$"$j$^$9!%(B
|
||||
$B$r=i4|2=$7!$%F%9%H%G!<%?$r:n$kI,MW$,$"$j$^$9!%(B-f$B%*%W%7%g%s$r;H$C$FFH<+(B
|
||||
$B$N%H%i%s%6%/%7%g%s$rDj5A$9$k>l9g$O!$<+J,$G%G!<%?%Y!<%9$N=i4|2=$r$7$F$*(B
|
||||
$B$/I,MW$,$"$j$^$9!%(B
|
||||
|
||||
$ pgbench -i [$B%G!<%?%Y!<%9L>(B]
|
||||
|
||||
@ -146,8 +156,11 @@ accounts 100000
|
||||
history 0
|
||||
|
||||
$B%9%1!<%j%s%0%U%!%/%?!<$r(B 10,100,1000 $B$J$I$KJQ99$9$k$H!$>e5-%?%W%k?t$O(B
|
||||
$B$=$l$K1~$8$F(B10$BG\!$(B100$BG\!$(B1000$BG\$K$J$j$^$9!%$?$H$($P!$%9%1!<%j%s%0%U%!(B
|
||||
$B%/%?!<$r(B 10 $B$H$9$k$H!$(B
|
||||
$B$=$l$K1~$8$F(B10$BG\!$(B100$BG\!$(B1000$BG\$K$J$j$^$9!%%F!<%V%k$H%$%s%G%C%/%9$N%5(B
|
||||
$B%$%:$O%G!<%?%Y!<%9%5%$%:$O35$M$=$l$>$l!$(B130MB$B!$(B1.3GB$B!$(B13GB$B$[$I$K$J$j$^(B
|
||||
$B$9!%(B
|
||||
|
||||
$B$?$H$($P!$%9%1!<%j%s%0%U%!%/%?!<$r(B 10 $B$H$9$k$H!$(B
|
||||
|
||||
$B%F!<%V%kL>(B $B%?%W%k?t(B
|
||||
-------------------------
|
||||
@ -201,37 +214,69 @@ pgbench $B$G$O!$0J2<$N%7!<%1%s%9$rA4It40N;$7$F(B1$B%H%i%s%6%/%7%g%s$H?t$($F(
|
||||
|
||||
$B8=:_$N$H$3$m!$0J2<$N%a%?%3%^%s%I$,Dj5A$5$l$F$$$^$9!%(B
|
||||
|
||||
\set name operand1 [ operator operand2 ]
|
||||
$BHo1i;;?t(B operand1 $B$H(B operand2 $B$r1i;;;R(B operator $B$K$h$C$F1i;;$7(B
|
||||
$B$?7k2L$rJQ?t(B name $B$K@_Dj$7$^$9!%8=>u$G$O@0?t$N;MB'1i;;$N$_$KBP(B
|
||||
$B1~$7$F$$$^$9!%$J$*!$1i;;;R$H(B 2 $B$DL\$NHo1i;;?t$r>JN,$9$k$HC1=c(B
|
||||
$B$K(B 1 $B$DL\$NHo1i;;?t$rJQ?t$K@_Dj$7$^$9!%(B
|
||||
|
||||
$BJQ?t$K1i;;$N7k2L$r@_Dj$9$k$K$O!$(B\set $B%a%?%3%^%s%I$r;HMQ$7$F0J(B
|
||||
$B2<$N$h$&$K5-=R$7$^$9!%(B
|
||||
|
||||
\set ntellers 10 * :tps
|
||||
|
||||
$B$3$l$O!$JQ?t(B ntellers $B$K%9%1!<%j%s%0%U%!%/%?!<(B (-s $B%*%W%7%g%s(B
|
||||
$B$G;XDj$7$?(B) $B$r(B 10 $BG\$7$?7k2L$r@_Dj$7$^$9!%(B
|
||||
|
||||
\setrandom name min max
|
||||
|
||||
$B:G>.CM(B min $B$H:GBgCM(B max $B$N4V$NCM$r<h$kMp?t$r!$(Bname $BJQ?t$K@_Dj(B
|
||||
$B$7$^$9!%(B
|
||||
|
||||
$BJQ?t$KMp?t$r@_Dj$9$k$K$O!$(B\setrandom $B%a%?%3%^%s%I$r;HMQ$7$F0J2<$N$h$&(B
|
||||
$B$K5-=R$7$^$9!%(B
|
||||
$BJQ?t$KMp?t$r@_Dj$9$k$K$O!$(B\setrandom $B%a%?%3%^%s%I$r;HMQ$7$F0J2<$N$h$&(B
|
||||
$B$K5-=R$7$^$9!%(B
|
||||
|
||||
\setrandom aid 1 100000
|
||||
\setrandom aid 1 100000
|
||||
|
||||
$B$3$l$O!$JQ?t(B aid $B$K(B 1 $B$+$i(B 100000 $B$N4V$NMp?t$r@_Dj$7$^$9!%$^$?!$JQ?t$N(B
|
||||
$BCM$r(B SQL $B%3%^%s%I$KKd$a9~$`$K$O!$0J2<$N$h$&$K$=$NL>A0$NA0$K%3%m%s$rIU(B
|
||||
$B$1$^$9!%(B
|
||||
$B$3$l$O!$JQ?t(B aid $B$K(B 1 $B$+$i(B 100000 $B$N4V$NMp?t$r@_Dj$7$^$9!%(B
|
||||
|
||||
$BJQ?t$O(B SQL $B%3%^%s%I$*$h$S%a%?%3%^%s%I$+$i;2>H$G$-$^$9!%$=$l$K$O0J2<$N(B
|
||||
$B$h$&$KJQ?tL>$NA0$K%3%m%s$rIU$1$^$9!%(B
|
||||
|
||||
SELECT abalance FROM accounts WHERE aid = :aid
|
||||
|
||||
$BJQ?t$rDj5A$9$k$K$O%a%?%3%^%s%I0J30$K(B -D $B%*%W%7%g%s$r;HMQ$9$k$3$H$b$G$-(B
|
||||
$B$^$9!%(B -D $B%*%W%7%g%s$GDj5A$7$?JQ?t$bJQ?tL>$NA0$K%3%m%s$rIU$1$F;2>H$7$^(B
|
||||
$B$9!%(B
|
||||
|
||||
$BNc$($P!$(BTCP-B $B$KN`;w$7$?%Y%s%A%^!<%/$r7WB,$9$k$K$O!$0J2<$N$h$&$K%H%i%s(B
|
||||
$B%6%/%7%g%s$NFbMF$r%U%!%$%k$K5-=R$7!$(B-f $B%*%W%7%g%s$K$h$C$F$=$N%U%!%$%k(B
|
||||
$B$r;XDj$7$F(B pgbench $B$r<B9T$7$^$9!%(B
|
||||
|
||||
\setrandom aid 1 100000
|
||||
\setrandom bid 1 1
|
||||
\setrandom tid 1 10
|
||||
\set nbranches :tps
|
||||
\set ntellers 10 * :tps
|
||||
\set naccounts 100000 * :tps
|
||||
\setrandom aid 1 :naccounts
|
||||
\setrandom bid 1 :nbranches
|
||||
\setrandom tid 1 :ntellers
|
||||
\setrandom delta 1 10000
|
||||
BEGIN
|
||||
UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid
|
||||
SELECT abalance FROM accounts WHERE aid = :aid
|
||||
UPDATE tellers SET tbalance = tbalance + :delta WHERE tid = :tid
|
||||
UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid
|
||||
INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, 'now')
|
||||
INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, current_timestamp)
|
||||
END
|
||||
|
||||
$B%9%1!<%j%s%0%U%!%/%?!<$r(B branches $B%F!<%V%k$N%?%W%k?t$+$i<+F0E*$K@_Dj$7(B
|
||||
$B$?$$>l9g!$0J2<$N$h$&$K(B -s $B%*%W%7%g%s$H%7%'%k$N%3%^%s%ICV49$J$I$rAH$_9g(B
|
||||
$B$o$;$^$9!%(B
|
||||
|
||||
pgbench -s $(psql -At -c "SELECT count(*) FROM branches") -f tpc_b.sql
|
||||
|
||||
$B$J$*!$(B-f $B%*%W%7%g%s$r;XDj$7$?>l9g!$%Y%s%A%^!<%/3+;OA0$K(B vacuum $B$H(B
|
||||
history $B$N%/%j%"$O<+F0E*$K9T$o$l$^$;$s!%(B
|
||||
|
||||
$B"#:n<T$H%i%$%;%s%9>r7o(B
|
||||
|
||||
pgbench $B$O@P0f(B $BC#IW$K$h$C$F=q$+$l$^$7$?!%%i%$%;%s%9>r7o$O(B pgbench.c $B$N(B
|
||||
@ -240,6 +285,18 @@ 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
|
||||
|
||||
2006/07/26
|
||||
* $B:4F#$5$s$N%Q%C%A$rE,MQ!%0J2<$N5!G=DI2C!%(BPostgreSQL 8.2$B$K<h$j(B
|
||||
$B9~$^$l$^$9!%(B
|
||||
|
||||
$BJQ?t(B tps
|
||||
-s $B%*%W%7%g%s$G;XDj$7$?%9%1!<%j%s%0%U%!%/%?!<$r%U%!%$%kFb$GJQ?t$H$7(B
|
||||
$B$F;2>H$9$k5!G=(B
|
||||
-D $B%*%W%7%g%s(B
|
||||
$B%3%^%s%I$N%*%W%7%g%s$H$7$FDj5A$7$?JQ?t$r%U%!%$%kFb$+$i;2>H$9$k5!G=(B
|
||||
\set $B%3%^%s%I(B
|
||||
$B%U%!%$%kFb$G;MB'1i;;$r9T$$!"$=$N7k2L$rJQ?t$KBeF~$9$k5!G=(B
|
||||
|
||||
2005/09/29
|
||||
* $B:4F#$5$s$N%Q%C%A$rE,MQ!%(B-f $B%*%W%7%g%s$NDI2C!%(B
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.49 2005/12/10 01:09:07 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.50 2006/07/26 07:24:50 ishii Exp $
|
||||
*
|
||||
* pgbench: a simple benchmark program for PostgreSQL
|
||||
* written by Tatsuo Ishii
|
||||
@ -169,7 +169,7 @@ static char *select_only = {
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-f filename][-l][-U login][-P password][-d][dbname]\n");
|
||||
fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-D varname=value][-n][-C][-v][-S][-N][-f filename][-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");
|
||||
}
|
||||
|
||||
@ -552,26 +552,130 @@ top:
|
||||
|
||||
if (strcasecmp(argv[0], "setrandom") == 0)
|
||||
{
|
||||
char *val;
|
||||
char *var;
|
||||
int min,
|
||||
max;
|
||||
char res[64];
|
||||
|
||||
if ((val = malloc(strlen(argv[3]) + 1)) == NULL)
|
||||
if (*argv[2] == ':')
|
||||
{
|
||||
if ((var = getVariable(st, argv[2] + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[2]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
min = atoi(var);
|
||||
}
|
||||
else
|
||||
min = atoi(argv[2]);
|
||||
|
||||
if (min < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid minimum number %d\n", argv[0], min);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*argv[3] == ':')
|
||||
{
|
||||
if ((var = getVariable(st, argv[3] + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[3]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
max = atoi(var);
|
||||
}
|
||||
else
|
||||
max = atoi(argv[3]);
|
||||
|
||||
if (max < min || max > MAX_RANDOM_VALUE)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid maximum number %d\n", argv[0], max);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(res, sizeof(res), "%d", getrand(min, max));
|
||||
|
||||
if (putVariable(st, argv[1], res) == false)
|
||||
{
|
||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(val, "%d", getrand(atoi(argv[2]), atoi(argv[3])));
|
||||
st->listen = 1;
|
||||
}
|
||||
else if (strcasecmp(argv[0], "set") == 0)
|
||||
{
|
||||
char *var;
|
||||
int ope1,
|
||||
ope2;
|
||||
char res[64];
|
||||
|
||||
if (putVariable(st, argv[1], val) == false)
|
||||
if (*argv[2] == ':')
|
||||
{
|
||||
if ((var = getVariable(st, argv[2] + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[2]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
ope1 = atoi(var);
|
||||
}
|
||||
else
|
||||
ope1 = atoi(argv[2]);
|
||||
|
||||
if (argc < 5)
|
||||
snprintf(res, sizeof(res), "%d", ope1);
|
||||
else
|
||||
{
|
||||
if (*argv[4] == ':')
|
||||
{
|
||||
if ((var = getVariable(st, argv[4] + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[4]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
ope2 = atoi(var);
|
||||
}
|
||||
else
|
||||
ope2 = atoi(argv[4]);
|
||||
|
||||
if (strcmp(argv[3], "+") == 0)
|
||||
snprintf(res, sizeof(res), "%d", ope1 + ope2);
|
||||
else if (strcmp(argv[3], "-") == 0)
|
||||
snprintf(res, sizeof(res), "%d", ope1 - ope2);
|
||||
else if (strcmp(argv[3], "*") == 0)
|
||||
snprintf(res, sizeof(res), "%d", ope1 * ope2);
|
||||
else if (strcmp(argv[3], "/") == 0)
|
||||
{
|
||||
if (ope2 == 0)
|
||||
{
|
||||
fprintf(stderr, "%s: division by zero\n", argv[0]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
snprintf(res, sizeof(res), "%d", ope1 / ope2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: unsupported operator %s\n", argv[0], argv[3]);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (putVariable(st, argv[1], res) == false)
|
||||
{
|
||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
||||
free(val);
|
||||
st->ecnt++;
|
||||
return;
|
||||
}
|
||||
|
||||
free(val);
|
||||
st->listen = 1;
|
||||
}
|
||||
|
||||
@ -808,9 +912,6 @@ process_commands(char *buf)
|
||||
|
||||
if (strcasecmp(my_commands->argv[0], "setrandom") == 0)
|
||||
{
|
||||
int min,
|
||||
max;
|
||||
|
||||
if (my_commands->argc < 4)
|
||||
{
|
||||
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
|
||||
@ -820,20 +921,18 @@ process_commands(char *buf)
|
||||
for (j = 4; j < my_commands->argc; j++)
|
||||
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
|
||||
my_commands->argv[0], my_commands->argv[j]);
|
||||
|
||||
if ((min = atoi(my_commands->argv[2])) < 0)
|
||||
}
|
||||
else if (strcasecmp(my_commands->argv[0], "set") == 0)
|
||||
{
|
||||
if (my_commands->argc < 3)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid minimum number %s\n",
|
||||
my_commands->argv[0], my_commands->argv[2]);
|
||||
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((max = atoi(my_commands->argv[3])) < min || max > MAX_RANDOM_VALUE)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid maximum number %s\n",
|
||||
my_commands->argv[0], my_commands->argv[3]);
|
||||
return NULL;
|
||||
}
|
||||
for (j = my_commands->argc < 5 ? 3 : 5; j < my_commands->argc; j++)
|
||||
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
|
||||
my_commands->argv[0], my_commands->argv[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -889,10 +988,14 @@ process_file(char *filename)
|
||||
while (fgets(buf, sizeof(buf), fd) != NULL)
|
||||
{
|
||||
Command *commands;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (isspace((unsigned char) buf[i]))
|
||||
i++;
|
||||
|
||||
if (strncmp(buf, "\n", 1) != 0) {
|
||||
commands = process_commands(buf);
|
||||
if (strncmp(&buf[i], "\n", 1) != 0 && strncmp(&buf[i], "--", 2) != 0) {
|
||||
commands = process_commands(&buf[i]);
|
||||
if (commands == NULL)
|
||||
{
|
||||
fclose(fd);
|
||||
@ -1067,7 +1170,16 @@ main(int argc, char **argv)
|
||||
else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
|
||||
login = env;
|
||||
|
||||
while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSlf:")) != -1)
|
||||
state = (CState *) malloc(sizeof(CState));
|
||||
if (state == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for state\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSlf:D:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -1151,9 +1263,27 @@ main(int argc, char **argv)
|
||||
case 'f':
|
||||
ttype = 3;
|
||||
filename = optarg;
|
||||
if (process_file(filename) == false)
|
||||
if (process_file(filename) == false || *sql_files[num_files - 1] == NULL)
|
||||
exit(1);
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = strchr(optarg, '=')) == NULL || p == optarg || *(p + 1) == '\0')
|
||||
{
|
||||
fprintf(stderr, "invalid variable definition: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
if (putVariable(&state[0], optarg, p) == false)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for variable\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
@ -1181,14 +1311,43 @@ main(int argc, char **argv)
|
||||
|
||||
remains = nclients;
|
||||
|
||||
state = (CState *) malloc(sizeof(CState) * nclients);
|
||||
if (state == NULL)
|
||||
if (getVariable(&state[0], "tps") == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for state\n");
|
||||
exit(1);
|
||||
char val[64];
|
||||
|
||||
snprintf(val, sizeof(val), "%d", tps);
|
||||
if (putVariable(&state[0], "tps", val) == false)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for variable\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
memset(state, 0, sizeof(*state) * nclients);
|
||||
if (nclients > 1)
|
||||
{
|
||||
state = (CState *) realloc(state, sizeof(CState) * nclients);
|
||||
if (state == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for state\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(state + sizeof(*state), 0, sizeof(*state) * (nclients - 1));
|
||||
|
||||
for (i = 1; i < nclients; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < state[0].nvariables; j++)
|
||||
{
|
||||
if (putVariable(&state[i], state[0].variables[j].name, state[0].variables[j].value) == false)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate memory for variable\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_log)
|
||||
{
|
||||
@ -1357,8 +1516,19 @@ main(int argc, char **argv)
|
||||
/* send start up queries in async manner */
|
||||
for (i = 0; i < nclients; i++)
|
||||
{
|
||||
Command **commands = sql_files[state[i].use_file];
|
||||
int prev_ecnt = state[i].ecnt;
|
||||
|
||||
state[i].use_file = getrand(0, num_files - 1);
|
||||
doCustom(state, i, debug);
|
||||
|
||||
if (state[i].ecnt > prev_ecnt && commands[state[i].state]->type == META_COMMAND)
|
||||
{
|
||||
fprintf(stderr, "Client %d aborted in state %d. Execution meta-command failed.\n", i, state[i].state);
|
||||
remains--; /* I've aborted */
|
||||
PQfinish(state[i].con);
|
||||
state[i].con = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
@ -1424,12 +1594,21 @@ main(int argc, char **argv)
|
||||
for (i = 0; i < nclients; i++)
|
||||
{
|
||||
Command **commands = sql_files[state[i].use_file];
|
||||
int prev_ecnt = state[i].ecnt;
|
||||
|
||||
if (state[i].con && (FD_ISSET(PQsocket(state[i].con), &input_mask)
|
||||
|| commands[state[i].state]->type == META_COMMAND))
|
||||
{
|
||||
doCustom(state, i, debug);
|
||||
}
|
||||
|
||||
if (state[i].ecnt > prev_ecnt && commands[state[i].state]->type == META_COMMAND)
|
||||
{
|
||||
fprintf(stderr, "Client %d aborted in state %d. Execution meta-command failed.\n", i, state[i].state);
|
||||
remains--; /* I've aborted */
|
||||
PQfinish(state[i].con);
|
||||
state[i].con = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user