Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
49639a7b
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
49639a7b
编写于
3月 19, 2008
作者:
T
Tatsuo Ishii
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add -M (query mode) option per ITAGAKI Takahiro
上级
965a2a19
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
256 addition
and
64 deletion
+256
-64
contrib/pgbench/pgbench.c
contrib/pgbench/pgbench.c
+238
-63
doc/src/sgml/pgbench.sgml
doc/src/sgml/pgbench.sgml
+18
-1
未找到文件。
contrib/pgbench/pgbench.c
浏览文件 @
49639a7b
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* A simple benchmark program for PostgreSQL
* A simple benchmark program for PostgreSQL
* Originally written by Tatsuo Ishii and enhanced by many contributors.
* Originally written by Tatsuo Ishii and enhanced by many contributors.
*
*
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.7
8 2008/03/19 00:29:35
ishii Exp $
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.7
9 2008/03/19 03:33:21
ishii Exp $
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED;
* ALL RIGHTS RESERVED;
*
*
...
@@ -112,6 +112,8 @@ typedef struct
...
@@ -112,6 +112,8 @@ typedef struct
char
*
value
;
/* its value */
char
*
value
;
/* its value */
}
Variable
;
}
Variable
;
#define MAX_FILES 128
/* max number of SQL script files allowed */
/*
/*
* structures used in custom query mode
* structures used in custom query mode
*/
*/
...
@@ -131,6 +133,7 @@ typedef struct
...
@@ -131,6 +133,7 @@ typedef struct
int
nvariables
;
int
nvariables
;
struct
timeval
txn_begin
;
/* used for measuring latencies */
struct
timeval
txn_begin
;
/* used for measuring latencies */
int
use_file
;
/* index in sql_files for this client */
int
use_file
;
/* index in sql_files for this client */
bool
prepared
[
MAX_FILES
];
}
CState
;
}
CState
;
/*
/*
...
@@ -140,6 +143,17 @@ typedef struct
...
@@ -140,6 +143,17 @@ typedef struct
#define META_COMMAND 2
#define META_COMMAND 2
#define MAX_ARGS 10
#define MAX_ARGS 10
typedef
enum
QueryMode
{
QUERY_SIMPLE
,
/* simple query */
QUERY_EXTENDED
,
/* extended query */
QUERY_PREPARED
,
/* extended query with prepared statements */
NUM_QUERYMODE
}
QueryMode
;
static
QueryMode
querymode
=
QUERY_SIMPLE
;
static
const
char
*
QUERYMODE
[]
=
{
"simple"
,
"extended"
,
"prepared"
};
typedef
struct
typedef
struct
{
{
int
type
;
/* command type (SQL_COMMAND or META_COMMAND) */
int
type
;
/* command type (SQL_COMMAND or META_COMMAND) */
...
@@ -147,8 +161,6 @@ typedef struct
...
@@ -147,8 +161,6 @@ typedef struct
char
*
argv
[
MAX_ARGS
];
/* command list */
char
*
argv
[
MAX_ARGS
];
/* command list */
}
Command
;
}
Command
;
#define MAX_FILES 128
/* max number of SQL script files allowed */
Command
**
sql_files
[
MAX_FILES
];
/* SQL script files */
Command
**
sql_files
[
MAX_FILES
];
/* SQL script files */
int
num_files
;
/* its number */
int
num_files
;
/* its number */
...
@@ -229,7 +241,7 @@ diffTime(struct timeval *t1, struct timeval *t2, struct timeval *result)
...
@@ -229,7 +241,7 @@ diffTime(struct timeval *t1, struct timeval *t2, struct timeval *result)
static
void
static
void
usage
(
void
)
usage
(
void
)
{
{
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][-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][-
M querymode][-
f filename][-l][-U login][-d][dbname]
\n
"
);
fprintf
(
stderr
,
"(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor] [-F fillfactor] [-U login][-d][dbname]
\n
"
);
fprintf
(
stderr
,
"(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor] [-F fillfactor] [-U login][-d][dbname]
\n
"
);
}
}
...
@@ -439,68 +451,104 @@ putVariable(CState * st, char *name, char *value)
...
@@ -439,68 +451,104 @@ putVariable(CState * st, char *name, char *value)
return
true
;
return
true
;
}
}
static
char
*
parseVariable
(
const
char
*
sql
,
int
*
eaten
)
{
int
i
=
0
;
char
*
name
;
do
{
i
++
;
}
while
(
isalnum
((
unsigned
char
)
sql
[
i
])
||
sql
[
i
]
==
'_'
);
if
(
i
==
1
)
return
NULL
;
name
=
malloc
(
i
);
if
(
name
==
NULL
)
return
NULL
;
memcpy
(
name
,
&
sql
[
1
],
i
-
1
);
name
[
i
-
1
]
=
'\0'
;
*
eaten
=
i
;
return
name
;
}
static
char
*
replaceVariable
(
char
**
sql
,
char
*
param
,
int
len
,
char
*
value
)
{
int
valueln
=
strlen
(
value
);
if
(
valueln
>
len
)
{
char
*
tmp
;
size_t
offset
=
param
-
*
sql
;
tmp
=
realloc
(
*
sql
,
strlen
(
*
sql
)
-
len
+
valueln
+
1
);
if
(
tmp
==
NULL
)
{
free
(
*
sql
);
return
NULL
;
}
*
sql
=
tmp
;
param
=
*
sql
+
offset
;
}
if
(
valueln
!=
len
)
memmove
(
param
+
valueln
,
param
+
len
,
strlen
(
param
+
len
)
+
1
);
strncpy
(
param
,
value
,
valueln
);
return
param
+
valueln
;
}
static
char
*
static
char
*
assignVariables
(
CState
*
st
,
char
*
sql
)
assignVariables
(
CState
*
st
,
char
*
sql
)
{
{
int
i
,
j
;
char
*
p
,
char
*
p
,
*
name
,
*
name
,
*
val
;
*
val
;
void
*
tmp
;
i
=
0
;
p
=
sql
;
while
((
p
=
strchr
(
&
sql
[
i
]
,
':'
))
!=
NULL
)
while
((
p
=
strchr
(
p
,
':'
))
!=
NULL
)
{
{
i
=
j
=
p
-
sql
;
int
eaten
;
do
name
=
parseVariable
(
p
,
&
eaten
);
if
(
name
==
NULL
)
{
{
i
++
;
while
(
*
p
==
':'
)
{
p
++
;
}
}
while
(
isalnum
((
unsigned
char
)
sql
[
i
])
||
sql
[
i
]
==
'_'
);
if
(
i
==
j
+
1
)
continue
;
continue
;
}
name
=
malloc
(
i
-
j
);
if
(
name
==
NULL
)
return
NULL
;
memcpy
(
name
,
&
sql
[
j
+
1
],
i
-
(
j
+
1
));
name
[
i
-
(
j
+
1
)]
=
'\0'
;
val
=
getVariable
(
st
,
name
);
val
=
getVariable
(
st
,
name
);
free
(
name
);
free
(
name
);
if
(
val
==
NULL
)
if
(
val
==
NULL
)
continue
;
if
(
strlen
(
val
)
>
i
-
j
)
{
{
tmp
=
realloc
(
sql
,
strlen
(
sql
)
-
(
i
-
j
)
+
strlen
(
val
)
+
1
);
p
++
;
if
(
tmp
==
NULL
)
continue
;
{
free
(
sql
);
return
NULL
;
}
sql
=
tmp
;
}
}
if
(
strlen
(
val
)
!=
i
-
j
)
if
((
p
=
replaceVariable
(
&
sql
,
p
,
eaten
,
val
))
==
NULL
)
memmove
(
&
sql
[
j
+
strlen
(
val
)],
&
sql
[
i
],
strlen
(
&
sql
[
i
])
+
1
);
return
NULL
;
}
strncpy
(
&
sql
[
j
],
val
,
strlen
(
val
));
return
sql
;
}
if
(
strlen
(
val
)
<
i
-
j
)
static
void
{
getQueryParams
(
CState
*
st
,
const
Command
*
command
,
const
char
**
params
)
tmp
=
realloc
(
sql
,
strlen
(
sql
)
+
1
);
{
if
(
tmp
==
NULL
)
int
i
;
{
free
(
sql
);
return
NULL
;
}
sql
=
tmp
;
}
i
=
j
+
strlen
(
val
);
for
(
i
=
0
;
i
<
command
->
argc
-
1
;
i
++
)
}
params
[
i
]
=
getVariable
(
st
,
command
->
argv
[
i
+
1
]);
}
return
sql
;
#define MAX_PREPARE_NAME 32
static
void
preparedStatementName
(
char
*
buffer
,
int
file
,
int
state
)
{
sprintf
(
buffer
,
"P%d_%d"
,
file
,
state
);
}
}
static
void
static
void
...
@@ -628,29 +676,83 @@ top:
...
@@ -628,29 +676,83 @@ top:
if
(
commands
[
st
->
state
]
->
type
==
SQL_COMMAND
)
if
(
commands
[
st
->
state
]
->
type
==
SQL_COMMAND
)
{
{
char
*
sql
;
const
Command
*
command
=
commands
[
st
->
state
];
int
r
;
if
((
sql
=
strdup
(
commands
[
st
->
state
]
->
argv
[
0
]))
==
NULL
if
(
querymode
==
QUERY_SIMPLE
)
||
(
sql
=
assignVariables
(
st
,
sql
))
==
NULL
)
{
{
fprintf
(
stderr
,
"out of memory
\n
"
);
char
*
sql
;
st
->
ecnt
++
;
return
;
if
((
sql
=
strdup
(
command
->
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
);
r
=
PQsendQuery
(
st
->
con
,
sql
);
free
(
sql
);
}
}
else
if
(
querymode
==
QUERY_EXTENDED
)
{
const
char
*
sql
=
command
->
argv
[
0
];
const
char
*
params
[
MAX_ARGS
];
if
(
debug
)
getQueryParams
(
st
,
command
,
params
);
fprintf
(
stderr
,
"client %d sending %s
\n
"
,
n
,
sql
);
if
(
PQsendQuery
(
st
->
con
,
sql
)
==
0
)
if
(
debug
)
fprintf
(
stderr
,
"client %d sending %s
\n
"
,
n
,
sql
);
r
=
PQsendQueryParams
(
st
->
con
,
sql
,
command
->
argc
-
1
,
NULL
,
params
,
NULL
,
NULL
,
0
);
}
else
if
(
querymode
==
QUERY_PREPARED
)
{
char
name
[
MAX_PREPARE_NAME
];
const
char
*
params
[
MAX_ARGS
];
if
(
!
st
->
prepared
[
st
->
use_file
])
{
int
j
;
for
(
j
=
0
;
commands
[
j
]
!=
NULL
;
j
++
)
{
PGresult
*
res
;
char
name
[
MAX_PREPARE_NAME
];
if
(
commands
[
j
]
->
type
!=
SQL_COMMAND
)
continue
;
preparedStatementName
(
name
,
st
->
use_file
,
j
);
res
=
PQprepare
(
st
->
con
,
name
,
commands
[
j
]
->
argv
[
0
],
commands
[
j
]
->
argc
-
1
,
NULL
);
if
(
PQresultStatus
(
res
)
!=
PGRES_COMMAND_OK
)
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
st
->
con
));
PQclear
(
res
);
}
st
->
prepared
[
st
->
use_file
]
=
true
;
}
getQueryParams
(
st
,
command
,
params
);
preparedStatementName
(
name
,
st
->
use_file
,
st
->
state
);
if
(
debug
)
fprintf
(
stderr
,
"client %d sending %s
\n
"
,
n
,
name
);
r
=
PQsendQueryPrepared
(
st
->
con
,
name
,
command
->
argc
-
1
,
params
,
NULL
,
NULL
,
0
);
}
else
/* unknown sql mode */
r
=
0
;
if
(
r
==
0
)
{
{
if
(
debug
)
if
(
debug
)
fprintf
(
stderr
,
"
PQsendQuery(%s)failed
\n
"
,
sql
);
fprintf
(
stderr
,
"
client %d cannot send %s
\n
"
,
n
,
command
->
argv
[
0
]
);
st
->
ecnt
++
;
st
->
ecnt
++
;
}
}
else
else
{
st
->
listen
=
1
;
/* flags that should be listened */
st
->
listen
=
1
;
/* flags that should be listened */
}
free
(
sql
);
}
}
else
if
(
commands
[
st
->
state
]
->
type
==
META_COMMAND
)
else
if
(
commands
[
st
->
state
]
->
type
==
META_COMMAND
)
{
{
...
@@ -984,6 +1086,52 @@ init(void)
...
@@ -984,6 +1086,52 @@ init(void)
PQfinish
(
con
);
PQfinish
(
con
);
}
}
/*
* Parse the raw sql and replace :param to $n.
*/
static
bool
parseQuery
(
Command
*
cmd
,
const
char
*
raw_sql
)
{
char
*
sql
,
*
p
;
sql
=
strdup
(
raw_sql
);
if
(
sql
==
NULL
)
return
false
;
cmd
->
argc
=
1
;
p
=
sql
;
while
((
p
=
strchr
(
p
,
':'
))
!=
NULL
)
{
char
var
[
12
];
char
*
name
;
int
eaten
;
name
=
parseVariable
(
p
,
&
eaten
);
if
(
name
==
NULL
)
{
while
(
*
p
==
':'
)
{
p
++
;
}
continue
;
}
if
(
cmd
->
argc
>=
MAX_ARGS
)
{
fprintf
(
stderr
,
"statement has too many arguments (maximum is %d): %s
\n
"
,
MAX_ARGS
-
1
,
raw_sql
);
return
false
;
}
sprintf
(
var
,
"$%d"
,
cmd
->
argc
);
if
((
p
=
replaceVariable
(
&
sql
,
p
,
eaten
,
var
))
==
NULL
)
return
false
;
cmd
->
argv
[
cmd
->
argc
]
=
name
;
cmd
->
argc
++
;
}
cmd
->
argv
[
0
]
=
sql
;
return
true
;
}
static
Command
*
static
Command
*
process_commands
(
char
*
buf
)
process_commands
(
char
*
buf
)
{
{
...
@@ -1090,10 +1238,21 @@ process_commands(char *buf)
...
@@ -1090,10 +1238,21 @@ process_commands(char *buf)
{
{
my_commands
->
type
=
SQL_COMMAND
;
my_commands
->
type
=
SQL_COMMAND
;
if
((
my_commands
->
argv
[
0
]
=
strdup
(
p
))
==
NULL
)
switch
(
querymode
)
return
NULL
;
{
case
QUERY_SIMPLE
:
my_commands
->
argc
++
;
if
((
my_commands
->
argv
[
0
]
=
strdup
(
p
))
==
NULL
)
return
NULL
;
my_commands
->
argc
++
;
break
;
case
QUERY_EXTENDED
:
case
QUERY_PREPARED
:
if
(
!
parseQuery
(
my_commands
,
p
))
return
NULL
;
break
;
default:
return
NULL
;
}
}
}
return
my_commands
;
return
my_commands
;
...
@@ -1270,6 +1429,7 @@ printResults(
...
@@ -1270,6 +1429,7 @@ printResults(
printf
(
"transaction type: %s
\n
"
,
s
);
printf
(
"transaction type: %s
\n
"
,
s
);
printf
(
"scaling factor: %d
\n
"
,
scale
);
printf
(
"scaling factor: %d
\n
"
,
scale
);
printf
(
"query mode: %s
\n
"
,
QUERYMODE
[
querymode
]);
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
);
...
@@ -1335,7 +1495,7 @@ main(int argc, char **argv)
...
@@ -1335,7 +1495,7 @@ main(int argc, char **argv)
memset
(
state
,
0
,
sizeof
(
*
state
));
memset
(
state
,
0
,
sizeof
(
*
state
));
while
((
c
=
getopt
(
argc
,
argv
,
"ih:nvp:dc:t:s:U:CNSlf:D:F:"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"ih:nvp:dc:t:s:U:CNSlf:D:F:
M:
"
))
!=
-
1
)
{
{
switch
(
c
)
switch
(
c
)
{
{
...
@@ -1445,6 +1605,21 @@ main(int argc, char **argv)
...
@@ -1445,6 +1605,21 @@ main(int argc, char **argv)
exit
(
1
);
exit
(
1
);
}
}
break
;
break
;
case
'M'
:
if
(
num_files
>
0
)
{
fprintf
(
stderr
,
"querymode(-M) should be specifiled before transaction scripts(-f)
\n
"
);
exit
(
1
);
}
for
(
querymode
=
0
;
querymode
<
NUM_QUERYMODE
;
querymode
++
)
if
(
strcmp
(
optarg
,
QUERYMODE
[
querymode
])
==
0
)
break
;
if
(
querymode
>=
NUM_QUERYMODE
)
{
fprintf
(
stderr
,
"invalid querymode(-M): %s
\n
"
,
optarg
);
exit
(
1
);
}
break
;
default:
default:
usage
();
usage
();
exit
(
1
);
exit
(
1
);
...
...
doc/src/sgml/pgbench.sgml
浏览文件 @
49639a7b
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.
5 2007/12/11 02:31:49 tgl
Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.
6 2008/03/19 03:33:21 ishii
Exp $ -->
<sect1 id="pgbench">
<sect1 id="pgbench">
<title>pgbench</title>
<title>pgbench</title>
...
@@ -173,6 +173,23 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
...
@@ -173,6 +173,23 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
Number of transactions each client runs. Default is 10.
Number of transactions each client runs. Default is 10.
</entry>
</entry>
</row>
</row>
<row>
<entry><literal>-M</literal> <replaceable>querymode</></entry>
<entry>
Choose the query mode from the follows. default is simple.
<itemizedlist>
<listitem>
<para>simple: using simple query protocol.</para>
</listitem>
<listitem>
<para>extended: using extended protocol.</para>
</listitem>
<listitem>
<para>prepared: using extended protocol with prepared statements.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<row>
<entry><literal>-N</literal></entry>
<entry><literal>-N</literal></entry>
<entry>
<entry>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录