Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3c66264

Browse files
committed
Allow pgbench to exit immediately when any client is aborted.
Previously when client was aborted due to some error during benchmarking, other clients continued their run until certain number of transactions specified -t was reached or the time specified by -T was expired. At the end, the results are printed with caution: "Run was aborted; the above results are incomplete" shows. New option "--exit-on-abort" allows pgbench to exit immediately in this case so that users could quickly fix the cause of the failure and try again another round of benchmarking. Author: Yugo Nagata Reviewed-by: Fabien COELHO, Tatsuo Ishii Discussion: https://postgr.es/m/flat/20230804130325.df32e60879c38c92bca64207%40sraoss.co.jp
1 parent 8bf7db0 commit 3c66264

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

doc/src/sgml/ref/pgbench.sgml

+25-3
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,24 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
768768
</listitem>
769769
</varlistentry>
770770

771+
<varlistentry id="pgbench-option-exit-on-abort">
772+
<term><option>--exit-on-abort</option></term>
773+
<listitem>
774+
<para>
775+
Exit immediately when any client is aborted due to some error. Without
776+
this option, even when a client is aborted, other clients could
777+
continue their run as specified by <option>-t</option>
778+
or <option>-T</option> option, and <application>pgbench</application>
779+
will print an incomplete results in this case.
780+
</para>
781+
<para>
782+
Note that serialization failures or deadlock failures do not abort the
783+
client, so they are not affected by this option.
784+
See <xref linkend="failures-and-retries"/> for more information.
785+
</para>
786+
</listitem>
787+
</varlistentry>
788+
771789
<varlistentry id="pgbench-option-failures-detailed">
772790
<term><option>--failures-detailed</option></term>
773791
<listitem>
@@ -985,7 +1003,8 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
9851003
benchmark such as initial connection failures also exit with status 1.
9861004
Errors during the run such as database errors or problems in the script
9871005
will result in exit status 2. In the latter case,
988-
<application>pgbench</application> will print partial results.
1006+
<application>pgbench</application> will print partial results if
1007+
<option>--exit-on-abort</option> option is not specified.
9891008
</para>
9901009
</refsect1>
9911010

@@ -2801,14 +2820,17 @@ statement latencies in milliseconds, failures and retries:
28012820
start a connection to the database server / the socket for connecting
28022821
the client to the database server has become invalid). In such cases
28032822
all clients of this thread stop while other threads continue to work.
2823+
However, <option>--exit-on-abort</option> is specified, all of the
2824+
threads stop immediately in this case.
28042825
</para>
28052826
</listitem>
28062827
<listitem>
28072828
<para>
28082829
Direct client errors. They lead to immediate exit from
28092830
<application>pgbench</application> with the corresponding error message
2810-
only in the case of an internal <application>pgbench</application>
2811-
error (which are supposed to never occur...). Otherwise in the worst
2831+
in the case of an internal <application>pgbench</application>
2832+
error (which are supposed to never occur...) or when
2833+
<option>--exit-on-abort</option> is specified. Otherwise in the worst
28122834
case they only lead to the abortion of the failed client while other
28132835
clients continue their run (but some client errors are handled without
28142836
an abortion of the client and reported separately, see below). Later in

src/bin/pgbench/pgbench.c

+32-1
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ static int64 total_weight = 0;
765765

766766
static bool verbose_errors = false; /* print verbose messages of all errors */
767767

768+
static bool exit_on_abort = false; /* exit when any client is aborted */
769+
768770
/* Builtin test scripts */
769771
typedef struct BuiltinScript
770772
{
@@ -911,6 +913,7 @@ usage(void)
911913
" -T, --time=NUM duration of benchmark test in seconds\n"
912914
" -v, --vacuum-all vacuum all four standard tables before tests\n"
913915
" --aggregate-interval=NUM aggregate data over NUM seconds\n"
916+
" --exit-on-abort exit when any client is aborted\n"
914917
" --failures-detailed report the failures grouped by basic types\n"
915918
" --log-prefix=PREFIX prefix for transaction time log file\n"
916919
" (default: \"pgbench_log\")\n"
@@ -6617,6 +6620,7 @@ main(int argc, char **argv)
66176620
{"failures-detailed", no_argument, NULL, 13},
66186621
{"max-tries", required_argument, NULL, 14},
66196622
{"verbose-errors", no_argument, NULL, 15},
6623+
{"exit-on-abort", no_argument, NULL, 16},
66206624
{NULL, 0, NULL, 0}
66216625
};
66226626

@@ -6950,6 +6954,10 @@ main(int argc, char **argv)
69506954
benchmarking_option_set = true;
69516955
verbose_errors = true;
69526956
break;
6957+
case 16: /* exit-on-abort */
6958+
benchmarking_option_set = true;
6959+
exit_on_abort = true;
6960+
break;
69536961
default:
69546962
/* getopt_long already emitted a complaint */
69556963
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
@@ -7558,11 +7566,18 @@ threadRun(void *arg)
75587566

75597567
advanceConnectionState(thread, st, &aggs);
75607568

7569+
/*
7570+
* If --exit-on-abort is used, the program is going to exit
7571+
* when any client is aborted.
7572+
*/
7573+
if (exit_on_abort && st->state == CSTATE_ABORTED)
7574+
goto done;
75617575
/*
75627576
* If advanceConnectionState changed client to finished state,
75637577
* that's one fewer client that remains.
75647578
*/
7565-
if (st->state == CSTATE_FINISHED || st->state == CSTATE_ABORTED)
7579+
else if (st->state == CSTATE_FINISHED ||
7580+
st->state == CSTATE_ABORTED)
75667581
remains--;
75677582
}
75687583

@@ -7595,6 +7610,22 @@ threadRun(void *arg)
75957610
}
75967611

75977612
done:
7613+
if (exit_on_abort)
7614+
{
7615+
/*
7616+
* Abort if any client is not finished, meaning some error occurred.
7617+
*/
7618+
for (int i = 0; i < nstate; i++)
7619+
{
7620+
if (state[i].state != CSTATE_FINISHED)
7621+
{
7622+
pg_log_error("Run was aborted due to an error in thread %d",
7623+
thread->tid);
7624+
exit(2);
7625+
}
7626+
}
7627+
}
7628+
75987629
disconnect_all(state, nstate);
75997630

76007631
if (thread->logfile)

src/bin/pgbench/t/001_pgbench_with_server.pl

+26
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,32 @@ BEGIN
14751475
# Clean up
14761476
$node->safe_psql('postgres', 'DROP TABLE first_client_table, xy;');
14771477

1478+
# Test --exit-on-abort
1479+
$node->safe_psql('postgres',
1480+
'CREATE TABLE counter(i int); '.
1481+
'INSERT INTO counter VALUES (0);'
1482+
);
1483+
1484+
$node->pgbench(
1485+
'-t 10 -c 2 -j 2 --exit-on-abort',
1486+
2,
1487+
[],
1488+
[
1489+
qr{division by zero},
1490+
qr{Run was aborted due to an error in thread}
1491+
],
1492+
'test --exit-on-abort',
1493+
{
1494+
'001_exit_on_abort' => q{
1495+
update counter set i = i+1 returning i \gset
1496+
\if :i = 5
1497+
\set y 1/0
1498+
\endif
1499+
}
1500+
});
1501+
1502+
# Clean up
1503+
$node->safe_psql('postgres', 'DROP TABLE counter;');
14781504

14791505
# done
14801506
$node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts');

0 commit comments

Comments
 (0)