Re: Pgbench: remove synchronous prepare - Mailing list pgsql-hackers
| From | Dmitrii Bondar |
|---|---|
| Subject | Re: Pgbench: remove synchronous prepare |
| Date | |
| Msg-id | 6e161344-d26a-4e3d-aa12-83a05a3ca8dc@postgrespro.ru Whole thread |
| In response to | Re: Pgbench: remove synchronous prepare (Robert Haas <robertmhaas@gmail.com>) |
| Responses |
Re: Pgbench: remove synchronous prepare
|
| List | pgsql-hackers |
Hi,On Mon, Mar 16, 2026 at 3:46 AM Dmitrii Bondar <d.bondar@postgrespro.ru> wrote:Rebase.Hi, I think that this patch is changing more behavior than is explained in the commit message. The existing code calls PQsendQueryPrepared, which only tries to execute an already-prepared query. The replacement code tries to prepare the query. It is not clear to me what's going on here. I would have expected that we would only ever reach that point in the code with the query already prepared; otherwise, the existing code would presumably fail. But if that is the case then how is the new code managing to do anything different than the old code? Another way to see that the patch must be changing more behavior than advertised is the change to 001_pgbench_with_server.pl. That change comes with no comment changes and no explanation of any kind. If this patch were just about doing something asynchronously instead of synchronously, I think that would be fine, but I don't think that's all that is happening here. The original post explains the problem behavior (pgbench freezing under certain circumstances) but I don't understand what causes that behavior. I think I would understand better if the original complaint were about something other than session pooling mode: then, I might expect that we might unexpectedly discover that our session does not have something prepared which we expected to find prepared, and maybe this revised logic in sendCommand() would somehow fix that. But in session pooling mode, shouldn't everything be the same as if connection pooling is not in use at all? What's actually different?
The patch does not change the existing behavior when a query has already been prepared. Both the old and new code paths use PQsendQueryPrepared, which sends a bind-execute-sync packet sequence without waiting for a response.
The main difference appears when the query has not yet been prepared. In the old code, PQprepare is called, which sends a parse message and then waits for the result via PQexecFinish. Since PQexecFinish blocks until a response arrives, it can block the entire thread if the server has not responded yet.
I replaced the call to PQprepare with a call to the new PQsendPBES function. Like PQsendQueryPrepared, it works asynchronously, but it sends a parse-bind-execute-sync sequence instead. This change avoids thread blocking because it eliminates the need to call PQexecFinish.
I chose to send a parse-bind-execute-sync sequence to match the behavior of extended query mode, in which pgbench sends the same sequence, but with an unnamed statement.
The expected output for 001_pgbench_with_server.pl was changed for the following reason. In the old pgbench code, prepareCommand is called and receives ERROR: syntax error. Since prepareCommand does not return a status, pgbench continues execution and then attempts to run the command with PQsendQueryPrepared. This leads to the error prepared statement .* does not exist, which is caused by the bind packet.
In the new code, PQsendPBES sends a parse-bind-execute-sync packet sequence. If the parse step fails with ERROR: syntax error, all subsequent messages are ignored until the sync packet is processed. That is why the additional prepared statement .* does not exist error from the bind packet no longer appears.
Session mode is indeed the most transparent way to use a pooler. However, pgbench can become stuck when the number of clients exceeds the pool size. If the pooler cannot reserve a backend for a client, it places the client in a waiting queue. In that case, pgbench may wait indefinitely because it is blocked in PQprepare, and the pgbench thread cannot process responses for other clients.
Regards,
Dmitrii Bondar
pgsql-hackers by date: