pgbench: When using pipelining only do PQconsumeInput() when necessary.
authorAndres Freund <andres@anarazel.de>
Thu, 5 Aug 2021 02:19:44 +0000 (19:19 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 5 Aug 2021 02:19:44 +0000 (19:19 -0700)
Up to now we did a PQconsumeInput() for each pipelined query, asking the OS
for more input - which it often won't have, as all results might already have
been sent. That turns out to have a noticeable performance impact.

Alvaro Herrera reviewed the idea to add the PQisBusy() check, but not this
concrete patch.

Author: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/20210720180039.23rivhdft3l4mayn@alap3.anarazel.de
Backpatch: 14, where libpq/pgbench pipelining was introduced.

src/bin/pgbench/pgbench.c

index 55d14604c020723f1b67f9b4ec7e759b9324546d..b0e20c46ae39e474595c2243867123e0fe08cb1b 100644 (file)
@@ -3461,7 +3461,14 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
                 */
            case CSTATE_WAIT_RESULT:
                pg_log_debug("client %d receiving", st->id);
-               if (!PQconsumeInput(st->con))
+
+               /*
+                * Only check for new network data if we processed all data
+                * fetched prior. Otherwise we end up doing a syscall for each
+                * individual pipelined query, which has a measurable
+                * performance impact.
+                */
+               if (PQisBusy(st->con) && !PQconsumeInput(st->con))
                {
                    /* there's something wrong */
                    commandFailed(st, "SQL", "perhaps the backend died while processing");