@@ -172,6 +172,7 @@ int agg_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
214215 int nvariables ;
215216 instr_time txn_begin ; /* used for measuring transaction latencies */
216217 instr_time stmt_begin ; /* used for measuring statement latencies */
218+ int64 txn_latencies ; /* cumulated latencies */
219+ int64 txn_sqlats ; /* cumulated square latencies */
217220 bool is_throttled ; /* whether transaction throttling is done */
218221 int use_file ; /* index in sql_files for this client */
219222 bool prepared [MAX_FILES ];
@@ -243,6 +246,8 @@ typedef struct
243246{
244247 instr_time conn_time ;
245248 int xacts ;
249+ int64 latencies ;
250+ int64 sqlats ;
246251 int64 throttle_lag ;
247252 int64 throttle_lag_max ;
248253} TResult ;
@@ -1006,6 +1011,26 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
10061011 thread -> 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
11951220 goto top ;
11961221 }
11971222
1198- /* Record transaction start time if logging is enabled */
1199- if (logfile && st -> state == 0 )
1223+ /* Record transaction start time under logging, progress or throttling */
1224+ if (( logfile || progress || throttle_delay ) && st -> state == 0 )
12001225 INSTR_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 ,
21062131 TState * threads , int nthreads ,
21072132 instr_time total_time , instr_time conn_total_time ,
2133+ int64 total_latencies , int64 total_sqlats ,
21082134 int64 throttle_lag , int64 throttle_lag_max )
21092135{
21102136 double time_include ,
@@ -2144,6 +2170,22 @@ printResults(int ttype, int normal_xacts, int nclients,
21442170 normal_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+
21472189 if (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: %.3f ms (max %.3f ms) \n" ,
2197+ printf ("rate limit schedule lag: avg %.3f (max %.3f) ms\n" ,
21562198 0.001 * throttle_lag / normal_xacts , 0.001 * throttle_lag_max );
21572199 }
21582200
@@ -2263,7 +2305,9 @@ main(int argc, char **argv)
22632305 instr_time start_time ; /* start up time */
22642306 instr_time total_time ;
22652307 instr_time conn_total_time ;
2266- int total_xacts ;
2308+ int total_xacts = 0 ;
2309+ int64 total_latencies = 0 ;
2310+ int64 total_sqlats = 0 ;
22672311 int64 throttle_lag = 0 ;
22682312 int64 throttle_lag_max = 0 ;
22692313
@@ -2617,6 +2661,7 @@ main(int argc, char **argv)
26172661 */
26182662 main_pid = (int ) getpid ();
26192663 progress_nclients = nclients ;
2664+ progress_nthreads = nthreads ;
26202665
26212666 if (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 ;
28292873 INSTR_TIME_SET_ZERO (conn_total_time );
28302874 for (i = 0 ; i < nthreads ; i ++ )
28312875 {
@@ -2841,6 +2885,8 @@ main(int argc, char **argv)
28412885 TResult * r = (TResult * ) ret ;
28422886
28432887 total_xacts += r -> xacts ;
2888+ total_latencies += r -> latencies ;
2889+ total_sqlats += r -> sqlats ;
28442890 throttle_lag += r -> throttle_lag ;
28452891 if (r -> throttle_lag_max > throttle_lag_max )
28462892 throttle_lag_max = r -> throttle_lag_max ;
@@ -2854,7 +2900,8 @@ main(int argc, char **argv)
28542900 INSTR_TIME_SET_CURRENT (total_time );
28552901 INSTR_TIME_SUBTRACT (total_time , start_time );
28562902 printResults (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
28592906 return 0 ;
28602907}
@@ -2875,7 +2922,7 @@ threadRun(void *arg)
28752922 int64 thread_start = INSTR_TIME_GET_MICROSEC (thread -> start_time );
28762923 int64 last_report = thread_start ;
28772924 int64 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
28802927 AggVals aggs ;
28812928
@@ -3075,21 +3122,40 @@ threadRun(void *arg)
30753122 if (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 ;
30793127 int64 run = now - last_report ;
3080- double tps , total_run , latency ;
3128+ double tps , total_run , latency , sqlat , stdev , lag ;
30813129
30823130 for (i = 0 ; i < nstate ; i ++ )
3131+ {
30833132 count += state [i ].cnt ;
3133+ lats += state [i ].txn_latencies ;
3134+ sqlats += state [i ].txn_sqlats ;
3135+ }
30843136
30853137 total_run = (now - thread_start ) / 1000000.0 ;
30863138 tps = 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
30923155 last_count = count ;
3156+ last_lats = lats ;
3157+ last_sqlats = sqlats ;
3158+ last_lags = lags ;
30933159 last_report = now ;
30943160 next_report += progress * 1000000 ;
30953161 }
@@ -3105,21 +3171,42 @@ threadRun(void *arg)
31053171 if (now >= next_report )
31063172 {
31073173 /* generate and show report */
3108- int64 count = 0 ;
3174+ int64 count = 0 , lats = 0 , sqlats = 0 , lags = 0 ;
31093175 int64 run = now - last_report ;
3110- double tps , total_run , latency ;
3176+ double tps , total_run , latency , sqlat , lag , stdev ;
31113177
31123178 for (i = 0 ; i < progress_nclients ; i ++ )
3179+ {
31133180 count += 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
31153188 total_run = (now - thread_start ) / 1000000.0 ;
31163189 tps = 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
31223206 last_count = count ;
3207+ last_lats = lats ;
3208+ last_sqlats = sqlats ;
3209+ last_lags = lags ;
31233210 last_report = now ;
31243211 next_report += progress * 1000000 ;
31253212 }
@@ -3131,8 +3218,14 @@ threadRun(void *arg)
31313218 INSTR_TIME_SET_CURRENT (start );
31323219 disconnect_all (state , nstate );
31333220 result -> xacts = 0 ;
3221+ result -> latencies = 0 ;
3222+ result -> sqlats = 0 ;
31343223 for (i = 0 ; i < nstate ; i ++ )
3224+ {
31353225 result -> xacts += state [i ].cnt ;
3226+ result -> latencies += state [i ].txn_latencies ;
3227+ result -> sqlats += state [i ].txn_sqlats ;
3228+ }
31363229 result -> throttle_lag = thread -> throttle_lag ;
31373230 result -> throttle_lag_max = thread -> throttle_lag_max ;
31383231 INSTR_TIME_SET_CURRENT (end );
0 commit comments