@@ -229,7 +229,7 @@ typedef struct SimpleStats
229
229
typedef struct StatsData
230
230
{
231
231
time_t start_time ; /* interval start time, for aggregates */
232
- int64 cnt ; /* number of transactions */
232
+ int64 cnt ; /* number of transactions, including skipped */
233
233
int64 skipped ; /* number of transactions skipped under --rate
234
234
* and --latency-limit */
235
235
SimpleStats latency ;
@@ -329,7 +329,7 @@ typedef struct
329
329
bool prepared [MAX_SCRIPTS ]; /* whether client prepared the script */
330
330
331
331
/* per client collected stats */
332
- int64 cnt ; /* transaction count */
332
+ int64 cnt ; /* client transaction count, for -t */
333
333
int ecnt ; /* error count */
334
334
} CState ;
335
335
@@ -2062,10 +2062,11 @@ doCustom(TState *thread, CState *st, StatsData *agg)
2062
2062
}
2063
2063
2064
2064
/*
2065
- * If this --latency-limit is used, and this slot is already
2066
- * late so that the transaction will miss the latency limit
2067
- * even if it completed immediately, we skip this time slot
2068
- * and iterate till the next slot that isn't late yet.
2065
+ * If --latency-limit is used, and this slot is already late
2066
+ * so that the transaction will miss the latency limit even if
2067
+ * it completed immediately, we skip this time slot and
2068
+ * iterate till the next slot that isn't late yet. But don't
2069
+ * iterate beyond the -t limit, if one is given.
2069
2070
*/
2070
2071
if (latency_limit )
2071
2072
{
@@ -2074,14 +2075,21 @@ doCustom(TState *thread, CState *st, StatsData *agg)
2074
2075
if (INSTR_TIME_IS_ZERO (now ))
2075
2076
INSTR_TIME_SET_CURRENT (now );
2076
2077
now_us = INSTR_TIME_GET_MICROSEC (now );
2077
- while (thread -> throttle_trigger < now_us - latency_limit )
2078
+ while (thread -> throttle_trigger < now_us - latency_limit &&
2079
+ (nxacts <= 0 || st -> cnt < nxacts ))
2078
2080
{
2079
2081
processXactStats (thread , st , & now , true, agg );
2080
2082
/* next rendez-vous */
2081
2083
wait = getPoissonRand (thread , throttle_delay );
2082
2084
thread -> throttle_trigger += wait ;
2083
2085
st -> txn_scheduled = thread -> throttle_trigger ;
2084
2086
}
2087
+ /* stop client if -t exceeded */
2088
+ if (nxacts > 0 && st -> cnt >= nxacts )
2089
+ {
2090
+ st -> state = CSTATE_FINISHED ;
2091
+ break ;
2092
+ }
2085
2093
}
2086
2094
2087
2095
st -> state = CSTATE_THROTTLE ;
@@ -2393,15 +2401,8 @@ doCustom(TState *thread, CState *st, StatsData *agg)
2393
2401
*/
2394
2402
case CSTATE_END_TX :
2395
2403
2396
- /*
2397
- * transaction finished: calculate latency and log the
2398
- * transaction
2399
- */
2400
- if (progress || throttle_delay || latency_limit ||
2401
- per_script_stats || use_log )
2402
- processXactStats (thread , st , & now , false, agg );
2403
- else
2404
- thread -> stats .cnt ++ ;
2404
+ /* transaction finished: calculate latency and do log */
2405
+ processXactStats (thread , st , & now , false, agg );
2405
2406
2406
2407
if (is_connect )
2407
2408
{
@@ -2410,7 +2411,6 @@ doCustom(TState *thread, CState *st, StatsData *agg)
2410
2411
INSTR_TIME_SET_ZERO (now );
2411
2412
}
2412
2413
2413
- ++ st -> cnt ;
2414
2414
if ((st -> cnt >= nxacts && duration <= 0 ) || timer_exceeded )
2415
2415
{
2416
2416
/* exit success */
@@ -2540,35 +2540,45 @@ doLog(TState *thread, CState *st,
2540
2540
/*
2541
2541
* Accumulate and report statistics at end of a transaction.
2542
2542
*
2543
- * (This is also called when a transaction is late and thus skipped.)
2543
+ * (This is also called when a transaction is late and thus skipped.
2544
+ * Note that even skipped transactions are counted in the "cnt" fields.)
2544
2545
*/
2545
2546
static void
2546
2547
processXactStats (TState * thread , CState * st , instr_time * now ,
2547
2548
bool skipped , StatsData * agg )
2548
2549
{
2549
2550
double latency = 0.0 ,
2550
2551
lag = 0.0 ;
2552
+ bool thread_details = progress || throttle_delay || latency_limit ,
2553
+ detailed = thread_details || use_log || per_script_stats ;
2551
2554
2552
- if ((!skipped ) && INSTR_TIME_IS_ZERO (* now ))
2553
- INSTR_TIME_SET_CURRENT (* now );
2554
-
2555
- if (!skipped )
2555
+ if (detailed && !skipped )
2556
2556
{
2557
+ if (INSTR_TIME_IS_ZERO (* now ))
2558
+ INSTR_TIME_SET_CURRENT (* now );
2559
+
2557
2560
/* compute latency & lag */
2558
2561
latency = INSTR_TIME_GET_MICROSEC (* now ) - st -> txn_scheduled ;
2559
2562
lag = INSTR_TIME_GET_MICROSEC (st -> txn_begin ) - st -> txn_scheduled ;
2560
2563
}
2561
2564
2562
- if (progress || throttle_delay || latency_limit )
2565
+ if (thread_details )
2563
2566
{
2567
+ /* keep detailed thread stats */
2564
2568
accumStats (& thread -> stats , skipped , latency , lag );
2565
2569
2566
2570
/* count transactions over the latency limit, if needed */
2567
2571
if (latency_limit && latency > latency_limit )
2568
2572
thread -> latency_late ++ ;
2569
2573
}
2570
2574
else
2575
+ {
2576
+ /* no detailed stats, just count */
2571
2577
thread -> stats .cnt ++ ;
2578
+ }
2579
+
2580
+ /* client stat is just counting */
2581
+ st -> cnt ++ ;
2572
2582
2573
2583
if (use_log )
2574
2584
doLog (thread , st , agg , skipped , latency , lag );
@@ -3534,7 +3544,7 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
3534
3544
{
3535
3545
printf ("number of transactions per client: %d\n" , nxacts );
3536
3546
printf ("number of transactions actually processed: " INT64_FORMAT "/%d\n" ,
3537
- total -> cnt , nxacts * nclients );
3547
+ total -> cnt - total -> skipped , nxacts * nclients );
3538
3548
}
3539
3549
else
3540
3550
{
@@ -3550,12 +3560,12 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
3550
3560
if (throttle_delay && latency_limit )
3551
3561
printf ("number of transactions skipped: " INT64_FORMAT " (%.3f %%)\n" ,
3552
3562
total -> skipped ,
3553
- 100.0 * total -> skipped / ( total -> skipped + total -> cnt ) );
3563
+ 100.0 * total -> skipped / total -> cnt );
3554
3564
3555
3565
if (latency_limit )
3556
3566
printf ("number of transactions above the %.1f ms latency limit: %d (%.3f %%)\n" ,
3557
3567
latency_limit / 1000.0 , latency_late ,
3558
- 100.0 * latency_late / ( total -> skipped + total -> cnt ) );
3568
+ 100.0 * latency_late / total -> cnt );
3559
3569
3560
3570
if (throttle_delay || progress || latency_limit )
3561
3571
printSimpleStats ("latency" , & total -> latency );
@@ -3604,8 +3614,7 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
3604
3614
if (latency_limit )
3605
3615
printf (" - number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n" ,
3606
3616
sql_script [i ].stats .skipped ,
3607
- 100.0 * sql_script [i ].stats .skipped /
3608
- (sql_script [i ].stats .skipped + sql_script [i ].stats .cnt ));
3617
+ 100.0 * sql_script [i ].stats .skipped / sql_script [i ].stats .cnt );
3609
3618
3610
3619
if (num_scripts > 1 )
3611
3620
printSimpleStats (" - latency" , & sql_script [i ].stats .latency );
@@ -4144,6 +4153,12 @@ main(int argc, char **argv)
4144
4153
exit (1 );
4145
4154
}
4146
4155
4156
+ if (progress_timestamp && progress == 0 )
4157
+ {
4158
+ fprintf (stderr , "--progress-timestamp is allowed only under --progress\n" );
4159
+ exit (1 );
4160
+ }
4161
+
4147
4162
/*
4148
4163
* save main process id in the global variable because process id will be
4149
4164
* changed after fork.
0 commit comments