44 * A simple benchmark program for PostgreSQL
55 * Originally written by Tatsuo Ishii and enhanced by many contributors.
66 *
7- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.97 2010/02/26 02:00:32 momjian Exp $
7+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.98 2010/03/23 01:29:22 itagaki Exp $
88 * Copyright (c) 2000-2010, PostgreSQL Global Development Group
99 * ALL RIGHTS RESERVED;
1010 *
@@ -131,11 +131,9 @@ intfillfactor = 100;
131131#define ntellers 10
132132#define naccounts 100000
133133
134- FILE * LOGFILE = NULL ;
135-
136134bool use_log ;/* log transaction latencies to a file */
137-
138- int is_connect ;/*establish connection for each transaction */
135+ bool is_connect ; /* establish connection for each transaction */
136+ int main_pid ;/*main process id used in log filename */
139137
140138char * pghost = "" ;
141139char * pgport = "" ;
@@ -183,6 +181,7 @@ typedef struct
183181 */
184182typedef struct
185183{
184+ int tid ;/* thread id */
186185pthread_t thread ;/* thread handle */
187186CState * state ;/* array of CState */
188187int nstate ;/* length of state[] */
@@ -741,7 +740,7 @@ clientDone(CState *st, bool ok)
741740
742741/* return false iff client should be disconnected */
743742static bool
744- doCustom (CState * st ,instr_time * conn_time )
743+ doCustom (CState * st ,instr_time * conn_time , FILE * logfile )
745744{
746745PGresult * res ;
747746Command * * commands ;
@@ -778,7 +777,7 @@ doCustom(CState *st, instr_time *conn_time)
778777/*
779778 * transaction finished: record the time it took in the log
780779 */
781- if (use_log && commands [st -> state + 1 ]== NULL )
780+ if (logfile && commands [st -> state + 1 ]== NULL )
782781{
783782instr_time now ;
784783instr_time diff ;
@@ -791,12 +790,12 @@ doCustom(CState *st, instr_time *conn_time)
791790
792791#ifndef WIN32
793792/* This is more than we really ought to know about instr_time */
794- fprintf (LOGFILE ,"%d %d %.0f %d %ld %ld\n" ,
793+ fprintf (logfile ,"%d %d %.0f %d %ld %ld\n" ,
795794st -> id ,st -> cnt ,usec ,st -> use_file ,
796795(long )now .tv_sec , (long )now .tv_usec );
797796#else
798797/* On Windows, instr_time doesn't provide a timestamp anyway */
799- fprintf (LOGFILE ,"%d %d %.0f %d 0 0\n" ,
798+ fprintf (logfile ,"%d %d %.0f %d 0 0\n" ,
800799st -> id ,st -> cnt ,usec ,st -> use_file );
801800#endif
802801}
@@ -857,7 +856,7 @@ doCustom(CState *st, instr_time *conn_time)
857856INSTR_TIME_ACCUM_DIFF (* conn_time ,end ,start );
858857}
859858
860- if (use_log && st -> state == 0 )
859+ if (logfile && st -> state == 0 )
861860INSTR_TIME_SET_CURRENT (st -> txn_begin );
862861
863862if (commands [st -> state ]-> type == SQL_COMMAND )
@@ -1833,7 +1832,7 @@ main(int argc, char **argv)
18331832}
18341833break ;
18351834case 'C' :
1836- is_connect = 1 ;
1835+ is_connect = true ;
18371836break ;
18381837case 's' :
18391838scale_given = true;
@@ -1955,6 +1954,12 @@ main(int argc, char **argv)
19551954exit (1 );
19561955}
19571956
1957+ /*
1958+ * save main process id in the global variable because process id will be
1959+ * changed after fork.
1960+ */
1961+ main_pid = (int )getpid ();
1962+
19581963if (nclients > 1 )
19591964{
19601965state = (CState * )realloc (state ,sizeof (CState )* nclients );
@@ -1980,20 +1985,6 @@ main(int argc, char **argv)
19801985}
19811986}
19821987
1983- if (use_log )
1984- {
1985- char logpath [64 ];
1986-
1987- snprintf (logpath ,64 ,"pgbench_log.%d" , (int )getpid ());
1988- LOGFILE = fopen (logpath ,"w" );
1989-
1990- if (LOGFILE == NULL )
1991- {
1992- fprintf (stderr ,"Couldn't open logfile \"%s\": %s" ,logpath ,strerror (errno ));
1993- exit (1 );
1994- }
1995- }
1996-
19971988if (debug )
19981989{
19991990if (duration <=0 )
@@ -2111,6 +2102,7 @@ main(int argc, char **argv)
21112102threads = (TState * )malloc (sizeof (TState )* nthreads );
21122103for (i = 0 ;i < nthreads ;i ++ )
21132104{
2105+ threads [i ].tid = i ;
21142106threads [i ].state = & state [nclients /nthreads * i ];
21152107threads [i ].nstate = nclients /nthreads ;
21162108INSTR_TIME_SET_CURRENT (threads [i ].start_time );
@@ -2159,8 +2151,6 @@ main(int argc, char **argv)
21592151INSTR_TIME_SET_CURRENT (total_time );
21602152INSTR_TIME_SUBTRACT (total_time ,start_time );
21612153printResults (ttype ,total_xacts ,nclients ,nthreads ,total_time ,conn_total_time );
2162- if (LOGFILE )
2163- fclose (LOGFILE );
21642154
21652155return 0 ;
21662156}
@@ -2171,6 +2161,7 @@ threadRun(void *arg)
21712161TState * thread = (TState * )arg ;
21722162CState * state = thread -> state ;
21732163TResult * result ;
2164+ FILE * logfile = NULL ;/* per-thread log file */
21742165instr_time start ,
21752166end ;
21762167int nstate = thread -> nstate ;
@@ -2180,7 +2171,25 @@ threadRun(void *arg)
21802171result = malloc (sizeof (TResult ));
21812172INSTR_TIME_SET_ZERO (result -> conn_time );
21822173
2183- if (is_connect == 0 )
2174+ /* open log file if requested */
2175+ if (use_log )
2176+ {
2177+ char logpath [64 ];
2178+
2179+ if (thread -> tid == 0 )
2180+ snprintf (logpath ,sizeof (logpath ),"pgbench_log.%d" ,main_pid );
2181+ else
2182+ snprintf (logpath ,sizeof (logpath ),"pgbench_log.%d.%d" ,main_pid ,thread -> tid );
2183+ logfile = fopen (logpath ,"w" );
2184+
2185+ if (logfile == NULL )
2186+ {
2187+ fprintf (stderr ,"Couldn't open logfile \"%s\": %s" ,logpath ,strerror (errno ));
2188+ gotodone ;
2189+ }
2190+ }
2191+
2192+ if (!is_connect )
21842193{
21852194/* make connections to the database */
21862195for (i = 0 ;i < nstate ;i ++ )
@@ -2202,7 +2211,7 @@ threadRun(void *arg)
22022211int prev_ecnt = st -> ecnt ;
22032212
22042213st -> use_file = getrand (0 ,num_files - 1 );
2205- if (!doCustom (st ,& result -> conn_time ))
2214+ if (!doCustom (st ,& result -> conn_time , logfile ))
22062215remains -- ;/* I've aborted */
22072216
22082217if (st -> ecnt > prev_ecnt && commands [st -> state ]-> type == META_COMMAND )
@@ -2304,7 +2313,7 @@ threadRun(void *arg)
23042313if (st -> con && (FD_ISSET (PQsocket (st -> con ),& input_mask )
23052314|| commands [st -> state ]-> type == META_COMMAND ))
23062315{
2307- if (!doCustom (st ,& result -> conn_time ))
2316+ if (!doCustom (st ,& result -> conn_time , logfile ))
23082317remains -- ;/* I've aborted */
23092318}
23102319
@@ -2326,6 +2335,8 @@ threadRun(void *arg)
23262335result -> xacts += state [i ].cnt ;
23272336INSTR_TIME_SET_CURRENT (end );
23282337INSTR_TIME_ACCUM_DIFF (result -> conn_time ,end ,start );
2338+ if (logfile )
2339+ fclose (logfile );
23292340return result ;
23302341}
23312342