]> granicus.if.org Git - postgresql/commitdiff
Added a new scripting meta command
authorJan Wieck <JanWieck@Yahoo.com>
Fri, 6 Jul 2007 13:36:55 +0000 (13:36 +0000)
committerJan Wieck <JanWieck@Yahoo.com>
Fri, 6 Jul 2007 13:36:55 +0000 (13:36 +0000)
    \usleep [milliseconds|:variable]

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

Jan

contrib/pgbench/README.pgbench
contrib/pgbench/pgbench.c

index 599dc3b6c541552579ff524b2102b5548c1e5e97..2afd4db25e8355ef56735a244a4d9157ba3807bd 100644 (file)
@@ -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
 
@@ -231,6 +231,16 @@ o -f 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
   factor = 1):
 
index 2de6a51b053c9e83e5c65fae1e8b45d877599925..77d3a735d062bf38e11ae0fed20ef3a2a99f4a18 100644 (file)
@@ -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
  * written by Tatsuo Ishii
@@ -114,6 +114,8 @@ typedef struct
        int                     ecnt;                   /* error count */
        int                     listen;                 /* 0 indicates that an async query has been
                                                                 * sent */
+       int                     sleeping;               /* 1 indicates that the client is napping */
+       struct timeval until;           /* napping until */
        Variable   *variables;          /* array of variable definitions */
        int                     nvariables;
        struct timeval txn_begin;       /* used for measuring latencies */
@@ -445,6 +447,20 @@ doCustom(CState * state, int n, int debug)
 top:
        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)
        {                                                       /* are we receiver? */
                if (commands[st->state]->type == SQL_COMMAND)
@@ -711,6 +727,32 @@ top:
 
                        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;
        }
@@ -921,9 +963,21 @@ process_commands(char *buf)
                                fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
                                                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
                {
-                       fprintf(stderr, "invalid command %s\n", my_commands->argv[0]);
+                       fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]);
                        return NULL;
                }
        }
@@ -1143,6 +1197,9 @@ main(int argc, char **argv)
        fd_set          input_mask;
        int                     nsocks;                 /* return from select(2) */
        int                     maxsock;                /* max socket number to be waited */
+       struct timeval now;
+       struct timeval timeout;
+       int                     min_usec;
 
 #ifdef HAVE_GETRLIMIT
        struct rlimit rlim;
@@ -1526,11 +1583,33 @@ main(int argc, char **argv)
                FD_ZERO(&input_mask);
 
                maxsock = -1;
+               min_usec = -1;
                for (i = 0; i < nclients; i++)
                {
                        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);
 
@@ -1547,8 +1626,18 @@ main(int argc, char **argv)
 
                if (maxsock != -1)
                {
-                       if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
-                                                         (fd_set *) NULL, (struct timeval *) NULL)) < 0)
+                       if (min_usec >= 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)
                                        continue;
@@ -1557,6 +1646,7 @@ main(int argc, char **argv)
                                fprintf(stderr, "select failed: %s\n", strerror(errno));
                                exit(1);
                        }
+#ifdef NOT_USED
                        else if (nsocks == 0)
                        {                                       /* timeout */
                                fprintf(stderr, "select timeout\n");
@@ -1567,6 +1657,7 @@ main(int argc, char **argv)
                                }
                                exit(0);
                        }
+#endif
                }
 
                /* ok, backend returns reply */