@@ -172,6 +172,7 @@ intagg_interval;/* log aggregates instead of individual
172172 * transactions */
173173int progress = 0 ;/* thread progress report every this seconds */
174174int progress_nclients = 0 ;/* number of clients for progress report */
175+ int progress_nthreads = 0 ;/* number of threads for progress report */
175176bool is_connect ;/* establish connection for each transaction */
176177bool is_latencies ;/* report per-command latencies */
177178int main_pid ;/* main process id used in log filename */
@@ -214,6 +215,8 @@ typedef struct
214215int nvariables ;
215216instr_time txn_begin ;/* used for measuring transaction latencies */
216217instr_time stmt_begin ;/* used for measuring statement latencies */
218+ int64 txn_latencies ;/* cumulated latencies */
219+ int64 txn_sqlats ;/* cumulated square latencies */
217220bool is_throttled ;/* whether transaction throttling is done */
218221int use_file ;/* index in sql_files for this client */
219222bool prepared [MAX_FILES ];
@@ -243,6 +246,8 @@ typedef struct
243246{
244247instr_time conn_time ;
245248int xacts ;
249+ int64 latencies ;
250+ int64 sqlats ;
246251int64 throttle_lag ;
247252int64 throttle_lag_max ;
248253}TResult ;
@@ -1006,6 +1011,26 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
10061011thread -> exec_count [cnum ]++ ;
10071012}
10081013
1014+ /* transaction finished: record latency under progress or throttling */
1015+ if ((progress || throttle_delay )&& commands [st -> state + 1 ]== NULL )
1016+ {
1017+ instr_time diff ;
1018+ int64 latency ;
1019+
1020+ INSTR_TIME_SET_CURRENT (diff );
1021+ INSTR_TIME_SUBTRACT (diff ,st -> txn_begin );
1022+ latency = INSTR_TIME_GET_MICROSEC (diff );
1023+ st -> txn_latencies += latency ;
1024+ /*
1025+ * XXX In a long benchmark run of high-latency transactions, this
1026+ * int64 addition eventually overflows. For example, 100 threads
1027+ * running 10s transactions will overflow it in 2.56 hours. With
1028+ * a more-typical OLTP workload of .1s transactions, overflow
1029+ * would take 256 hours.
1030+ */
1031+ st -> txn_sqlats += latency * latency ;
1032+ }
1033+
10091034/*
10101035 * if transaction finished, record the time it took in the log
10111036 */
@@ -1195,8 +1220,8 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
11951220gototop ;
11961221}
11971222
1198- /* Record transaction start timeif logging is enabled */
1199- if (logfile && st -> state == 0 )
1223+ /* Record transaction start timeunder logging, progress or throttling */
1224+ if (( logfile || progress || throttle_delay ) && st -> state == 0 )
12001225INSTR_TIME_SET_CURRENT (st -> txn_begin );
12011226
12021227/* Record statement start time if per-command latencies are requested */
@@ -2105,6 +2130,7 @@ static void
21052130printResults (int ttype ,int normal_xacts ,int nclients ,
21062131TState * threads ,int nthreads ,
21072132instr_time total_time ,instr_time conn_total_time ,
2133+ int64 total_latencies ,int64 total_sqlats ,
21082134int64 throttle_lag ,int64 throttle_lag_max )
21092135{
21102136double time_include ,
@@ -2144,6 +2170,22 @@ printResults(int ttype, int normal_xacts, int nclients,
21442170normal_xacts );
21452171}
21462172
2173+ if (throttle_delay || progress )
2174+ {
2175+ /* compute and show latency average and standard deviation */
2176+ double latency = 0.001 * total_latencies /normal_xacts ;
2177+ double sqlat = (double )total_sqlats /normal_xacts ;
2178+ printf ("latency average: %.3f ms\n"
2179+ "latency stddev: %.3f ms\n" ,
2180+ latency ,0.001 * sqrt (sqlat - 1000000.0 * latency * latency ));
2181+ }
2182+ else
2183+ {
2184+ /* only an average latency computed from the duration is available */
2185+ printf ("latency average: %.3f ms\n" ,
2186+ 1000.0 * duration * nclients /normal_xacts );
2187+ }
2188+
21472189if (throttle_delay )
21482190{
21492191/*
@@ -2152,7 +2194,7 @@ printResults(int ttype, int normal_xacts, int nclients,
21522194 * transaction. The measured lag may be caused by thread/client load,
21532195 * the database load, or the Poisson throttling process.
21542196 */
2155- printf ("average rate limit schedule lag: %.3fms (max %.3f ms) \n" ,
2197+ printf ("rate limit schedule lag:avg %.3f (max %.3f) ms\n" ,
215621980.001 * throttle_lag /normal_xacts ,0.001 * throttle_lag_max );
21572199}
21582200
@@ -2263,7 +2305,9 @@ main(int argc, char **argv)
22632305instr_time start_time ;/* start up time */
22642306instr_time total_time ;
22652307instr_time conn_total_time ;
2266- int total_xacts ;
2308+ int total_xacts = 0 ;
2309+ int64 total_latencies = 0 ;
2310+ int64 total_sqlats = 0 ;
22672311int64 throttle_lag = 0 ;
22682312int64 throttle_lag_max = 0 ;
22692313
@@ -2617,6 +2661,7 @@ main(int argc, char **argv)
26172661 */
26182662main_pid = (int )getpid ();
26192663progress_nclients = nclients ;
2664+ progress_nthreads = nthreads ;
26202665
26212666if (nclients > 1 )
26222667{
@@ -2825,7 +2870,6 @@ main(int argc, char **argv)
28252870}
28262871
28272872/* wait for threads and accumulate results */
2828- total_xacts = 0 ;
28292873INSTR_TIME_SET_ZERO (conn_total_time );
28302874for (i = 0 ;i < nthreads ;i ++ )
28312875{
@@ -2841,6 +2885,8 @@ main(int argc, char **argv)
28412885TResult * r = (TResult * )ret ;
28422886
28432887total_xacts += r -> xacts ;
2888+ total_latencies += r -> latencies ;
2889+ total_sqlats += r -> sqlats ;
28442890throttle_lag += r -> throttle_lag ;
28452891if (r -> throttle_lag_max > throttle_lag_max )
28462892throttle_lag_max = r -> throttle_lag_max ;
@@ -2854,7 +2900,8 @@ main(int argc, char **argv)
28542900INSTR_TIME_SET_CURRENT (total_time );
28552901INSTR_TIME_SUBTRACT (total_time ,start_time );
28562902printResults (ttype ,total_xacts ,nclients ,threads ,nthreads ,
2857- total_time ,conn_total_time ,throttle_lag ,throttle_lag_max );
2903+ total_time ,conn_total_time ,total_latencies ,total_sqlats ,
2904+ throttle_lag ,throttle_lag_max );
28582905
28592906return 0 ;
28602907}
@@ -2875,7 +2922,7 @@ threadRun(void *arg)
28752922int64 thread_start = INSTR_TIME_GET_MICROSEC (thread -> start_time );
28762923int64 last_report = thread_start ;
28772924int64 next_report = last_report + progress * 1000000 ;
2878- int64 last_count = 0 ;
2925+ int64 last_count = 0 , last_lats = 0 , last_sqlats = 0 , last_lags = 0 ;
28792926
28802927AggVals aggs ;
28812928
@@ -3075,21 +3122,40 @@ threadRun(void *arg)
30753122if (now >=next_report )
30763123{
30773124/* generate and show report */
3078- int64 count = 0 ;
3125+ int64 count = 0 ,lats = 0 ,sqlats = 0 ;
3126+ int64 lags = thread -> throttle_lag ;
30793127int64 run = now - last_report ;
3080- double tps ,total_run ,latency ;
3128+ double tps ,total_run ,latency , sqlat , stdev , lag ;
30813129
30823130for (i = 0 ;i < nstate ;i ++ )
3131+ {
30833132count += state [i ].cnt ;
3133+ lats += state [i ].txn_latencies ;
3134+ sqlats += state [i ].txn_sqlats ;
3135+ }
30843136
30853137total_run = (now - thread_start ) /1000000.0 ;
30863138tps = 1000000.0 * (count - last_count ) /run ;
3087- latency = 1000.0 * nstate /tps ;
3139+ latency = 0.001 * (lats - last_lats ) / (count - last_count );
3140+ sqlat = 1.0 * (sqlats - last_sqlats ) / (count - last_count );
3141+ stdev = 0.001 * sqrt (sqlat - 1000000.0 * latency * latency );
3142+ lag = 0.001 * (lags - last_lags ) / (count - last_count );
30883143
3089- fprintf (stderr ,"progress %d: %.1f s, %.1f tps, %.3f ms lat\n" ,
3090- thread -> tid ,total_run ,tps ,latency );
3144+ if (throttle_delay )
3145+ fprintf (stderr ,
3146+ "progress %d: %.1f s, %.1f tps, "
3147+ "lat %.3f ms stddev %.3f, lag %.3f ms\n" ,
3148+ thread -> tid ,total_run ,tps ,latency ,stdev ,lag );
3149+ else
3150+ fprintf (stderr ,
3151+ "progress %d: %.1f s, %.1f tps, "
3152+ "lat %.3f ms stddev %.3f\n" ,
3153+ thread -> tid ,total_run ,tps ,latency ,stdev );
30913154
30923155last_count = count ;
3156+ last_lats = lats ;
3157+ last_sqlats = sqlats ;
3158+ last_lags = lags ;
30933159last_report = now ;
30943160next_report += progress * 1000000 ;
30953161}
@@ -3105,21 +3171,42 @@ threadRun(void *arg)
31053171if (now >=next_report )
31063172{
31073173/* generate and show report */
3108- int64 count = 0 ;
3174+ int64 count = 0 , lats = 0 , sqlats = 0 , lags = 0 ;
31093175int64 run = now - last_report ;
3110- double tps ,total_run ,latency ;
3176+ double tps ,total_run ,latency , sqlat , lag , stdev ;
31113177
31123178for (i = 0 ;i < progress_nclients ;i ++ )
3179+ {
31133180count += state [i ].cnt ;
3181+ lats += state [i ].txn_latencies ;
3182+ sqlats += state [i ].txn_sqlats ;
3183+ }
3184+
3185+ for (i = 0 ;i < progress_nthreads ;i ++ )
3186+ lags += thread [i ].throttle_lag ;
31143187
31153188total_run = (now - thread_start ) /1000000.0 ;
31163189tps = 1000000.0 * (count - last_count ) /run ;
3117- latency = 1000.0 * progress_nclients /tps ;
3190+ latency = 0.001 * (lats - last_lats ) / (count - last_count );
3191+ sqlat = 1.0 * (sqlats - last_sqlats ) / (count - last_count );
3192+ stdev = 0.001 * sqrt (sqlat - 1000000.0 * latency * latency );
3193+ lag = 0.001 * (lags - last_lags ) / (count - last_count );
31183194
3119- fprintf (stderr ,"progress: %.1f s, %.1f tps, %.3f ms lat\n" ,
3120- total_run ,tps ,latency );
3195+ if (throttle_delay )
3196+ fprintf (stderr ,
3197+ "progress: %.1f s, %.1f tps, "
3198+ "lat %.3f ms stddev %.3f, lag %.3f ms\n" ,
3199+ total_run ,tps ,latency ,stdev ,lag );
3200+ else
3201+ fprintf (stderr ,
3202+ "progress: %.1f s, %.1f tps, "
3203+ "lat %.3f ms stddev %.3f\n" ,
3204+ total_run ,tps ,latency ,stdev );
31213205
31223206last_count = count ;
3207+ last_lats = lats ;
3208+ last_sqlats = sqlats ;
3209+ last_lags = lags ;
31233210last_report = now ;
31243211next_report += progress * 1000000 ;
31253212}
@@ -3131,8 +3218,14 @@ threadRun(void *arg)
31313218INSTR_TIME_SET_CURRENT (start );
31323219disconnect_all (state ,nstate );
31333220result -> xacts = 0 ;
3221+ result -> latencies = 0 ;
3222+ result -> sqlats = 0 ;
31343223for (i = 0 ;i < nstate ;i ++ )
3224+ {
31353225result -> xacts += state [i ].cnt ;
3226+ result -> latencies += state [i ].txn_latencies ;
3227+ result -> sqlats += state [i ].txn_sqlats ;
3228+ }
31363229result -> throttle_lag = thread -> throttle_lag ;
31373230result -> throttle_lag_max = thread -> throttle_lag_max ;
31383231INSTR_TIME_SET_CURRENT (end );