Thanks to visit codestin.com
Credit goes to github.com

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

+9-3
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

+25-3
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

+36
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)