]> granicus.if.org Git - postgresql/commitdiff
Various pgbench enhancements. Patch contributed by ITAGAKI Takahiro.
authorTatsuo Ishii <ishii@postgresql.org>
Fri, 6 Apr 2007 08:49:44 +0000 (08:49 +0000)
committerTatsuo Ishii <ishii@postgresql.org>
Fri, 6 Apr 2007 08:49:44 +0000 (08:49 +0000)
Also tweak README.pgbench/README.pgbench_jis:
  Remove history after pgbench was added to PostgreSQL contrib module.
  Those info was not only redundant since it has already been in CVS
  log, but also incomplete.
--------------------------------------------------------------------------
The attached is a patch to optimize contrib/pgbench using new 8.3 features.

- Use DROP IF EXISTS to suppress errors for initial loadings.
- Use a combination of TRUNCATE and COPY to reduce WAL on creating
  the accounts table.

Also, there are some cosmetic changes.

- Change the output of -v option from "starting full vacuum..."
  to "starting vacuum accounts..." in reflection of the fact.
- Shape duplicated error checks into executeStatement().

There is a big performance win in "COPY with no WAL" feature.
Thanks for the efforts!
--------------------------------------------------------------------------

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

index d576b594a9fbe32ff15df29e95c78d22d64e255a..7fc683cef035027f6d3b1fe5d4f47ea2e95c82f6 100644 (file)
@@ -1,4 +1,6 @@
-pgbench README         2006/10/21 Tatsuo Ishii
+$PostgreSQL: pgsql/contrib/pgbench/README.pgbench,v 1.16 2007/04/06 08:49:44 ishii Exp $
+
+pgbench README
 
 o What is pgbench?
 
@@ -233,54 +235,7 @@ o License?
 
 Basically it is same as BSD license. See pgbench.c for more details.
 
-o History
-
-2006/10/21
-       * more fix with handling default scaling factor in the default
-          scenarios
-
-2006/09/14
-       * change "tps" to "scale" to avoid confusion
-
-       * fix bug with handling default scaling factor in the default
-          scenarios
-
-2006/07/26
-       * New features contributed by Tomoaki Sato.
-
-       * predefined variable "tps"
-           The value of variable tps is taken from the scaling factor
-           specified by -s option.
-        * -D option
-          Variable values can be defined by -D option.
-       * \set command now allows arithmetic calculations.
-
-2005/09/29
-       * add -f option. contributed by Tomoaki Sato.
-
-[updation records were missing]
-
-2003/11/26
-       * create indexes after data insertion to reduce time.
-         patch from Yutaka Tanida.
-
-2003/06/10
-       * fix uninitialized memory bug
-       * add support for PGHOST, PGPORT, PGUSER environment variables
-
-2002/07/20
-       * patch contributed by Neil Conway.
-       * code/document clean up and add -l option.
-
-2002/02/24
-       * do not CHECKPOINT anymore while initializing benchmark
-       * database. Add -N option.
-
-2001/10/24
-       * "time"->"mtime"
-
-2001/09/09
-       * Add -U, -P, -C options
+o History before contributed to PostgreSQL
 
 2000/1/15 pgbench-1.2 contributed to PostgreSQL
        * Add -v option
index adb22af4051c92e1556d74ea894f462efdf639e6..5afa9324367249fc1ec1ba1999048082e5571f02 100644 (file)
@@ -1,4 +1,6 @@
-pgbench README         2006/10/21 Tatsuo Ishii
+$PostgreSQL: pgsql/contrib/pgbench/README.pgbench_jis,v 1.17 2007/04/06 08:49:44 ishii Exp $
+
+pgbench README
 
 \e$B"#\e(Bpgbench \e$B$H$O!)\e(B
 
@@ -283,57 +285,7 @@ pgbench \e$B$O@P0f\e(B \e$BC#IW$K$h$C$F=q$+$l$^$7$?!%%i%$%;%s%9>r7o$O\e(B pgbench.c
 \e$BKAF,$K=q$$$F$"$j$^$9!%$3$N>r7o$r<i$k8B$jL5=~$GMxMQ$7!$$^$?<+M3$K:FG[IU\e(B
 \e$B$G$-$^$9!%\e(B
 
-\e$B"#2~DjMzNr\e(B
-
-2006/10/21
-       * \e$B99$K%G%U%)%k%H$N%9%1!<%j%s%0%U%!%/%?$r\e(Bbranches\e$B$+$i<h$C$F$3$J\e(B
-          \e$B$$%P%0$r=$@5!%\e(B
-
-2006/09/13
-       * \e$BJQ?t\e(Btps\e$B$OJ6$i$o$7$$$N$G\e(Bscale\e$B$KJQ99!%%G%U%)%k%H%7%J%j%*$N;~$K!$\e(B
-         \e$B%G%U%)%k%H$N%9%1!<%j%s%0%U%!%/%?$r\e(Bbranches\e$B$+$i<h$C$F$3$J$$%P%0$r=$@5!%\e(B
-
-2006/07/26
-       * \e$B:4F#$5$s$N%Q%C%A$rE,MQ!%0J2<$N5!G=DI2C!%\e(BPostgreSQL 8.2\e$B$K<h$j\e(B
-       \e$B9~$^$l$^$9!%\e(B
-
-       \e$BJQ?t\e(B tps
-           -s \e$B%*%W%7%g%s$G;XDj$7$?%9%1!<%j%s%0%U%!%/%?!<$r%U%!%$%kFb$GJQ?t$H$7\e(B
-          \e$B$F;2>H$9$k5!G=\e(B
-        -D \e$B%*%W%7%g%s\e(B
-          \e$B%3%^%s%I$N%*%W%7%g%s$H$7$FDj5A$7$?JQ?t$r%U%!%$%kFb$+$i;2>H$9$k5!G=\e(B
-       \set \e$B%3%^%s%I\e(B
-          \e$B%U%!%$%kFb$G;MB'1i;;$r9T$$!"$=$N7k2L$rJQ?t$KBeF~$9$k5!G=\e(B
-
-2005/09/29
-       * \e$B:4F#$5$s$N%Q%C%A$rE,MQ!%\e(B-f \e$B%*%W%7%g%s$NDI2C!%\e(B
-
-[\e$B$3$N4V$$$m$$$mJQ99$,$"$C$?$h$&$@$,\e(BREADME\e$B$O%a%$%s%F%J%s%9$5$l$F$$$J$$\e(B]
-
-2003/11/26
-       * \e$BC+ED$5$s$N%Q%C%A$rE,MQ!%\e(Bpgbench -i\e$B$N:]$K!$8e$+$i<g%-!<$r:n@.\e(B
-         \e$B$9$k$h$&$K$7$?!%$3$l$K$h$C$F=i4|2=$N<B9T;~4V$,BgI}$KC;=L$G$-\e(B
-         \e$B$k\e(B(\e$B$O$:\e(B)\e$B!%\e(B
-
-2003/06/10
-       * \e$B%a%b%j$,=i4|2=$5$l$F$$$J$$%P%0$r=$@5\e(B
-       * \e$B4D6-JQ?t\e(BPGHOST, PGPORT, PGUSER\e$B$rG'<1$9$k$h$&$K$7$?!%\e(B
-
-2002/07/20
-       * Nei Conway\e$B$5$s$N%Q%C%A$rE,MQ!%\e(B
-       * -l \e$B%*%W%7%g%s$NDI2C!%\e(B
-
-2002/02/24
-       * \e$B$3$3$+$i$O\e(B7.3\e$BMQ$NJQ99$G$9!%\e(B
-       * CHECKPOINT\e$B$NH/9T$r$d$a$^$7$?!%\e(B
-       * -N \e$B%*%W%7%g%s$rDI2C$7$^$7$?!%\e(B
-
-2001/10/24
-       * PostgreSQL 7.2\e$B$G!$\e(B"time"\e$B$,M=Ls8l$K$J$C$?$N$G!$\e(B"mtime"\e$B$KJQ99\e(B
-       \e$B$7$?!%\e(B
-
-2001/09/09
-       * PostgreSQL 7.2\e$BMQ$K!$\e(B-U, -P, -C \e$B%*%W%7%g%s$rDI2C$7$^$7$?!%\e(B
+\e$B"#\e(BPostgreSQL\e$B$N\e(Bcontrib\e$B%b%8%e!<%k$H$7$F<h$j9~$^$l$k$^$G$N2~DjMzNr\e(B
 
 2000/1/15 pgbench-1.2 \e$B$O\e(B PostgreSQL \e$B$K\e(B contribute \e$B$5$l$^$7$?!%\e(B
        * -v \e$B%*%W%7%g%sDI2C\e(B
index 1f2e0bf4167e5d27cc5917d8c217ff492f06d9c1..369b7669f121e7bc66614a12609f9db28cdea4f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.62 2007/03/13 09:06:35 mha Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.63 2007/04/06 08:49:44 ishii Exp $
  *
  * pgbench: a simple benchmark program for PostgreSQL
  * written by Tatsuo Ishii
@@ -188,12 +188,26 @@ getrand(int min, int max)
        return min + (int) (((max - min) * (double) random()) / MAX_RANDOM_VALUE + 0.5);
 }
 
+/* call PQexec() and exit() on failure */
+static void
+executeStatement(PGconn *con, const char* sql)
+{
+       PGresult   *res;
+
+       res = PQexec(con, sql);
+       if (PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, "%s", PQerrorMessage(con));
+               exit(1);
+       }
+       PQclear(res);
+}
+
 /* set up a connection to the backend */
 static PGconn *
 doConnect(void)
 {
        PGconn     *con;
-       PGresult   *res;
 
        con = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
                                           login, pwd);
@@ -216,13 +230,7 @@ doConnect(void)
                return (NULL);
        }
 
-       res = PQexec(con, "SET search_path = public");
-       if (PQresultStatus(res) != PGRES_COMMAND_OK)
-       {
-               fprintf(stderr, "%s", PQerrorMessage(con));
-               exit(1);
-       }
-       PQclear(res);
+       executeStatement(con, "SET search_path = public");
 
        return (con);
 }
@@ -720,18 +728,18 @@ init(void)
        PGconn     *con;
        PGresult   *res;
        static char *DDLs[] = {
-               "drop table branches",
+               "drop table if exists branches",
                "create table branches(bid int not null,bbalance int,filler char(88))",
-               "drop table tellers",
+               "drop table if exists tellers",
                "create table tellers(tid int not null,bid int,tbalance int,filler char(84))",
-               "drop table accounts",
+               "drop table if exists accounts",
                "create table accounts(aid int not null,bid int,abalance int,filler char(84))",
-               "drop table history",
-       "create table history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22))"};
+               "drop table if exists history",
+               "create table history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22))"};
        static char *DDLAFTERs[] = {
                "alter table branches add primary key (bid)",
                "alter table tellers add primary key (tid)",
-       "alter table accounts add primary key (aid)"};
+               "alter table accounts add primary key (aid)"};
 
 
        char            sql[256];
@@ -741,77 +749,46 @@ init(void)
        if ((con = doConnect()) == NULL)
                exit(1);
 
-       for (i = 0; i < (sizeof(DDLs) / sizeof(char *)); i++)
-       {
-               res = PQexec(con, DDLs[i]);
-               if (strncmp(DDLs[i], "drop", 4) && PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
-       }
+       for (i = 0; i < lengthof(DDLs); i++)
+               executeStatement(con, DDLs[i]);
 
-       res = PQexec(con, "begin");
-       if (PQresultStatus(res) != PGRES_COMMAND_OK)
-       {
-               fprintf(stderr, "%s", PQerrorMessage(con));
-               exit(1);
-       }
-       PQclear(res);
+       executeStatement(con, "begin");
 
        for (i = 0; i < nbranches * scale; i++)
        {
                snprintf(sql, 256, "insert into branches(bid,bbalance) values(%d,0)", i + 1);
-               res = PQexec(con, sql);
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
+               executeStatement(con, sql);
        }
 
        for (i = 0; i < ntellers * scale; i++)
        {
                snprintf(sql, 256, "insert into tellers(tid,bid,tbalance) values (%d,%d,0)"
                                 ,i + 1, i / ntellers + 1);
-               res = PQexec(con, sql);
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
+               executeStatement(con, sql);
        }
 
-       res = PQexec(con, "end");
-       if (PQresultStatus(res) != PGRES_COMMAND_OK)
+       executeStatement(con, "commit");
+
+       /*
+        * fill the accounts table with some data
+        */
+       fprintf(stderr, "creating tables...\n");
+
+       executeStatement(con, "begin");
+       executeStatement(con, "truncate accounts");
+
+       res = PQexec(con, "copy accounts from stdin");
+       if (PQresultStatus(res) != PGRES_COPY_IN)
        {
                fprintf(stderr, "%s", PQerrorMessage(con));
                exit(1);
        }
        PQclear(res);
 
-       /*
-        * occupy accounts table with some data
-        */
-       fprintf(stderr, "creating tables...\n");
        for (i = 0; i < naccounts * scale; i++)
        {
                int                     j = i + 1;
 
-               if (j % 10000 == 1)
-               {
-                       res = PQexec(con, "copy accounts from stdin");
-                       if (PQresultStatus(res) != PGRES_COPY_IN)
-                       {
-                               fprintf(stderr, "%s", PQerrorMessage(con));
-                               exit(1);
-                       }
-                       PQclear(res);
-               }
-
                snprintf(sql, 256, "%d\t%d\t%d\t\n", j, i / naccounts + 1, 0);
                if (PQputline(con, sql))
                {
@@ -820,62 +797,32 @@ init(void)
                }
 
                if (j % 10000 == 0)
-               {
-                       /*
-                        * every 10000 tuples, we commit the copy command. this should
-                        * avoid generating too much WAL logs
-                        */
                        fprintf(stderr, "%d tuples done.\n", j);
-                       if (PQputline(con, "\\.\n"))
-                       {
-                               fprintf(stderr, "very last PQputline failed\n");
-                               exit(1);
-                       }
-
-                       if (PQendcopy(con))
-                       {
-                               fprintf(stderr, "PQendcopy failed\n");
-                               exit(1);
-                       }
-
-#ifdef NOT_USED
-
-                       /*
-                        * do a checkpoint to purge the old WAL logs
-                        */
-                       res = PQexec(con, "checkpoint");
-                       if (PQresultStatus(res) != PGRES_COMMAND_OK)
-                       {
-                               fprintf(stderr, "%s", PQerrorMessage(con));
-                               exit(1);
-                       }
-                       PQclear(res);
-#endif   /* NOT_USED */
-               }
        }
-       fprintf(stderr, "set primary key...\n");
-       for (i = 0; i < (sizeof(DDLAFTERs) / sizeof(char *)); i++)
+       if (PQputline(con, "\\.\n"))
        {
-               res = PQexec(con, DDLAFTERs[i]);
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
+               fprintf(stderr, "very last PQputline failed\n");
+               exit(1);
        }
-
-       /* vacuum */
-       fprintf(stderr, "vacuum...");
-       res = PQexec(con, "vacuum analyze");
-       if (PQresultStatus(res) != PGRES_COMMAND_OK)
+       if (PQendcopy(con))
        {
-               fprintf(stderr, "%s", PQerrorMessage(con));
+               fprintf(stderr, "PQendcopy failed\n");
                exit(1);
        }
-       PQclear(res);
-       fprintf(stderr, "done.\n");
+       executeStatement(con, "commit");
+
+       /*
+        * create indexes
+        */
+       fprintf(stderr, "set primary key...\n");
+       for (i = 0; i < lengthof(DDLAFTERs); i++)
+               executeStatement(con, DDLAFTERs[i]);
 
+       /* vacuum */
+       fprintf(stderr, "vacuum...");
+       executeStatement(con, "vacuum analyze");
+
+       fprintf(stderr, "done.\n");
        PQfinish(con);
 }
 
@@ -1155,7 +1102,7 @@ main(int argc, char **argv)
        int                     c;
        int                     is_init_mode = 0;               /* initialize mode? */
        int                     is_no_vacuum = 0;               /* no vacuum at all before testing? */
-       int                     is_full_vacuum = 0;             /* do full vacuum before testing? */
+       int                     do_vacuum_accounts = 0; /* do vacuum accounts before testing? */
        int                     debug = 0;              /* debug flag */
        int                     ttype = 0;              /* transaction type. 0: TPC-B, 1: SELECT only,
                                                                 * 2: skip update of branches and tellers */
@@ -1219,7 +1166,7 @@ main(int argc, char **argv)
                                is_no_vacuum++;
                                break;
                        case 'v':
-                               is_full_vacuum++;
+                               do_vacuum_accounts++;
                                break;
                        case 'p':
                                pgport = optarg;
@@ -1456,49 +1403,16 @@ main(int argc, char **argv)
        if (!is_no_vacuum)
        {
                fprintf(stderr, "starting vacuum...");
-               res = PQexec(con, "vacuum branches");
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
-
-               res = PQexec(con, "vacuum tellers");
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
-
-               res = PQexec(con, "delete from history");
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
-               res = PQexec(con, "vacuum history");
-               if (PQresultStatus(res) != PGRES_COMMAND_OK)
-               {
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-                       exit(1);
-               }
-               PQclear(res);
-
+               executeStatement(con, "vacuum branches");
+               executeStatement(con, "vacuum tellers");
+               executeStatement(con, "delete from history");
+               executeStatement(con, "vacuum history");
                fprintf(stderr, "end.\n");
 
-               if (is_full_vacuum)
+               if (do_vacuum_accounts)
                {
-                       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, "starting vacuum accounts...");
+                       executeStatement(con, "vacuum analyze accounts");
                        fprintf(stderr, "end.\n");
                }
        }