Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
9b19abd7
Commit
9b19abd7
authored
Sep 29, 2005
by
Tatsuo Ishii
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add -f option which enables to read SQL commands from a file.
Patches Contributed by Tomoaki Sato.
parent
8928d4d6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
666 additions
and
92 deletions
+666
-92
contrib/pgbench/README.pgbench
contrib/pgbench/README.pgbench
+58
-11
contrib/pgbench/README.pgbench_jis
contrib/pgbench/README.pgbench_jis
+65
-12
contrib/pgbench/pgbench.c
contrib/pgbench/pgbench.c
+543
-69
No files found.
contrib/pgbench/README.pgbench
View file @
9b19abd7
pgbench README 200
3/11/26 Tatsuo Ishii (t-ishii@sra.co.jp)
pgbench README 200
5/09/29 Tatsuo Ishii
o What is pgbench?
o What is pgbench?
...
@@ -34,16 +34,8 @@ o features of pgbench
...
@@ -34,16 +34,8 @@ o features of pgbench
o How to install pgbench
o How to install pgbench
(1) Configure and build the standard Postgres distribution.
$make
$make install
You can get away with just running configure at the top level
and doing "make all" in src/interfaces/libpq.
(2) Run make in this directory.
You will see an executable file "pgbench". You can run it here,
or install it with the standard Postgres programs by doing
"make install".
o How to use pgbench?
o How to use pgbench?
...
@@ -124,6 +116,15 @@ o options
...
@@ -124,6 +116,15 @@ o options
-S
-S
Perform select only transactions instead of TPC-B.
Perform select only transactions instead of TPC-B.
-N Do not update "branches" and "tellers". This will
avoid heavy update contention on branches and tellers,
while it will not make pgbench supporting TPC-B like
transactions.
-f filename
Read transaction script from file. Detailed
explanation will appear later.
-C
-C
Establish connection for each transaction, rather than
Establish connection for each transaction, rather than
doing it just once at beginning of pgbench in the normal
doing it just once at beginning of pgbench in the normal
...
@@ -158,12 +159,58 @@ o What is the "transaction" actually performed in pgbench?
...
@@ -158,12 +159,58 @@ o What is the "transaction" actually performed in pgbench?
(7) end;
(7) end;
o -f option
This supports for reading transaction script from a specified
file. This file should include SQL commands in each line. SQL
command consists of multiple lines are not supported. Empty lines
and lines begging with "--" will be ignored.
SQL commands can include "meta command" which begins with "\" (back
slash). A meta command takes some arguments separted by white
spaces. Currently following meta command is supported:
\setrandom name min max
assign random integer to name between min and max
example:
\setrandom aid 1 100000
variables can be reffered to in SQL comands by adding ":" in front
of the varible name.
example:
SELECT abalance FROM accounts WHERE aid = :aid
For 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
\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')
END
o License?
o License?
Basically it is same as BSD license. See pgbench.c for more details.
Basically it is same as BSD license. See pgbench.c for more details.
o History
o History
2005/09/29
* add -f option. contributed by Tomoaki Sato.
[updation records were missing]
2003/11/26
2003/11/26
* create indexes after data insertion to reduce time.
* create indexes after data insertion to reduce time.
patch from Yutaka Tanida.
patch from Yutaka Tanida.
...
...
contrib/pgbench/README.pgbench_jis
View file @
9b19abd7
pgbench README 200
3/11/26 Tatsuo Ishii (t-ishii@sra.co.jp)
pgbench README 200
5/09/29 Tatsuo Ishii
$B"#(Bpgbench $B$H$O!)(B
$B"#(Bpgbench $B$H$O!)(B
pgbench $B$O
(B TPC-B$B$K;w$?%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!%:#$N$H(B
pgbench $B$O
%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!%:#$N$H$3$m(B
$B$3$m(B
PostgreSQL $B@lMQ$G$9!%(B
PostgreSQL $B@lMQ$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<B9T;~4V$H<B:]$K40N;$7$?%H%i%s%6%/%7%g%s$N?t$+$i(B 1 $BIC4V$K<B9T$G$-$?%H(B
...
@@ -31,16 +31,12 @@ o pgbench $B$O(B libpq $B$NHsF14|=hM}5!G=$r;H$C$F%^%k%A%f!<%64D6-$r%7%_%e%l!<
...
@@ -31,16 +31,12 @@ o pgbench $B$O(B libpq $B$NHsF14|=hM}5!G=$r;H$C$F%^%k%A%f!<%64D6-$r%7%_%e%l!<
$B"#(Bpgbench $B$N%$%s%9%H!<%k(B
$B"#(Bpgbench $B$N%$%s%9%H!<%k(B
(1) PostgreSQL$B$r(Bconfigure$B!$%3%s%Q%$%k$7$^$9!%(Bpgbench$B$N%$%s%9%H!<%k$@$1(B
PostgreSQL$B$r%3%s%Q%$%k!$%$%s%9%H!<%k$7$?8e(B
$B$,L\E*$G$"$l$P!$(BPostgreSQL$B$N$9$Y$F$r%3%s%Q%$%k$9$kI,MW$O$"$j$^$;$s!%(B
PostgreSQL$B%=!<%9$N%H%C%W%G%#%l%/%H%j$G(Bconfigure$B$r$7$?8e!$(B
src/interface/libpq $B$G(B "make all" $B$r<B9T$9$l$P=`Hw40N;$G$9!%(B
(2) $B$3$N%G%#%l%/%H%j$G(B make $B$r<B9T$7$^$9!%$=$&$9$k$H!$(B"pgbench" $B$H$$$&(B
$ make
$B<B9T%W%m%0%i%`$,$G$-$^$9!%$=$N$^$^<B9T$7$F$b9=$$$^$;$s$7!$(B"make
$ make install
install" $B$r<B9T$7$F(B PostgreSQL $B$NI8=`<B9T%W%m%0%i%`%G%#%l%/%H%j(B
($B%G%U%)%k%H$G$O(B /usr/local/pgsql/bin) $B$K%$%s%9%H!<%k$9$k$3$H$b$G$-(B
$B$H$7$^$9!%(B
$B$^$9!%(B
$B"#(Bpgbench $B$N;H$$J}(B
$B"#(Bpgbench $B$N;H$$J}(B
...
@@ -104,6 +100,12 @@ pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B
...
@@ -104,6 +100,12 @@ 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
-f filename $B%H%i%s%6%/%7%g%s$NFbMF$,5-=R$5$l$?%U%!%$%kL>$r;XDj$7$^(B
$B$9!%$3$N%*%W%7%g%s$r;XDj$9$k$H!$%U%!%$%k$K5-=R$5$l$?Fb(B
$BMF$N%H%i%s%6%/%7%g%s$r<B9T$7$^$9!%$J$*!$%Y%s%A%^!<%/$N(B
$BBP>]$H$J$k%G!<%?%Y!<%9$O$"$i$+$8$a=i4|2=$7$F$*$/I,MW$,(B
$B$"$j$^$9!%F~NO%U%)!<%^%C%H$K$D$$$F$O8e=R$7$^$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
...
@@ -176,6 +178,52 @@ 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(
...
@@ -176,6 +178,52 @@ 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(
(7) end;
(7) end;
$B"#F~NO%U%!%$%k$N%U%)!<%^%C%H(B
pgbench $B$G$O!$(B-f $B%*%W%7%g%s$r;XDj$7$F%H%i%s%6%/%7%g%s$K4^$^$l$k(B SQL $B%3(B
$B%^%s%I$NFbMF$r5-=R$7$?%U%!%$%k$rFI$_9~$`$3$H$,$G$-$^$9!%F~NO%U%!%$%k$K(B
$B$O(B 1 $B9T$K$D$-(B 1 $B$D$N%3%^%s%I$r5-=R$7$^$9!%6u9T$OL5;k$5$l!$Fs=E%O%$%U%s(B
$B$G;O$^$k9T$O%3%a%s%H$r0UL#$7$^$9!%(B
$B%3%^%s%I$K$O!$(BSQL $B%3%^%s%I$K2C$(!$%P%C%/%9%i%C%7%e$G;O$^$k%a%?%3%^%s%I(B
$B$r5-=R$G$-$^$9!%%a%?%3%^%s%I$O(B pgbench $B<+?H$K$h$C$F<B9T$5$l$^$9!%%a%?(B
$B%3%^%s%I$N7A<0$O%P%C%/%9%i%C%7%e!$$=$ND>8e$K%3%^%s%I$NF0;l!$$=$N<!$K0z(B
$B?t$,B3$-$^$9!%F0;l%3%^%s%I$H0z?t!$$^$?$=$l$>$l$N0z?t$O6uGrJ8;z$K$h$C$F(B
$B6h@Z$i$l$^$9!%(B
$B8=:_$N$H$3$m!$0J2<$N%a%?%3%^%s%I$,Dj5A$5$l$F$$$^$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
\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
SELECT abalance FROM accounts WHERE aid = :aid
$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
\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')
END
$B"#:n<T$H%i%$%;%s%9>r7o(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
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
...
@@ -184,6 +232,11 @@ pgbench $B$O@P0f(B $BC#IW$K$h$C$F=q$+$l$^$7$?!%%i%$%;%s%9>r7o$O(B pgbench.c
...
@@ -184,6 +232,11 @@ 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
2005/09/29
* $B:4F#$5$s$N%Q%C%A$rE,MQ!%(B-f $B%*%W%7%g%s$NDI2C!%(B
[$B$3$N4V$$$m$$$mJQ99$,$"$C$?$h$&$@$,(BREADME$B$O%a%$%s%F%J%s%9$5$l$F$$$J$$(B]
2003/11/26
2003/11/26
* $BC+ED$5$s$N%Q%C%A$rE,MQ!%(Bpgbench -i$B$N:]$K!$8e$+$i<g%-!<$r:n@.(B
* $BC+ED$5$s$N%Q%C%A$rE,MQ!%(Bpgbench -i$B$N:]$K!$8e$+$i<g%-!<$r:n@.(B
$B$9$k$h$&$K$7$?!%$3$l$K$h$C$F=i4|2=$N<B9T;~4V$,BgI}$KC;=L$G$-(B
$B$9$k$h$&$K$7$?!%$3$l$K$h$C$F=i4|2=$N<B9T;~4V$,BgI}$KC;=L$G$-(B
...
...
contrib/pgbench/pgbench.c
View file @
9b19abd7
/*
/*
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.3
6 2005/05/24 00:26:40 neilc
Exp $
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.3
7 2005/09/29 13:44:25 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
*
*
* Copyright (c) 2000-200
4
Tatsuo Ishii
* Copyright (c) 2000-200
5
Tatsuo Ishii
*
*
* Permission to use, copy, modify, and distribute this software and
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* its documentation for any purpose and without fee is hereby
...
@@ -41,6 +41,9 @@
...
@@ -41,6 +41,9 @@
#include <sys/resource.h>
#include <sys/resource.h>
#endif
/* ! WIN32 */
#endif
/* ! WIN32 */
#include <ctype.h>
#include <search.h>
extern
char
*
optarg
;
extern
char
*
optarg
;
extern
int
optind
;
extern
int
optind
;
...
@@ -72,6 +75,9 @@ int tps = 1;
...
@@ -72,6 +75,9 @@ int tps = 1;
#define ntellers 10
#define ntellers 10
#define naccounts 100000
#define naccounts 100000
#define SQL_COMMAND 1
#define META_COMMAND 2
FILE
*
LOGFILE
=
NULL
;
FILE
*
LOGFILE
=
NULL
;
bool
use_log
;
/* log transaction latencies to a file */
bool
use_log
;
/* log transaction latencies to a file */
...
@@ -89,6 +95,12 @@ char *login = NULL;
...
@@ -89,6 +95,12 @@ char *login = NULL;
char
*
pwd
=
NULL
;
char
*
pwd
=
NULL
;
char
*
dbName
;
char
*
dbName
;
typedef
struct
{
char
*
name
;
char
*
value
;
}
Variable
;
typedef
struct
typedef
struct
{
{
PGconn
*
con
;
/* connection handle to DB */
PGconn
*
con
;
/* connection handle to DB */
...
@@ -103,13 +115,23 @@ typedef struct
...
@@ -103,13 +115,23 @@ typedef struct
int
tid
;
/* teller id for this transaction */
int
tid
;
/* teller id for this transaction */
int
delta
;
int
delta
;
int
abalance
;
int
abalance
;
void
*
variables
;
struct
timeval
txn_begin
;
/* used for measuring latencies */
struct
timeval
txn_begin
;
/* used for measuring latencies */
}
CState
;
}
CState
;
typedef
struct
{
int
type
;
int
argc
;
char
**
argv
;
}
Command
;
Command
**
commands
=
NULL
;
static
void
static
void
usage
(
void
)
usage
(
void
)
{
{
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
,
"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
,
"(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
"
);
}
}
...
@@ -190,6 +212,115 @@ check(CState * state, PGresult *res, int n, int good)
...
@@ -190,6 +212,115 @@ check(CState * state, PGresult *res, int n, int good)
return
(
0
);
/* OK */
return
(
0
);
/* OK */
}
}
static
int
compareVariables
(
const
void
*
v1
,
const
void
*
v2
)
{
return
strcmp
(((
Variable
*
)
v1
)
->
name
,
((
Variable
*
)
v2
)
->
name
);
}
static
char
*
getVariable
(
CState
*
st
,
char
*
name
)
{
Variable
key
=
{
name
},
*
var
;
var
=
tfind
(
&
key
,
&
st
->
variables
,
compareVariables
);
if
(
var
!=
NULL
)
return
(
*
(
Variable
**
)
var
)
->
value
;
else
return
NULL
;
}
static
int
putVariable
(
CState
*
st
,
char
*
name
,
char
*
value
)
{
Variable
key
=
{
name
},
*
var
;
var
=
tfind
(
&
key
,
&
st
->
variables
,
compareVariables
);
if
(
var
==
NULL
)
{
if
((
var
=
malloc
(
sizeof
(
Variable
)))
==
NULL
)
return
false
;
var
->
name
=
NULL
;
var
->
value
=
NULL
;
if
((
var
->
name
=
strdup
(
name
))
==
NULL
||
(
var
->
value
=
strdup
(
value
))
==
NULL
||
tsearch
(
var
,
&
st
->
variables
,
compareVariables
)
==
NULL
)
{
free
(
var
->
name
);
free
(
var
->
value
);
free
(
var
);
return
false
;
}
}
else
{
free
((
*
(
Variable
**
)
var
)
->
value
);
if
(((
*
(
Variable
**
)
var
)
->
value
=
strdup
(
value
))
==
NULL
)
return
false
;
}
return
true
;
}
static
char
*
assignVariables
(
CState
*
st
,
char
*
sql
)
{
int
i
,
j
;
char
*
p
,
*
name
,
*
val
;
void
*
tmp
;
i
=
0
;
while
((
p
=
strchr
(
&
sql
[
i
],
':'
))
!=
NULL
)
{
i
=
j
=
p
-
sql
;
do
i
++
;
while
(
isalnum
(
sql
[
i
])
!=
0
||
sql
[
i
]
==
'_'
);
if
(
i
==
j
+
1
)
continue
;
if
((
name
=
strndup
(
&
sql
[
j
+
1
],
i
-
(
j
+
1
)))
==
NULL
)
return
NULL
;
val
=
getVariable
(
st
,
name
);
free
(
name
);
if
(
val
==
NULL
)
continue
;
if
(
strlen
(
val
)
>
i
-
j
)
{
tmp
=
realloc
(
sql
,
strlen
(
sql
)
-
(
i
-
j
)
+
strlen
(
val
)
+
1
);
if
(
tmp
==
NULL
)
{
free
(
sql
);
return
NULL
;
}
sql
=
tmp
;
}
if
(
strlen
(
val
)
!=
i
-
j
)
memmove
(
&
sql
[
j
+
strlen
(
val
)],
&
sql
[
i
],
strlen
(
&
sql
[
i
])
+
1
);
strncpy
(
&
sql
[
j
],
val
,
strlen
(
val
));
if
(
strlen
(
val
)
<
i
-
j
)
{
tmp
=
realloc
(
sql
,
strlen
(
sql
)
+
1
);
if
(
tmp
==
NULL
)
{
free
(
sql
);
return
NULL
;
}
sql
=
tmp
;
}
i
=
j
+
strlen
(
val
);
}
return
sql
;
}
/* process a transaction */
/* process a transaction */
static
void
static
void
doOne
(
CState
*
state
,
int
n
,
int
debug
,
int
ttype
)
doOne
(
CState
*
state
,
int
n
,
int
debug
,
int
ttype
)
...
@@ -465,6 +596,170 @@ doSelectOnly(CState * state, int n, int debug)
...
@@ -465,6 +596,170 @@ doSelectOnly(CState * state, int n, int debug)
}
}
}
}
static
void
doCustom
(
CState
*
state
,
int
n
,
int
debug
)
{
PGresult
*
res
;
CState
*
st
=
&
state
[
n
];
if
(
st
->
listen
)
{
/* are we receiver? */
if
(
commands
[
st
->
state
]
->
type
==
SQL_COMMAND
)
{
if
(
debug
)
fprintf
(
stderr
,
"client %d receiving
\n
"
,
n
);
if
(
!
PQconsumeInput
(
st
->
con
))
{
/* there's something wrong */
fprintf
(
stderr
,
"Client %d aborted in state %d. Probably the backend died while processing.
\n
"
,
n
,
st
->
state
);
remains
--
;
/* I've aborted */
PQfinish
(
st
->
con
);
st
->
con
=
NULL
;
return
;
}
if
(
PQisBusy
(
st
->
con
))
return
;
/* don't have the whole result yet */
}
/*
* transaction finished: record the time it took in the
* log
*/
if
(
use_log
&&
commands
[
st
->
state
+
1
]
==
NULL
)
{
double
diff
;
struct
timeval
now
;
gettimeofday
(
&
now
,
NULL
);
diff
=
(
int
)
(
now
.
tv_sec
-
st
->
txn_begin
.
tv_sec
)
*
1000000
.
0
+
(
int
)
(
now
.
tv_usec
-
st
->
txn_begin
.
tv_usec
);
fprintf
(
LOGFILE
,
"%d %d %.0f
\n
"
,
st
->
id
,
st
->
cnt
,
diff
);
}
if
(
commands
[
st
->
state
]
->
type
==
SQL_COMMAND
)
{
res
=
PQgetResult
(
st
->
con
);
if
(
strncasecmp
(
commands
[
st
->
state
]
->
argv
[
0
],
"select"
,
6
)
!=
0
)
{
if
(
check
(
state
,
res
,
n
,
PGRES_COMMAND_OK
))
return
;
}
else
{
if
(
check
(
state
,
res
,
n
,
PGRES_TUPLES_OK
))
return
;
}
PQclear
(
res
);
discard_response
(
st
);
}
if
(
commands
[
st
->
state
+
1
]
==
NULL
)
{
if
(
is_connect
)
{
PQfinish
(
st
->
con
);
st
->
con
=
NULL
;
}
if
(
++
st
->
cnt
>=
nxacts
)
{
remains
--
;
/* I'm done */
if
(
st
->
con
!=
NULL
)
{
PQfinish
(
st
->
con
);
st
->
con
=
NULL
;
}
return
;
}
}
/* increment state counter */
st
->
state
++
;
if
(
commands
[
st
->
state
]
==
NULL
)
st
->
state
=
0
;
}
if
(
st
->
con
==
NULL
)
{
if
((
st
->
con
=
doConnect
())
==
NULL
)
{
fprintf
(
stderr
,
"Client %d aborted in establishing connection.
\n
"
,
n
);
remains
--
;
/* I've aborted */
PQfinish
(
st
->
con
);
st
->
con
=
NULL
;
return
;
}
}
if
(
use_log
&&
st
->
state
==
0
)
gettimeofday
(
&
(
st
->
txn_begin
),
NULL
);
if
(
commands
[
st
->
state
]
->
type
==
SQL_COMMAND
)
{
char
*
sql
;
if
((
sql
=
strdup
(
commands
[
st
->
state
]
->
argv
[
0
]))
==
NULL
||
(
sql
=
assignVariables
(
st
,
sql
))
==
NULL
)
{
fprintf
(
stderr
,
"out of memory
\n
"
);
st
->
ecnt
++
;
return
;
}
if
(
debug
)
fprintf
(
stderr
,
"client %d sending %s
\n
"
,
n
,
sql
);
if
(
PQsendQuery
(
st
->
con
,
sql
)
==
0
)
{
if
(
debug
)
fprintf
(
stderr
,
"PQsendQuery(%s)failed
\n
"
,
sql
);
st
->
ecnt
++
;
}
else
{
st
->
listen
++
;
/* flags that should be listened */
}
}
else
if
(
commands
[
st
->
state
]
->
type
==
META_COMMAND
)
{
int
argc
=
commands
[
st
->
state
]
->
argc
,
i
;
char
**
argv
=
commands
[
st
->
state
]
->
argv
;
if
(
debug
)
{
fprintf
(
stderr
,
"client %d executing
\\
%s"
,
n
,
argv
[
0
]);
for
(
i
=
1
;
i
<
argc
;
i
++
)
fprintf
(
stderr
,
" %s"
,
argv
[
i
]);
fprintf
(
stderr
,
"
\n
"
);
}
if
(
strcasecmp
(
argv
[
0
],
"setrandom"
)
==
0
)
{
char
*
val
;
if
((
val
=
malloc
(
strlen
(
argv
[
3
])
+
1
))
==
NULL
)
{
fprintf
(
stderr
,
"%s: out of memory
\n
"
,
argv
[
0
]);
st
->
ecnt
++
;
return
;
}
sprintf
(
val
,
"%d"
,
getrand
(
atoi
(
argv
[
2
]),
atoi
(
argv
[
3
])));
if
(
putVariable
(
st
,
argv
[
1
],
val
)
==
false
)
{
fprintf
(
stderr
,
"%s: out of memory
\n
"
,
argv
[
0
]);
free
(
val
);
st
->
ecnt
++
;
return
;
}
free
(
val
);
st
->
listen
++
;
}
}
}
/* discard connections */
/* discard connections */
static
void
static
void
disconnect_all
(
CState
*
state
)
disconnect_all
(
CState
*
state
)
...
@@ -644,6 +939,160 @@ init(void)
...
@@ -644,6 +939,160 @@ init(void)
PQfinish
(
con
);
PQfinish
(
con
);
}
}
static
int
process_file
(
char
*
filename
)
{
const
char
delim
[]
=
"
\f\n\r\t\v
"
;
FILE
*
fd
;
int
lineno
,
i
,
j
;
char
buf
[
BUFSIZ
],
*
p
,
*
tok
;
void
*
tmp
;
if
(
strcmp
(
filename
,
"-"
)
==
0
)
fd
=
stdin
;
else
if
((
fd
=
fopen
(
filename
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"%s: %s
\n
"
,
strerror
(
errno
),
filename
);
return
false
;
}
fprintf
(
stderr
,
"processing file...
\n
"
);
lineno
=
1
;
i
=
0
;
while
(
fgets
(
buf
,
sizeof
(
buf
),
fd
)
!=
NULL
)
{
if
((
p
=
strchr
(
buf
,
'\n'
))
!=
NULL
)
*
p
=
'\0'
;
p
=
buf
;
while
(
isspace
(
*
p
))
p
++
;
if
(
*
p
==
'\0'
||
strncmp
(
p
,
"--"
,
2
)
==
0
)
{
lineno
++
;
continue
;
}
if
((
tmp
=
realloc
(
commands
,
sizeof
(
Command
*
)
*
(
i
+
1
)))
==
NULL
)
{
i
--
;
goto
error
;
}
commands
=
tmp
;
if
((
commands
[
i
]
=
malloc
(
sizeof
(
Command
)))
==
NULL
)
goto
error
;
commands
[
i
]
->
argv
=
NULL
;
commands
[
i
]
->
argc
=
0
;
if
(
*
p
==
'\\'
)
{
commands
[
i
]
->
type
=
META_COMMAND
;
j
=
0
;
tok
=
strtok
(
++
p
,
delim
);
while
(
tok
!=
NULL
)
{
tmp
=
realloc
(
commands
[
i
]
->
argv
,
sizeof
(
char
*
)
*
(
j
+
1
));
if
(
tmp
==
NULL
)
goto
error
;
commands
[
i
]
->
argv
=
tmp
;
if
((
commands
[
i
]
->
argv
[
j
]
=
strdup
(
tok
))
==
NULL
)
goto
error
;
commands
[
i
]
->
argc
++
;
j
++
;
tok
=
strtok
(
NULL
,
delim
);
}
if
(
strcasecmp
(
commands
[
i
]
->
argv
[
0
],
"setrandom"
)
==
0
)
{
int
min
,
max
;
if
(
commands
[
i
]
->
argc
<
4
)
{
fprintf
(
stderr
,
"%s: %d:
\\
%s: missing argument
\n
"
,
filename
,
lineno
,
commands
[
i
]
->
argv
[
0
]);
goto
error
;
}
for
(
j
=
4
;
j
<
commands
[
i
]
->
argc
;
j
++
)
fprintf
(
stderr
,
"%s: %d:
\\
%s: extra argument
\"
%s
\"
ignored
\n
"
,
filename
,
lineno
,
commands
[
i
]
->
argv
[
0
],
commands
[
i
]
->
argv
[
j
]);
if
((
min
=
atoi
(
commands
[
i
]
->
argv
[
2
]))
<
0
)
{
fprintf
(
stderr
,
"%s: %d:
\\
%s: invalid minimum number %s
\n
"
,
filename
,
lineno
,
commands
[
i
]
->
argv
[
0
],
commands
[
i
]
->
argv
[
2
]);
goto
error
;
}
if
((
max
=
atoi
(
commands
[
i
]
->
argv
[
3
]))
<
min
||
max
>
RAND_MAX
)
{
fprintf
(
stderr
,
"%s: %d:
\\
%s: invalid maximum number %s
\n
"
,
filename
,
lineno
,
commands
[
i
]
->
argv
[
0
],
commands
[
i
]
->
argv
[
3
]);
goto
error
;
}
}
else
{
fprintf
(
stderr
,
"%s: %d: invalid command
\\
%s
\n
"
,
filename
,
lineno
,
commands
[
i
]
->
argv
[
0
]);
goto
error
;
}
}
else
{
commands
[
i
]
->
type
=
SQL_COMMAND
;
if
((
commands
[
i
]
->
argv
=
malloc
(
sizeof
(
char
*
)))
==
NULL
)
goto
error
;
if
((
commands
[
i
]
->
argv
[
0
]
=
strdup
(
p
))
==
NULL
)
goto
error
;
commands
[
i
]
->
argc
++
;
}
i
++
;
lineno
++
;
}
fclose
(
fd
);
if
((
tmp
=
realloc
(
commands
,
sizeof
(
Command
*
)
*
(
i
+
1
)))
==
NULL
)
goto
error
;
commands
=
tmp
;
commands
[
i
]
=
NULL
;
return
true
;
error:
if
(
errno
==
ENOMEM
)
fprintf
(
stderr
,
"%s: %d: out of memory
\n
"
,
filename
,
lineno
);
fclose
(
fd
);
if
(
commands
==
NULL
)
return
false
;
while
(
i
>=
0
)
{
if
(
commands
[
i
]
!=
NULL
)
{
for
(
j
=
0
;
j
<
commands
[
i
]
->
argc
;
j
++
)
free
(
commands
[
i
]
->
argv
[
j
]);
free
(
commands
[
i
]
->
argv
);
free
(
commands
[
i
]);
}
i
--
;
}
free
(
commands
);
return
false
;
}
/* print out results */
/* print out results */
static
void
static
void
printResults
(
printResults
(
...
@@ -670,8 +1119,10 @@ printResults(
...
@@ -670,8 +1119,10 @@ printResults(
s
=
"TPC-B (sort of)"
;
s
=
"TPC-B (sort of)"
;
else
if
(
ttype
==
2
)
else
if
(
ttype
==
2
)
s
=
"Update only accounts"
;
s
=
"Update only accounts"
;
else
else
if
(
ttype
==
1
)
s
=
"SELECT only"
;
s
=
"SELECT only"
;
else
s
=
"Custom query"
;
printf
(
"transaction type: %s
\n
"
,
s
);
printf
(
"transaction type: %s
\n
"
,
s
);
printf
(
"scaling factor: %d
\n
"
,
tps
);
printf
(
"scaling factor: %d
\n
"
,
tps
);
...
@@ -695,6 +1146,7 @@ main(int argc, char **argv)
...
@@ -695,6 +1146,7 @@ main(int argc, char **argv)
int
ttype
=
0
;
/* transaction type. 0: TPC-B, 1: SELECT
int
ttype
=
0
;
/* transaction type. 0: TPC-B, 1: SELECT
* only, 2: skip update of branches and
* only, 2: skip update of branches and
* tellers */
* tellers */
char
*
filename
=
NULL
;
static
CState
*
state
;
/* status of clients */
static
CState
*
state
;
/* status of clients */
...
@@ -724,7 +1176,7 @@ main(int argc, char **argv)
...
@@ -724,7 +1176,7 @@ main(int argc, char **argv)
else
if
((
env
=
getenv
(
"PGUSER"
))
!=
NULL
&&
*
env
!=
'\0'
)
else
if
((
env
=
getenv
(
"PGUSER"
))
!=
NULL
&&
*
env
!=
'\0'
)
login
=
env
;
login
=
env
;
while
((
c
=
getopt
(
argc
,
argv
,
"ih:nvp:dc:t:s:U:P:CNSl"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"ih:nvp:dc:t:s:U:P:CNSl
f:
"
))
!=
-
1
)
{
{
switch
(
c
)
switch
(
c
)
{
{
...
@@ -806,6 +1258,10 @@ main(int argc, char **argv)
...
@@ -806,6 +1258,10 @@ main(int argc, char **argv)
case
'l'
:
case
'l'
:
use_log
=
true
;
use_log
=
true
;
break
;
break
;
case
'f'
:
ttype
=
3
;
filename
=
optarg
;
break
;
default:
default:
usage
();
usage
();
exit
(
1
);
exit
(
1
);
...
@@ -868,74 +1324,83 @@ main(int argc, char **argv)
...
@@ -868,74 +1324,83 @@ main(int argc, char **argv)
exit
(
1
);
exit
(
1
);
}
}
/*
if
(
ttype
==
3
)
* get the scaling factor that should be same as count(*) from
* branches...
*/
res
=
PQexec
(
con
,
"select count(*) from branches"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_TUPLES_OK
)
{
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
PQfinish
(
con
);
exit
(
1
);
if
(
process_file
(
filename
)
==
false
)
}
exit
(
1
);
tps
=
atoi
(
PQgetvalue
(
res
,
0
,
0
));
if
(
tps
<
0
)
{
fprintf
(
stderr
,
"count(*) from branches invalid (%d)
\n
"
,
tps
);
exit
(
1
);
}
}
PQclear
(
res
);
else
if
(
!
is_no_vacuum
)
{
{
fprintf
(
stderr
,
"starting vacuum..."
);
/*
res
=
PQexec
(
con
,
"vacuum branches"
);
* get the scaling factor that should be same as count(*) from
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
* branches...
*/
res
=
PQexec
(
con
,
"select count(*) from branches"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_TUPLES_OK
)
{
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
exit
(
1
);
exit
(
1
);
}
}
PQclear
(
res
);
tps
=
atoi
(
PQgetvalue
(
res
,
0
,
0
));
if
(
tps
<
0
)
res
=
PQexec
(
con
,
"vacuum tellers"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
{
{
fprintf
(
stderr
,
"
%s"
,
PQerrorMessage
(
con
)
);
fprintf
(
stderr
,
"
count(*) from branches invalid (%d)
\n
"
,
tps
);
exit
(
1
);
exit
(
1
);
}
}
PQclear
(
res
);
PQclear
(
res
);
res
=
PQexec
(
con
,
"delete from history"
);
if
(
!
is_no_vacuum
)
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
{
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
fprintf
(
stderr
,
"starting vacuum..."
);
exit
(
1
);
res
=
PQexec
(
con
,
"vacuum branches"
);
}
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
PQclear
(
res
);
{
res
=
PQexec
(
con
,
"vacuum history"
);
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
exit
(
1
);
{
}
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
PQclear
(
res
);
exit
(
1
);
}
PQclear
(
res
);
fprintf
(
stderr
,
"end.
\n
"
);
res
=
PQexec
(
con
,
"vacuum tellers"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
exit
(
1
);
}
PQclear
(
res
);
if
(
is_full_vacuum
)
res
=
PQexec
(
con
,
"delete from history"
);
{
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
fprintf
(
stderr
,
"starting full vacuum..."
);
{
res
=
PQexec
(
con
,
"vacuum analyze accounts"
);
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
exit
(
1
);
}
PQclear
(
res
);
res
=
PQexec
(
con
,
"vacuum history"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
{
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
exit
(
1
);
exit
(
1
);
}
}
PQclear
(
res
);
PQclear
(
res
);
fprintf
(
stderr
,
"end.
\n
"
);
fprintf
(
stderr
,
"end.
\n
"
);
if
(
is_full_vacuum
)
{
fprintf
(
stderr
,
"starting full vacuum..."
);
res
=
PQexec
(
con
,
"vacuum analyze accounts"
);
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
con
));
exit
(
1
);
}
PQclear
(
res
);
fprintf
(
stderr
,
"end.
\n
"
);
}
}
}
PQfinish
(
con
);
}
}
PQfinish
(
con
);
/* set random seed */
/* set random seed */
gettimeofday
(
&
tv1
,
NULL
);
gettimeofday
(
&
tv1
,
NULL
);
...
@@ -965,6 +1430,8 @@ main(int argc, char **argv)
...
@@ -965,6 +1430,8 @@ main(int argc, char **argv)
doOne
(
state
,
i
,
debug
,
ttype
);
doOne
(
state
,
i
,
debug
,
ttype
);
else
if
(
ttype
==
1
)
else
if
(
ttype
==
1
)
doSelectOnly
(
state
,
i
,
debug
);
doSelectOnly
(
state
,
i
,
debug
);
else
if
(
ttype
==
3
)
doCustom
(
state
,
i
,
debug
);
}
}
for
(;;)
for
(;;)
...
@@ -982,16 +1449,16 @@ main(int argc, char **argv)
...
@@ -982,16 +1449,16 @@ main(int argc, char **argv)
FD_ZERO
(
&
input_mask
);
FD_ZERO
(
&
input_mask
);
maxsock
=
0
;
maxsock
=
-
1
;
for
(
i
=
0
;
i
<
nclients
;
i
++
)
for
(
i
=
0
;
i
<
nclients
;
i
++
)
{
{
if
(
state
[
i
].
con
)
if
(
state
[
i
].
con
&&
(
ttype
!=
3
||
commands
[
state
[
i
].
state
]
->
type
!=
META_COMMAND
))
{
{
int
sock
=
PQsocket
(
state
[
i
].
con
);
int
sock
=
PQsocket
(
state
[
i
].
con
);
if
(
sock
<
0
)
if
(
sock
<
0
)
{
{
fprintf
(
stderr
,
"Client %d: PQsocket failed
\n
"
,
i
);
disconnect_all
(
state
);
disconnect_all
(
state
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -1001,36 +1468,43 @@ main(int argc, char **argv)
...
@@ -1001,36 +1468,43 @@ main(int argc, char **argv)
}
}
}
}
if
((
nsocks
=
select
(
maxsock
+
1
,
&
input_mask
,
(
fd_set
*
)
NULL
,
if
(
maxsock
!=
-
1
)
(
fd_set
*
)
NULL
,
(
struct
timeval
*
)
NULL
))
<
0
)
{
{
if
(
errno
==
EINTR
)
if
((
nsocks
=
select
(
maxsock
+
1
,
&
input_mask
,
(
fd_set
*
)
NULL
,
continue
;
(
fd_set
*
)
NULL
,
(
struct
timeval
*
)
NULL
))
<
0
)
/* must be something wrong */
disconnect_all
(
state
);
fprintf
(
stderr
,
"select failed: %s
\n
"
,
strerror
(
errno
));
exit
(
1
);
}
else
if
(
nsocks
==
0
)
{
/* timeout */
fprintf
(
stderr
,
"select timeout
\n
"
);
for
(
i
=
0
;
i
<
nclients
;
i
++
)
{
{
fprintf
(
stderr
,
"client %d:state %d cnt %d ecnt %d listen %d
\n
"
,
if
(
errno
==
EINTR
)
i
,
state
[
i
].
state
,
state
[
i
].
cnt
,
state
[
i
].
ecnt
,
state
[
i
].
listen
);
continue
;
/* must be something wrong */
disconnect_all
(
state
);
fprintf
(
stderr
,
"select failed: %s
\n
"
,
strerror
(
errno
));
exit
(
1
);
}
else
if
(
nsocks
==
0
)
{
/* timeout */
fprintf
(
stderr
,
"select timeout
\n
"
);
for
(
i
=
0
;
i
<
nclients
;
i
++
)
{
fprintf
(
stderr
,
"client %d:state %d cnt %d ecnt %d listen %d
\n
"
,
i
,
state
[
i
].
state
,
state
[
i
].
cnt
,
state
[
i
].
ecnt
,
state
[
i
].
listen
);
}
exit
(
0
);
}
}
exit
(
0
);
}
}
/* ok, backend returns reply */
/* ok, backend returns reply */
for
(
i
=
0
;
i
<
nclients
;
i
++
)
for
(
i
=
0
;
i
<
nclients
;
i
++
)
{
{
if
(
state
[
i
].
con
&&
FD_ISSET
(
PQsocket
(
state
[
i
].
con
),
&
input_mask
))
if
(
state
[
i
].
con
&&
(
FD_ISSET
(
PQsocket
(
state
[
i
].
con
),
&
input_mask
)
||
(
ttype
==
3
&&
commands
[
state
[
i
].
state
]
->
type
==
META_COMMAND
)))
{
{
if
(
ttype
==
0
||
ttype
==
2
)
if
(
ttype
==
0
||
ttype
==
2
)
doOne
(
state
,
i
,
debug
,
ttype
);
doOne
(
state
,
i
,
debug
,
ttype
);
else
if
(
ttype
==
1
)
else
if
(
ttype
==
1
)
doSelectOnly
(
state
,
i
,
debug
);
doSelectOnly
(
state
,
i
,
debug
);
else
if
(
ttype
==
3
)
doCustom
(
state
,
i
,
debug
);
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment