Re: Assertion failure in pgbench

From: Stepan Neretin <slpmcf(at)gmail(dot)com>
To: Tatsuo Ishii <ishii(at)postgresql(dot)org>
Cc: masao(dot)fujii(at)gmail(dot)com, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Assertion failure in pgbench
Date: 2025-07-31 02:14:29
Message-ID: CA+Yyo5SNK7L7JC_4veAmBMAM+o8WFfTnbhyR_W3Q3Hmt+k+49w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Jul 31, 2025 at 9:03 AM Tatsuo Ishii <ishii(at)postgresql(dot)org> wrote:

> >> Hi,
> >>
> >> I encountered the following assertion failure in pgbench on the current
> master:
> >>
> >> Assertion failed: (res == ((void*)0)), function discardUntilSync,
> >> file pgbench.c, line 3515.
> >> Abort trap: 6
> >>
> >>
> >> This can be reliably reproduced with the following steps:
> >>
> >> ------------------------
> >> $ psql -c "ALTER SYSTEM SET default_transaction_isolation TO
> 'serializable'"
> >>
> >> $ psql -c "SELECT pg_reload_conf()"
> >>
> >> $ pgbench -i
> >>
> >> $ cat test.sql
> >> \set aid random(1, 100000 * :scale)
> >> \set bid random(1, 1 * :scale)
> >> \set tid random(1, 10 * :scale)
> >> \set delta random(-5000, 5000)
> >> \startpipeline
> >> BEGIN;
> >> UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid =
> :aid;
> >> SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
> >> UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid =
> :tid;
> >> UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid =
> :bid;
> >> INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES
> >> (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
> >> END;
> >> \endpipeline
> >>
> >> $ pgbench -f test.sql -c 10 -j 10 -T 60 -M extended
> >> ------------------------
> >>
> >> Even without a custom script, shutting down the server with
> >> immediate mode while running "pgbench -c 10 -j 10 -T 60" could
> >> trigger the same assertion, though not always reliably.
> >>
> >>
> >> /* receive PGRES_PIPELINE_SYNC and null following it */
> >> for (;;)
> >> {
> >> PGresult *res = PQgetResult(st->con);
> >>
> >> if (PQresultStatus(res) == PGRES_PIPELINE_SYNC)
> >> {
> >> PQclear(res);
> >> res = PQgetResult(st->con);
> >> Assert(res == NULL);
> >> break;
> >> }
> >> PQclear(res);
> >> }
> >>
> >> The failure occurs in this code. This code assumes that
> PGRES_PIPELINE_SYNC
> >> is always followed by a NULL. However, it seems that another
> >> PGRES_PIPELINE_SYNC can appear consecutively, which violates that
> assumption
> >> and causes the assertion to fail. Thought?
> >
> > Yes. When an error occurs and an error response message returned from
> > backend, pgbench will send one more sync message, then sends ROLLBACK
> > if necessary. I think the code above should be changed to call
> > PQgetResult repeatably until it returns NULL.
>
> Correction. That would not be a proper fix. Just removing inner
> PQgetResult and the Assert is enough?
>
> Best regards,
> --
> Tatsuo Ishii
> SRA OSS K.K.
> English: http://www.sraoss.co.jp/index_en/
> Japanese:http://www.sraoss.co.jp
>
>

Hi, Tatsuo.
Do you understand why there is an assertion error in the immediate shutdown
case?
Best Regards,
Stepan Neretin

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Ajin Cherian 2025-07-31 02:53:22 Re: 024_add_drop_pub.pl might fail due to deadlock
Previous Message Tatsuo Ishii 2025-07-31 02:03:06 Re: Assertion failure in pgbench