Re: Suggestion to add --continue-client-on-abort option to pgbench

Chao Li <li.evan.chao@gmail.com>

From: Chao Li <li.evan.chao@gmail.com>
To: Fujii Masao <masao.fujii@gmail.com>
Cc: Rintaro Ikeda <ikedarintarof@oss.nttdata.com>, Yugo Nagata <nagata@sraoss.co.jp>, Jakub Wartak <jakub.wartak@enterprisedb.com>, "Hayato Kuroda (Fujitsu)" <kuroda.hayato@fujitsu.com>, "slpmcf@gmail.com" <slpmcf@gmail.com>, "boekewurm+postgres@gmail.com" <boekewurm+postgres@gmail.com>, "pgsql-hackers@postgresql.org" <pgsql-hackers@postgresql.org>, Srinath Reddy Sadipiralla <srinath2133@gmail.com>, Dilip Kumar <dilipbalaut@gmail.com>
Date: 2025-11-11T02:49:16Z
Lists: pgsql-hackers

> On Nov 10, 2025, at 12:45, Fujii Masao <masao.fujii@gmail.com> wrote:
> 
> On Mon, Nov 10, 2025 at 11:07 AM Chao Li <li.evan.chao@gmail.com> wrote:
>> I just did a test. In the test, I inserted a tuple with the same primary key so that the inserts fails by the unique key constraint which breaks the pipeline, and some random select statements followed. And I added some debug messages in discardAvailableResults(), which showed me that the function will discard rest of statements’ results until \endpipeline. As there are anyway limited number of statements before \endpipeline, my concern is actually not valid. So, now I am good with this patch.
> 
> Thanks a lot for testing!
> 

Hi Fujii-san,

I just did more tests on both pipeline mode and non-pipeline mode, I think the main purpose of discardAvailableResults() is to drain results for pipeline mode. In non-pipeline mode, a NULL res indicates no more result to read; while in pipeline mode, when a pipeline is aborted, either a valid result or NULL could still be returned, thus we need to wait until pipeline state switch to PQ_PIPELINE_OK. From this perspective, the current inline comment is correct, but I feel it’s not clear enough.

So I am proposing the function comment and inline comment like the following:
```
/*
 * Read and discard all available results from the connection.
 *
 * Non-pipeline mode:
 * ------------------
 * PQgetResult() returns each PGresult in order for the last command sent.
 * When it returns NULL, that definitively means there are no more results
 * for that command. We stop on NULL (or on CONNECTION_BAD).
 *
 * Pipeline mode:
 * --------------
 * If an earlier command in the pipeline errors, libpq enters the
 * PQ_PIPELINE_ABORTED state. In this state, PQgetResult() may return
 * either a valid PGresult or NULL, and a NULL return does NOT mean
 * that the connection is drained. More results for later commands (or
 * protocol housekeeping such as the pipeline sync result) can still
 * arrive afterward. Therefore we must continue calling PQgetResult()
 * while PQpipelineStatus(conn) == PQ_PIPELINE_ABORTED, even if we see
 * intermittent NULLs.
 */
static void
discardAvailableResults(CState *st)
{
	PGresult   *res = NULL;

	for (;;)
	{
		res = PQgetResult(st->con);

		/*
		 * Stop when there are no more results *and* the pipeline is not
		 * in the aborted state, or if the connection has failed.
		 */
		if ((res == NULL && PQpipelineStatus(st->con) != PQ_PIPELINE_ABORTED) ||
			PQstatus(st->con) == CONNECTION_BAD)
			break;

		PQclear(res);
	}
	PQclear(res);
}
```

What do you think?

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/







Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. pgbench: Fix assertion failure with multiple \syncpipeline in pipeline mode.

  2. pgbench: Add --continue-on-error option.

  3. Fix "inconsistent DLL linkage" warning on Windows MSVC

  4. pgbench: Fix error reporting in readCommandResponse().

  5. pgbench: Fix assertion failure with retriable errors in pipeline mode.

  6. Allow pgbench to retry in some cases.