Skip to content

Commit 94edfe2

Browse files
committed
pgbench: Add \syncpipeline
This change adds a new meta-command called \syncpipeline to pgbench, able to send a sync message without flushing using the new libpq function PQsendPipelineSync(). This meta-command is available within a block made of \startpipeline and \endpipeline. Author: Anthonin Bonnefoy Discussion: https://postgr.es/m/CAO6_XqpcNhW6LZHLF-2NpPzdTbyMm4-RVkr3+AP5cOKSm9hrWA@mail.gmail.com
1 parent faa2b95 commit 94edfe2

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

doc/src/sgml/ref/pgbench.sgml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,13 +1386,19 @@ SELECT 4 AS four \; SELECT 5 AS five \aset
13861386

13871387
<varlistentry id="pgbench-metacommand-pipeline">
13881388
<term><literal>\startpipeline</literal></term>
1389+
<term><literal>\syncpipeline</literal></term>
13891390
<term><literal>\endpipeline</literal></term>
13901391

13911392
<listitem>
13921393
<para>
1393-
These commands delimit the start and end of a pipeline of SQL
1394-
statements. In pipeline mode, statements are sent to the server
1395-
without waiting for the results of previous statements. See
1394+
This group of commands implements pipelining of SQL statements.
1395+
A pipeline must begin with a <command>\startpipeline</command>
1396+
and end with an <command>\endpipeline</command>. In between there
1397+
may be any number of <command>\syncpipeline</command> commands,
1398+
which sends a <link linkend="protocol-flow-ext-query">sync message</link>
1399+
without ending the ongoing pipeline and flushing the send buffer.
1400+
In pipeline mode, statements are sent to the server without waiting
1401+
for the results of previous statements. See
13961402
<xref linkend="libpq-pipeline-mode"/> for more details.
13971403
Pipeline mode requires the use of extended query protocol.
13981404
</para>

src/bin/pgbench/pgbench.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ typedef struct
608608

609609
int use_file; /* index in sql_script for this client */
610610
int command; /* command number in script */
611+
int num_syncs; /* number of ongoing sync commands */
611612

612613
/* client variables */
613614
Variables variables;
@@ -697,6 +698,7 @@ typedef enum MetaCommand
697698
META_ELSE, /* \else */
698699
META_ENDIF, /* \endif */
699700
META_STARTPIPELINE, /* \startpipeline */
701+
META_SYNCPIPELINE, /* \syncpipeline */
700702
META_ENDPIPELINE, /* \endpipeline */
701703
} MetaCommand;
702704

@@ -2902,6 +2904,8 @@ getMetaCommand(const char *cmd)
29022904
mc = META_ASET;
29032905
else if (pg_strcasecmp(cmd, "startpipeline") == 0)
29042906
mc = META_STARTPIPELINE;
2907+
else if (pg_strcasecmp(cmd, "syncpipeline") == 0)
2908+
mc = META_SYNCPIPELINE;
29052909
else if (pg_strcasecmp(cmd, "endpipeline") == 0)
29062910
mc = META_ENDPIPELINE;
29072911
else
@@ -3317,8 +3321,10 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
33173321
break;
33183322

33193323
case PGRES_PIPELINE_SYNC:
3320-
pg_log_debug("client %d pipeline ending", st->id);
3321-
if (PQexitPipelineMode(st->con) != 1)
3324+
pg_log_debug("client %d pipeline ending, ongoing syncs: %d",
3325+
st->id, st->num_syncs);
3326+
st->num_syncs--;
3327+
if (st->num_syncs == 0 && PQexitPipelineMode(st->con) != 1)
33223328
pg_log_error("client %d failed to exit pipeline mode: %s", st->id,
33233329
PQerrorMessage(st->con));
33243330
break;
@@ -4449,6 +4455,20 @@ executeMetaCommand(CState *st, pg_time_usec_t *now)
44494455
return CSTATE_ABORTED;
44504456
}
44514457
}
4458+
else if (command->meta == META_SYNCPIPELINE)
4459+
{
4460+
if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
4461+
{
4462+
commandFailed(st, "syncpipeline", "not in pipeline mode");
4463+
return CSTATE_ABORTED;
4464+
}
4465+
if (PQsendPipelineSync(st->con) == 0)
4466+
{
4467+
commandFailed(st, "syncpipeline", "failed to send a pipeline sync");
4468+
return CSTATE_ABORTED;
4469+
}
4470+
st->num_syncs++;
4471+
}
44524472
else if (command->meta == META_ENDPIPELINE)
44534473
{
44544474
if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
@@ -4461,6 +4481,7 @@ executeMetaCommand(CState *st, pg_time_usec_t *now)
44614481
commandFailed(st, "endpipeline", "failed to send a pipeline sync");
44624482
return CSTATE_ABORTED;
44634483
}
4484+
st->num_syncs++;
44644485
/* Now wait for the PGRES_PIPELINE_SYNC and exit pipeline mode there */
44654486
/* collect pending results before getting out of pipeline mode */
44664487
return CSTATE_WAIT_RESULT;
@@ -5794,7 +5815,8 @@ process_backslash_command(PsqlScanState sstate, const char *source)
57945815
}
57955816
else if (my_command->meta == META_ELSE || my_command->meta == META_ENDIF ||
57965817
my_command->meta == META_STARTPIPELINE ||
5797-
my_command->meta == META_ENDPIPELINE)
5818+
my_command->meta == META_ENDPIPELINE ||
5819+
my_command->meta == META_SYNCPIPELINE)
57985820
{
57995821
if (my_command->argc != 1)
58005822
syntax_error(source, lineno, my_command->first_line, my_command->argv[0],

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,27 @@ sub check_data_state
814814
}
815815
});
816816

817+
# Working \startpipeline with \syncpipeline
818+
$node->pgbench(
819+
'-t 1 -n -M extended',
820+
0,
821+
[ qr{type: .*/001_pgbench_pipeline_sync}, qr{actually processed: 1/1} ],
822+
[],
823+
'working \startpipeline with \syncpipeline',
824+
{
825+
'001_pgbench_pipeline_sync' => q{
826+
-- test startpipeline
827+
\startpipeline
828+
select 1;
829+
\syncpipeline
830+
\syncpipeline
831+
select 2;
832+
\syncpipeline
833+
select 3;
834+
\endpipeline
835+
}
836+
});
837+
817838
# Working \startpipeline in prepared query mode
818839
$node->pgbench(
819840
'-t 1 -n -M prepared',
@@ -904,6 +925,21 @@ sub check_data_state
904925
}
905926
});
906927

928+
# Try \startpipeline with \syncpipeline without \endpipeline
929+
$node->pgbench(
930+
'-t 2 -n -M extended',
931+
2,
932+
[],
933+
[qr{end of script reached with pipeline open}],
934+
'error: call \startpipeline and \syncpipeline without \endpipeline',
935+
{
936+
'001_pgbench_pipeline_7' => q{
937+
-- startpipeline with \syncpipeline only
938+
\startpipeline
939+
\syncpipeline
940+
}
941+
});
942+
907943
# Working \startpipeline in prepared query mode with serializable
908944
$node->pgbench(
909945
'-c4 -t 10 -n -M prepared',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy