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 @@ int fillfactor = 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 */
186185 pthread_t thread ; /* thread handle */
187186 CState * state ; /* array of CState */
188187 int 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{
746745 PGresult * res ;
747746 Command * * 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 {
783782 instr_time now ;
784783 instr_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" ,
795794 st -> 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" ,
800799 st -> id , st -> cnt , usec , st -> use_file );
801800#endif
802801 }
@@ -857,7 +856,7 @@ doCustom(CState *st, instr_time *conn_time)
857856 INSTR_TIME_ACCUM_DIFF (* conn_time , end , start );
858857 }
859858
860- if (use_log && st -> state == 0 )
859+ if (logfile && st -> state == 0 )
861860 INSTR_TIME_SET_CURRENT (st -> txn_begin );
862861
863862 if (commands [st -> state ]-> type == SQL_COMMAND )
@@ -1833,7 +1832,7 @@ main(int argc, char **argv)
18331832 }
18341833 break ;
18351834 case 'C' :
1836- is_connect = 1 ;
1835+ is_connect = true ;
18371836 break ;
18381837 case 's' :
18391838 scale_given = true;
@@ -1955,6 +1954,12 @@ main(int argc, char **argv)
19551954 exit (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+
19581963 if (nclients > 1 )
19591964 {
19601965 state = (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-
19971988 if (debug )
19981989 {
19991990 if (duration <= 0 )
@@ -2111,6 +2102,7 @@ main(int argc, char **argv)
21112102 threads = (TState * ) malloc (sizeof (TState ) * nthreads );
21122103 for (i = 0 ; i < nthreads ; i ++ )
21132104 {
2105+ threads [i ].tid = i ;
21142106 threads [i ].state = & state [nclients / nthreads * i ];
21152107 threads [i ].nstate = nclients / nthreads ;
21162108 INSTR_TIME_SET_CURRENT (threads [i ].start_time );
@@ -2159,8 +2151,6 @@ main(int argc, char **argv)
21592151 INSTR_TIME_SET_CURRENT (total_time );
21602152 INSTR_TIME_SUBTRACT (total_time , start_time );
21612153 printResults (ttype , total_xacts , nclients , nthreads , total_time , conn_total_time );
2162- if (LOGFILE )
2163- fclose (LOGFILE );
21642154
21652155 return 0 ;
21662156}
@@ -2171,6 +2161,7 @@ threadRun(void *arg)
21712161 TState * thread = (TState * ) arg ;
21722162 CState * state = thread -> state ;
21732163 TResult * result ;
2164+ FILE * logfile = NULL ; /* per-thread log file */
21742165 instr_time start ,
21752166 end ;
21762167 int nstate = thread -> nstate ;
@@ -2180,7 +2171,25 @@ threadRun(void *arg)
21802171 result = malloc (sizeof (TResult ));
21812172 INSTR_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+ goto done ;
2189+ }
2190+ }
2191+
2192+ if (!is_connect )
21842193 {
21852194 /* make connections to the database */
21862195 for (i = 0 ; i < nstate ; i ++ )
@@ -2202,7 +2211,7 @@ threadRun(void *arg)
22022211 int prev_ecnt = st -> ecnt ;
22032212
22042213 st -> use_file = getrand (0 , num_files - 1 );
2205- if (!doCustom (st , & result -> conn_time ))
2214+ if (!doCustom (st , & result -> conn_time , logfile ))
22062215 remains -- ; /* I've aborted */
22072216
22082217 if (st -> ecnt > prev_ecnt && commands [st -> state ]-> type == META_COMMAND )
@@ -2304,7 +2313,7 @@ threadRun(void *arg)
23042313 if (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 ))
23082317 remains -- ; /* I've aborted */
23092318 }
23102319
@@ -2326,6 +2335,8 @@ threadRun(void *arg)
23262335 result -> xacts += state [i ].cnt ;
23272336 INSTR_TIME_SET_CURRENT (end );
23282337 INSTR_TIME_ACCUM_DIFF (result -> conn_time , end , start );
2338+ if (logfile )
2339+ fclose (logfile );
23292340 return result ;
23302341}
23312342
0 commit comments