diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/pgbench/pgbench.c | 33 | ||||
-rw-r--r-- | src/bin/pgbench/t/001_pgbench_with_server.pl | 26 |
2 files changed, 58 insertions, 1 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 763c4b946a4..617b2023b18 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -765,6 +765,8 @@ static int64 total_weight = 0; static bool verbose_errors = false; /* print verbose messages of all errors */ +static bool exit_on_abort = false; /* exit when any client is aborted */ + /* Builtin test scripts */ typedef struct BuiltinScript { @@ -911,6 +913,7 @@ usage(void) " -T, --time=NUM duration of benchmark test in seconds\n" " -v, --vacuum-all vacuum all four standard tables before tests\n" " --aggregate-interval=NUM aggregate data over NUM seconds\n" + " --exit-on-abort exit when any client is aborted\n" " --failures-detailed report the failures grouped by basic types\n" " --log-prefix=PREFIX prefix for transaction time log file\n" " (default: \"pgbench_log\")\n" @@ -6617,6 +6620,7 @@ main(int argc, char **argv) {"failures-detailed", no_argument, NULL, 13}, {"max-tries", required_argument, NULL, 14}, {"verbose-errors", no_argument, NULL, 15}, + {"exit-on-abort", no_argument, NULL, 16}, {NULL, 0, NULL, 0} }; @@ -6950,6 +6954,10 @@ main(int argc, char **argv) benchmarking_option_set = true; verbose_errors = true; break; + case 16: /* exit-on-abort */ + benchmarking_option_set = true; + exit_on_abort = true; + break; default: /* getopt_long already emitted a complaint */ pg_log_error_hint("Try \"%s --help\" for more information.", progname); @@ -7559,10 +7567,17 @@ threadRun(void *arg) advanceConnectionState(thread, st, &aggs); /* + * If --exit-on-abort is used, the program is going to exit + * when any client is aborted. + */ + if (exit_on_abort && st->state == CSTATE_ABORTED) + goto done; + /* * If advanceConnectionState changed client to finished state, * that's one fewer client that remains. */ - if (st->state == CSTATE_FINISHED || st->state == CSTATE_ABORTED) + else if (st->state == CSTATE_FINISHED || + st->state == CSTATE_ABORTED) remains--; } @@ -7595,6 +7610,22 @@ threadRun(void *arg) } done: + if (exit_on_abort) + { + /* + * Abort if any client is not finished, meaning some error occurred. + */ + for (int i = 0; i < nstate; i++) + { + if (state[i].state != CSTATE_FINISHED) + { + pg_log_error("Run was aborted due to an error in thread %d", + thread->tid); + exit(2); + } + } + } + disconnect_all(state, nstate); if (thread->logfile) diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl index 142f966300a..96be529d6bb 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -1475,6 +1475,32 @@ SELECT pg_advisory_unlock_all(); # Clean up $node->safe_psql('postgres', 'DROP TABLE first_client_table, xy;'); +# Test --exit-on-abort +$node->safe_psql('postgres', + 'CREATE TABLE counter(i int); '. + 'INSERT INTO counter VALUES (0);' +); + +$node->pgbench( + '-t 10 -c 2 -j 2 --exit-on-abort', + 2, + [], + [ + qr{division by zero}, + qr{Run was aborted due to an error in thread} + ], + 'test --exit-on-abort', + { + '001_exit_on_abort' => q{ +update counter set i = i+1 returning i \gset +\if :i = 5 +\set y 1/0 +\endif +} + }); + +# Clean up +$node->safe_psql('postgres', 'DROP TABLE counter;'); # done $node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts'); |