mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
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
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
$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
|
|||||||
|
|
||||||
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):
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $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
|
|||||||
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)
|
|||||||
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:
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, backend returns reply */
|
/* ok, backend returns reply */
|
||||||
|
Reference in New Issue
Block a user