Dear Matsumasa,
Here is a v4 that takes into account most of your points: The report is
performed for all threads by thread 0, however --progress is not supported
under thread fork emulation if there are more than one thread. The report
time does not slip anymore.
However I've kept the format scarse. It is a style thing:-) and it is more
consistent with the kind of format used in the log. I have not added the
"latency" measure because it is redundant with the tps, and the latency
that people are expecting is the actual latency of each transactions, not
the apparent latency of transactions running in parallel, which is really
a throuput.
--
Fabien.
diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index 1303217..707ea37 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -74,7 +74,7 @@ static int pthread_join(pthread_t th, void **thread_return);
#include <pthread.h>
#else
/* Use emulation with fork. Rename pthread identifiers to avoid conflicts */
-
+#define PTHREAD_FORK_EMULATION
#include <sys/wait.h>
#define pthread_t pg_pthread_t
@@ -164,6 +164,8 @@ bool use_log; /* log transaction latencies to a file */
bool use_quiet; /* quiet logging onto stderr */
int agg_interval; /* log aggregates instead of individual
* transactions */
+int progress = 0; /* thread progress report every this seconds */
+int progress_nclients = 0; /* number of clients for progress report */
bool is_connect; /* establish connection for each transaction */
bool is_latencies; /* report per-command latencies */
int main_pid; /* main process id used in log filename */
@@ -354,6 +356,8 @@ usage(void)
" protocol for submitting queries to server (default: simple)\n"
" -n do not run VACUUM before tests\n"
" -N do not update tables \"pgbench_tellers\" and \"pgbench_branches\"\n"
+ " -P NUM, --progress NUM\n"
+ " show progress report about every NUM seconds\n"
" -r report average latency per command\n"
" -s NUM report this scale factor in output\n"
" -S perform SELECT-only transactions\n"
@@ -2115,6 +2119,7 @@ main(int argc, char **argv)
{"unlogged-tables", no_argument, &unlogged_tables, 1},
{"sampling-rate", required_argument, NULL, 4},
{"aggregate-interval", required_argument, NULL, 5},
+ {"progress", required_argument, NULL, 'P'},
{NULL, 0, NULL, 0}
};
@@ -2181,7 +2186,7 @@ main(int argc, char **argv)
state = (CState *) pg_malloc(sizeof(CState));
memset(state, 0, sizeof(CState));
- while ((c = getopt_long(argc, argv, "ih:nvp:dqSNc:j:Crs:t:T:U:lf:D:F:M:", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "ih:nvp:dqSNc:j:Crs:t:T:U:lf:D:F:M:P:", long_options, &optindex)) != -1)
{
switch (c)
{
@@ -2336,6 +2341,16 @@ main(int argc, char **argv)
exit(1);
}
break;
+ case 'P':
+ progress = atoi(optarg);
+ if (progress <= 0)
+ {
+ fprintf(stderr,
+ "thread progress delay (-P) must not be negative (%s)\n",
+ optarg);
+ exit(1);
+ }
+ break;
case 0:
/* This covers long options which take no argument. */
break;
@@ -2401,6 +2416,15 @@ main(int argc, char **argv)
exit(1);
}
+#ifdef PTHREAD_FORK_EMULATION
+ if (progress && nthreads>1)
+ {
+ fprintf(stderr,
+ "option --progress does not work with thread fork emulation");
+ exit(1);
+ }
+#endif /* PTHREAD_FORK_EMULATION */
+
/* --sampling-rate may be used only with -l */
if (sample_rate > 0.0 && !use_log)
{
@@ -2461,6 +2485,7 @@ main(int argc, char **argv)
* changed after fork.
*/
main_pid = (int) getpid();
+ progress_nclients = nclients;
if (nclients > 1)
{
@@ -2712,6 +2737,11 @@ threadRun(void *arg)
int nstate = thread->nstate;
int remains = nstate; /* number of remaining clients */
int i;
+ /* for reporting progress: */
+ int64 thread_start = INSTR_TIME_GET_MICROSEC(thread->start_time);
+ int64 last_report = thread_start;
+ int64 next_report = last_report + progress * 1000000;
+ int64 last_count = 0;
AggVals aggs;
@@ -2875,6 +2905,30 @@ threadRun(void *arg)
st->con = NULL;
}
}
+
+ /* progress report by thread 0 */
+ if (progress && thread->tid == 0)
+ {
+ instr_time now_time;
+ int64 now;
+ INSTR_TIME_SET_CURRENT(now_time);
+ now = INSTR_TIME_GET_MICROSEC(now_time);
+ if (now >= next_report)
+ {
+ /* generate and show report */
+ int64 count = 0;
+ int64 run = now - last_report;
+ /* thread 0 reports other threads data */
+ for (i = 0 ; i < progress_nclients ; i++)
+ count += state[i].cnt;
+ fprintf(stderr, "progress: %.1f s %.1f tps\n",
+ (now - thread_start) / 1000000.0,
+ 1000000.0 * (count-last_count) / run);
+ last_count = count;
+ last_report = now;
+ next_report += progress * 1000000;
+ }
+ }
}
done:
diff --git a/doc/src/sgml/pgbench.sgml b/doc/src/sgml/pgbench.sgml
index 8775606..e82757c 100644
--- a/doc/src/sgml/pgbench.sgml
+++ b/doc/src/sgml/pgbench.sgml
@@ -392,6 +392,17 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
</varlistentry>
<varlistentry>
+ <term><option>-P</option> <replaceable>sec</></term>
+ <term><option>--progress</option> <replaceable>sec</></term>
+ <listitem>
+ <para>
+ Show progress report about every <literal>sec</> seconds.
+ Note: this option does not work under thread fork emulation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-s</option> <replaceable>scale_factor</></term>
<listitem>
<para>
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers