@@ -323,6 +323,10 @@ typedef struct
323
323
char * argv [MAX_ARGS ];/* command word list */
324
324
PgBenchExpr * expr ;/* parsed expression, if needed */
325
325
SimpleStats stats ;/* time spent in this command */
326
+ int64 serialization_failures ;/* number of serialization failures in
327
+ * this command */
328
+ int64 deadlock_failures ;/* number of deadlock failures in this
329
+ * command */
326
330
}Command ;
327
331
328
332
typedef struct ParsedScript
@@ -1970,6 +1974,15 @@ doCustom(TState *thread, CState *st, StatsData *agg)
1970
1974
INSTR_TIME_GET_DOUBLE (st -> stmt_begin ));
1971
1975
}
1972
1976
1977
+ /*
1978
+ * accumulate per-command serialization / deadlock failures count in
1979
+ * thread-local data structure
1980
+ */
1981
+ if (serialization_failure )
1982
+ commands [st -> state ]-> serialization_failures ++ ;
1983
+ if (deadlock_failure )
1984
+ commands [st -> state ]-> deadlock_failures ++ ;
1985
+
1973
1986
/* transaction finished: calculate latency and log the transaction */
1974
1987
if (commands [st -> state + 1 ]== NULL )
1975
1988
{
@@ -2877,6 +2890,8 @@ process_sql_command(PQExpBuffer buf, const char *source)
2877
2890
my_command -> type = SQL_COMMAND ;
2878
2891
my_command -> argc = 0 ;
2879
2892
initSimpleStats (& my_command -> stats );
2893
+ my_command -> serialization_failures = 0 ;
2894
+ my_command -> deadlock_failures = 0 ;
2880
2895
2881
2896
/*
2882
2897
* If SQL command is multi-line, we only want to save the first line as
@@ -2946,6 +2961,8 @@ process_backslash_command(PsqlScanState sstate, const char *source)
2946
2961
my_command -> type = META_COMMAND ;
2947
2962
my_command -> argc = 0 ;
2948
2963
initSimpleStats (& my_command -> stats );
2964
+ my_command -> serialization_failures = 0 ;
2965
+ my_command -> deadlock_failures = 0 ;
2949
2966
2950
2967
/* Save first word (command name) */
2951
2968
j = 0 ;
@@ -3462,6 +3479,7 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
3462
3479
if (per_script_stats || latency_limit || is_latencies )
3463
3480
{
3464
3481
int i ;
3482
+ Command * * commands ;
3465
3483
3466
3484
for (i = 0 ;i < num_scripts ;i ++ )
3467
3485
{
@@ -3497,20 +3515,26 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
3497
3515
if (num_scripts > 1 )
3498
3516
printSimpleStats (" - latency" ,& sql_script [i ].stats .latency );
3499
3517
3500
- /* Report per-command latencies */
3518
+ /*
3519
+ * Report per-command serialization / deadlock failures and
3520
+ * latencies (if needed). */
3501
3521
if (is_latencies )
3502
- {
3503
- Command * * commands ;
3504
-
3505
- printf (" - statement latencies in milliseconds:\n" );
3522
+ printf (" - statement serialization, deadlock failures and latencies in milliseconds:\n" );
3523
+ else
3524
+ printf (" - statement serialization and deadlock failures:\n" );
3506
3525
3507
- for (commands = sql_script [i ].commands ;
3508
- * commands != NULL ;
3509
- commands ++ )
3510
- printf (" %11.3f %s\n" ,
3526
+ for (commands = sql_script [i ].commands ;
3527
+ * commands != NULL ;
3528
+ commands ++ )
3529
+ {
3530
+ printf (" %25" INT64_MODIFIER "d %25" INT64_MODIFIER "d" ,
3531
+ (* commands )-> serialization_failures ,
3532
+ (* commands )-> deadlock_failures );
3533
+ if (is_latencies )
3534
+ printf (" %11.3f" ,
3511
3535
1000.0 * (* commands )-> stats .sum /
3512
- (* commands )-> stats .count ,
3513
- (* commands )-> line );
3536
+ (* commands )-> stats .count );
3537
+ printf ( " %s\n" , (* commands )-> line );
3514
3538
}
3515
3539
}
3516
3540
}
@@ -3869,6 +3893,7 @@ main(int argc, char **argv)
3869
3893
case 'I' :
3870
3894
{
3871
3895
benchmarking_option_set = true;
3896
+ per_script_stats = true;
3872
3897
3873
3898
for (default_isolation_level = 0 ;
3874
3899
default_isolation_level < NUM_DEFAULT_ISOLATION_LEVEL ;