mysql/doc/qbk/20_pipeline.qbk
2025-02-13 21:40:01 +01:00

182 lines
6.3 KiB
Plaintext

[/
Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:pipeline (Experimental) Pipelines]
[nochunk]
Functions like [refmemunq any_connection execute], [refmemunq any_connection prepare_statement]
and their async counterparts are half-duplex:
they write a single request to the server and wait for its response.
In contrast, pipelines can increase efficiency by coalescing several requests into a single message, saving round-trips to the server.
[warning
The MySQL client/server protocol doesn't have explicit support for pipelines. [*From the server's point of view,
a pipeline is just a sequence of unrelated requests]. The server will try to execute all stages
in each pipeline, regardless of the result of previous stages. Pipelines are considered
an [*advanced feature]. Please read [link mysql.pipeline.pitfalls the pitfalls section] for more info.
]
[note
This feature is experimental. Its API may change in subsequent releases.
]
[heading Use cases]
You should use pipelines for lightweight operations, dominated by round-trip time. Typical examples include:
* Running connection setup code, involving operations like [refmemunq any_connection reset_connection],
[refmemunq any_connection set_character_set] or preparing statements. [reflink connection_pool] uses
pipelines to clean up connections for re-use.
* Preparing several statements, in batch.
* Executing and closing a statement in a single round-trip.
You should [*avoid] pipelines for the following cases:
* When you can achieve the same functionality using semicolon-separated queries
(thus using [link mysql.multi_resultset.multi_queries multi-queries] and [link mysql.text_queries client-side SQL formatting]).
Multi-queries will stop after the first error, which is usually what you want. See [link mysql.pipeline.pitfalls this section] for more info.
* When running heavyweight queries, where the gains in round-trip time are not significant.
* When there are dependencies between stages in the pipeline. Lack of protocol support makes this use case impossible.
If you're not sure, don't use this feature.
[heading Pipeline requests and responses]
To run a pipeline, create a [reflink pipeline_request] object describing what should the pipeline do:
[pipeline_request]
We're using [refmemunq pipeline_request add_execute] and [refmemunq pipeline_request add_prepare_statement]
to add stages to our pipeline. You can find all available stage types in the [link mysql.pipeline.reference reference section].
To actually run the pipeline, create a response object and call
[refmem any_connection run_pipeline] or [refmemunq any_connection async_run_pipeline]:
[pipeline_run]
Finally, you can access the statements using [refmem stage_response as_statement]:
[pipeline_results]
If your pipeline contains an execution stage, it will generate a `results` object
that can be accessed using [refmem stage_response as_results].
[heading:error Error handling]
If any of the pipeline stages result in an error, the entire [refmemunq any_connection run_pipeline] operation
is considered failed. This means that [*if `run_pipipeline` completed successfully, all stages succeeded]. Recall that
[*all stages are always run, regardless of the outcome of previous stages].
If `run_pipipeline` fails, you can check which stages succeeded and failed by inspecting responses.
[refmem stage_response error] and [refmem stage_response diag] will return error information about failed steps. For instance:
[pipeline_errors]
[heading:pitfalls Potential pitfalls]
All requests in the pipeline are always run, regardless of the outcome of previous requests. As a result, some pipelines can behave non-intuitively:
[pipeline_pitfalls_bad]
Pipelines aren't the best fit here. Instead, you can express the same logic using semicolon-separated queries:
[pipeline_pitfalls_good]
Pipeline stages are run sequentially by the server. If any of the stages involves a heavyweight query,
the server won't process subsequent stages until the query completes.
[heading:reference Pipeline stage reference]
In the table below, the following variables are assumed:
* `req` is a [reflink pipeline_request].
* `stmt` is a valid [reflink statement].
* `result` is a [reflink results] object.
* `conn` is an [reflink any_connection] object.
[table:reference
[
[Stage type]
[Example]
[When run, equivalent to...]
[Response type]
]
[
[
[*Execute]: behaves like [refmem any_connection execute][br][br]
[refmem pipeline_request add_execute][br]
[refmem pipeline_request add_execute_range]
]
[[pipeline_reference_execute]]
[[pipeline_reference_execute_equivalent]]
[
[reflink results] or an error
]
]
[
[
[*Prepare statement]: behaves like [refmem any_connection prepare_statement][br][br]
[refmem pipeline_request add_prepare_statement]
]
[[pipeline_reference_prepare_statement]]
[[pipeline_reference_prepare_statement_equivalent]]
[
[reflink statement] or an error
]
]
[
[
[*Close statement]: behaves like [refmem any_connection close_statement][br][br]
[refmem pipeline_request add_close_statement]
]
[[pipeline_reference_close_statement]]
[[pipeline_reference_close_statement_equivalent]]
[
Possibly empty error
]
]
[
[
[*Reset connection]: behaves like [refmem any_connection reset_connection][br][br]
[refmem pipeline_request add_reset_connection]
]
[[pipeline_reference_reset_connection]]
[[pipeline_reference_reset_connection_equivalent]]
[
Possibly empty error
]
]
[
[
[*Set character set]: behaves like [refmem any_connection set_character_set][br][br]
[refmem pipeline_request add_set_character_set]
]
[[pipeline_reference_set_character_set]]
[[pipeline_reference_set_character_set_equivalent]]
[
Possibly empty error
]
]
]
[endsect]