Commit 0f17da9b authored by Jan Wieck's avatar Jan Wieck

Added a new scripting meta command

    \usleep [milliseconds|:variable]

which can be used in -f scripts to insert a thinking time between
other commands.

Jan
parent 7af3a6fc
$PostgreSQL: pgsql/contrib/pgbench/README.pgbench,v 1.18 2007/04/08 01:15:07 ishii Exp $ $PostgreSQL: pgsql/contrib/pgbench/README.pgbench,v 1.19 2007/07/06 13:36:55 wieck Exp $
pgbench README pgbench README
...@@ -231,6 +231,16 @@ o -f option ...@@ -231,6 +231,16 @@ o -f option
Variables can also be defined by using -D option. Variables can also be defined by using -D option.
\usleep usec
causes script execution to sleep for the specified duration in
microseconds.
example:
\setrandom usec 1000000 3000000
\usleep :usec
Example, TPC-B like benchmark can be defined as follows(scaling Example, TPC-B like benchmark can be defined as follows(scaling
factor = 1): factor = 1):
......
/* /*
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.66 2007/05/24 18:54:10 tgl Exp $ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.67 2007/07/06 13:36:55 wieck Exp $
* *
* pgbench: a simple benchmark program for PostgreSQL * pgbench: a simple benchmark program for PostgreSQL
* written by Tatsuo Ishii * written by Tatsuo Ishii
...@@ -114,6 +114,8 @@ typedef struct ...@@ -114,6 +114,8 @@ typedef struct
int ecnt; /* error count */ int ecnt; /* error count */
int listen; /* 0 indicates that an async query has been int listen; /* 0 indicates that an async query has been
* sent */ * sent */
int sleeping; /* 1 indicates that the client is napping */
struct timeval until; /* napping until */
Variable *variables; /* array of variable definitions */ Variable *variables; /* array of variable definitions */
int nvariables; int nvariables;
struct timeval txn_begin; /* used for measuring latencies */ struct timeval txn_begin; /* used for measuring latencies */
...@@ -445,6 +447,20 @@ doCustom(CState * state, int n, int debug) ...@@ -445,6 +447,20 @@ doCustom(CState * state, int n, int debug)
top: top:
commands = sql_files[st->use_file]; commands = sql_files[st->use_file];
if (st->sleeping)
{ /* are we sleeping? */
int usec;
struct timeval now;
gettimeofday(&now, NULL);
usec = (st->until.tv_sec - now.tv_sec) * 1000000 +
st->until.tv_usec - now.tv_usec;
if (usec <= 0)
st->sleeping = 0; /* Done sleeping, go ahead with next command */
else
return; /* Still sleeping, nothing to do here */
}
if (st->listen) if (st->listen)
{ /* are we receiver? */ { /* are we receiver? */
if (commands[st->state]->type == SQL_COMMAND) if (commands[st->state]->type == SQL_COMMAND)
...@@ -711,6 +727,32 @@ top: ...@@ -711,6 +727,32 @@ top:
st->listen = 1; st->listen = 1;
} }
else if (pg_strcasecmp(argv[0], "usleep") == 0)
{
char *var;
int usec;
struct timeval now;
if (*argv[1] == ':')
{
if ((var = getVariable(st, argv[1] + 1)) == NULL)
{
fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[1]);
st->ecnt++;
return;
}
usec = atoi(var);
}
else
usec = atoi(argv[1]);
gettimeofday(&now, NULL);
st->until.tv_sec = now.tv_sec + (now.tv_usec + usec) / 1000000;
st->until.tv_usec = (now.tv_usec + usec) % 1000000;
st->sleeping = 1;
st->listen = 1;
}
goto top; goto top;
} }
...@@ -921,9 +963,21 @@ process_commands(char *buf) ...@@ -921,9 +963,21 @@ process_commands(char *buf)
fprintf(stderr, "%s: extra argument \"%s\" ignored\n", fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
my_commands->argv[0], my_commands->argv[j]); my_commands->argv[0], my_commands->argv[j]);
} }
else if (pg_strcasecmp(my_commands->argv[0], "usleep") == 0)
{
if (my_commands->argc < 2)
{
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
return NULL;
}
for (j = 2; j < my_commands->argc; j++)
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
my_commands->argv[0], my_commands->argv[j]);
}
else else
{ {
fprintf(stderr, "invalid command %s\n", my_commands->argv[0]); fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]);
return NULL; return NULL;
} }
} }
...@@ -1143,6 +1197,9 @@ main(int argc, char **argv) ...@@ -1143,6 +1197,9 @@ main(int argc, char **argv)
fd_set input_mask; fd_set input_mask;
int nsocks; /* return from select(2) */ int nsocks; /* return from select(2) */
int maxsock; /* max socket number to be waited */ int maxsock; /* max socket number to be waited */
struct timeval now;
struct timeval timeout;
int min_usec;
#ifdef HAVE_GETRLIMIT #ifdef HAVE_GETRLIMIT
struct rlimit rlim; struct rlimit rlim;
...@@ -1526,11 +1583,33 @@ main(int argc, char **argv) ...@@ -1526,11 +1583,33 @@ main(int argc, char **argv)
FD_ZERO(&input_mask); FD_ZERO(&input_mask);
maxsock = -1; maxsock = -1;
min_usec = -1;
for (i = 0; i < nclients; i++) for (i = 0; i < nclients; i++)
{ {
Command **commands = sql_files[state[i].use_file]; Command **commands = sql_files[state[i].use_file];
if (state[i].con && commands[state[i].state]->type != META_COMMAND) if (state[i].sleeping)
{
int this_usec;
int sock = PQsocket(state[i].con);
if (min_usec < 0)
{
gettimeofday(&now, NULL);
min_usec = 0;
}
this_usec = (state[i].until.tv_sec - now.tv_sec) * 1000000 +
state[i].until.tv_usec - now.tv_usec;
if (this_usec > 0 && (min_usec == 0 || this_usec < min_usec))
min_usec = this_usec;
FD_SET(sock, &input_mask);
if (maxsock < sock)
maxsock = sock;
}
else if (state[i].con && commands[state[i].state]->type != META_COMMAND)
{ {
int sock = PQsocket(state[i].con); int sock = PQsocket(state[i].con);
...@@ -1547,8 +1626,18 @@ main(int argc, char **argv) ...@@ -1547,8 +1626,18 @@ main(int argc, char **argv)
if (maxsock != -1) if (maxsock != -1)
{ {
if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL, if (min_usec >= 0)
(fd_set *) NULL, (struct timeval *) NULL)) < 0) {
timeout.tv_sec = min_usec / 1000000;
timeout.tv_usec = min_usec % 1000000;
nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
(fd_set *) NULL, &timeout);
}
else
nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
(fd_set *) NULL, (struct timeval *) NULL);
if (nsocks < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
...@@ -1557,6 +1646,7 @@ main(int argc, char **argv) ...@@ -1557,6 +1646,7 @@ main(int argc, char **argv)
fprintf(stderr, "select failed: %s\n", strerror(errno)); fprintf(stderr, "select failed: %s\n", strerror(errno));
exit(1); exit(1);
} }
#ifdef NOT_USED
else if (nsocks == 0) else if (nsocks == 0)
{ /* timeout */ { /* timeout */
fprintf(stderr, "select timeout\n"); fprintf(stderr, "select timeout\n");
...@@ -1567,6 +1657,7 @@ main(int argc, char **argv) ...@@ -1567,6 +1657,7 @@ main(int argc, char **argv)
} }
exit(0); exit(0);
} }
#endif
} }
/* ok, backend returns reply */ /* ok, backend returns reply */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment