diff -cprN head/contrib/pgbench/pgbench.c work/contrib/pgbench/pgbench.c
*** head/contrib/pgbench/pgbench.c 2010-02-26 11:29:55.507518000 +0900
--- work/contrib/pgbench/pgbench.c 2010-03-16 11:48:29.572863239 +0900
*************** int fillfactor = 100;
*** 131,141 ****
#define ntellers 10
#define naccounts 100000
- FILE *LOGFILE = NULL;
-
bool use_log; /* log transaction latencies to a file */
!
! int is_connect; /* establish connection for each transaction */
char *pghost = "";
char *pgport = "";
--- 131,139 ----
#define ntellers 10
#define naccounts 100000
bool use_log; /* log transaction latencies to a file */
! bool is_connect; /* establish connection for each transaction */
! int main_pid; /* main process id used in log filename */
char *pghost = "";
char *pgport = "";
*************** typedef struct
*** 183,188 ****
--- 181,187 ----
*/
typedef struct
{
+ int tid; /* thread id */
pthread_t thread; /* thread handle */
CState *state; /* array of CState */
int nstate; /* length of state[] */
*************** clientDone(CState *st, bool ok)
*** 741,747 ****
/* return false iff client should be disconnected */
static bool
! doCustom(CState *st, instr_time *conn_time)
{
PGresult *res;
Command **commands;
--- 740,746 ----
/* return false iff client should be disconnected */
static bool
! doCustom(CState *st, instr_time *conn_time, FILE *log_file)
{
PGresult *res;
Command **commands;
*************** top:
*** 778,784 ****
/*
* transaction finished: record the time it took in the log
*/
! if (use_log && commands[st->state + 1] == NULL)
{
instr_time now;
instr_time diff;
--- 777,783 ----
/*
* transaction finished: record the time it took in the log
*/
! if (log_file && commands[st->state + 1] == NULL)
{
instr_time now;
instr_time diff;
*************** top:
*** 791,802 ****
#ifndef WIN32
/* This is more than we really ought to know about instr_time */
! fprintf(LOGFILE, "%d %d %.0f %d %ld %ld\n",
st->id, st->cnt, usec, st->use_file,
(long) now.tv_sec, (long) now.tv_usec);
#else
/* On Windows, instr_time doesn't provide a timestamp anyway */
! fprintf(LOGFILE, "%d %d %.0f %d 0 0\n",
st->id, st->cnt, usec, st->use_file);
#endif
}
--- 790,801 ----
#ifndef WIN32
/* This is more than we really ought to know about instr_time */
! fprintf(log_file, "%d %d %.0f %d %ld %ld\n",
st->id, st->cnt, usec, st->use_file,
(long) now.tv_sec, (long) now.tv_usec);
#else
/* On Windows, instr_time doesn't provide a timestamp anyway */
! fprintf(log_file, "%d %d %.0f %d 0 0\n",
st->id, st->cnt, usec, st->use_file);
#endif
}
*************** top:
*** 857,863 ****
INSTR_TIME_ACCUM_DIFF(*conn_time, end, start);
}
! if (use_log && st->state == 0)
INSTR_TIME_SET_CURRENT(st->txn_begin);
if (commands[st->state]->type == SQL_COMMAND)
--- 856,862 ----
INSTR_TIME_ACCUM_DIFF(*conn_time, end, start);
}
! if (log_file && st->state == 0)
INSTR_TIME_SET_CURRENT(st->txn_begin);
if (commands[st->state]->type == SQL_COMMAND)
*************** main(int argc, char **argv)
*** 1833,1839 ****
}
break;
case 'C':
! is_connect = 1;
break;
case 's':
scale_given = true;
--- 1832,1838 ----
}
break;
case 'C':
! is_connect = true;
break;
case 's':
scale_given = true;
*************** main(int argc, char **argv)
*** 1955,1960 ****
--- 1954,1965 ----
exit(1);
}
+ /*
+ * save main process id in the global variable because process id will be
+ * changed after fork.
+ */
+ main_pid = (int) getpid();
+
if (nclients > 1)
{
state = (CState *) realloc(state, sizeof(CState) * nclients);
*************** main(int argc, char **argv)
*** 1980,1999 ****
}
}
- if (use_log)
- {
- char logpath[64];
-
- snprintf(logpath, 64, "pgbench_log.%d", (int) getpid());
- LOGFILE = fopen(logpath, "w");
-
- if (LOGFILE == NULL)
- {
- fprintf(stderr, "Couldn't open logfile \"%s\": %s", logpath, strerror(errno));
- exit(1);
- }
- }
-
if (debug)
{
if (duration <= 0)
--- 1985,1990 ----
*************** main(int argc, char **argv)
*** 2111,2116 ****
--- 2102,2108 ----
threads = (TState *) malloc(sizeof(TState) * nthreads);
for (i = 0; i < nthreads; i++)
{
+ threads[i].tid = i;
threads[i].state = &state[nclients / nthreads * i];
threads[i].nstate = nclients / nthreads;
INSTR_TIME_SET_CURRENT(threads[i].start_time);
*************** main(int argc, char **argv)
*** 2159,2166 ****
INSTR_TIME_SET_CURRENT(total_time);
INSTR_TIME_SUBTRACT(total_time, start_time);
printResults(ttype, total_xacts, nclients, nthreads, total_time, conn_total_time);
- if (LOGFILE)
- fclose(LOGFILE);
return 0;
}
--- 2151,2156 ----
*************** threadRun(void *arg)
*** 2171,2176 ****
--- 2161,2167 ----
TState *thread = (TState *) arg;
CState *state = thread->state;
TResult *result;
+ FILE *log_file = NULL; /* per-thread log file */
instr_time start,
end;
int nstate = thread->nstate;
*************** threadRun(void *arg)
*** 2180,2186 ****
result = malloc(sizeof(TResult));
INSTR_TIME_SET_ZERO(result->conn_time);
! if (is_connect == 0)
{
/* make connections to the database */
for (i = 0; i < nstate; i++)
--- 2171,2195 ----
result = malloc(sizeof(TResult));
INSTR_TIME_SET_ZERO(result->conn_time);
! /* open log file if requested */
! if (use_log)
! {
! char logpath[64];
!
! if (thread->tid == 0)
! snprintf(logpath, 64, "pgbench_log.%d", main_pid);
! else
! snprintf(logpath, 64, "pgbench_log.%d.%d", main_pid, thread->tid);
! log_file = fopen(logpath, "w");
!
! if (log_file == NULL)
! {
! fprintf(stderr, "Couldn't open logfile \"%s\": %s", logpath, strerror(errno));
! goto done;
! }
! }
!
! if (!is_connect)
{
/* make connections to the database */
for (i = 0; i < nstate; i++)
*************** threadRun(void *arg)
*** 2202,2208 ****
int prev_ecnt = st->ecnt;
st->use_file = getrand(0, num_files - 1);
! if (!doCustom(st, &result->conn_time))
remains--; /* I've aborted */
if (st->ecnt > prev_ecnt && commands[st->state]->type == META_COMMAND)
--- 2211,2217 ----
int prev_ecnt = st->ecnt;
st->use_file = getrand(0, num_files - 1);
! if (!doCustom(st, &result->conn_time, log_file))
remains--; /* I've aborted */
if (st->ecnt > prev_ecnt && commands[st->state]->type == META_COMMAND)
*************** threadRun(void *arg)
*** 2304,2310 ****
if (st->con && (FD_ISSET(PQsocket(st->con), &input_mask)
|| commands[st->state]->type == META_COMMAND))
{
! if (!doCustom(st, &result->conn_time))
remains--; /* I've aborted */
}
--- 2313,2319 ----
if (st->con && (FD_ISSET(PQsocket(st->con), &input_mask)
|| commands[st->state]->type == META_COMMAND))
{
! if (!doCustom(st, &result->conn_time, log_file))
remains--; /* I've aborted */
}
*************** done:
*** 2326,2331 ****
--- 2335,2342 ----
result->xacts += state[i].cnt;
INSTR_TIME_SET_CURRENT(end);
INSTR_TIME_ACCUM_DIFF(result->conn_time, end, start);
+ if (log_file)
+ fclose(log_file);
return result;
}
diff -cprN head/doc/src/sgml/pgbench.sgml work/doc/src/sgml/pgbench.sgml
*** head/doc/src/sgml/pgbench.sgml 2009-12-16 09:17:22.613136000 +0900
--- work/doc/src/sgml/pgbench.sgml 2010-03-16 11:59:11.389926000 +0900
*************** END;
*** 551,556 ****
--- 551,564 ----
taken by each transaction to a logfile. The logfile will be named
pgbench_log.nnn>, where
nnn> is the PID of the pgbench process.
+ If -j> option is 2 or higher, each worker threads use a
+ dedicated log file. Those log files except the first thread will be named
+ pgbench_log.nnn>.mmm>,
+ where mmm> is a sequential number of the threads starting
+ with 1.
+
+
+
The format of the log is: