aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2024-11-28 09:43:22 +0900
committerMichael Paquier <michael@paquier.xyz>2024-11-28 09:43:22 +0900
commit76653134ae87c7c08e1eb58da07af9f64ec78ccb (patch)
treeaf3d6e120a49af4381d78e8fdca563b066763f6d
parentc26831e7362487b4f2c606e1223207baa1d495cb (diff)
downloadpostgresql-76653134ae87c7c08e1eb58da07af9f64ec78ccb.tar.gz
postgresql-76653134ae87c7c08e1eb58da07af9f64ec78ccb.zip
Revert "Handle better implicit transaction state of pipeline mode"
This reverts commit d77f91214fb7 on all stable branches, due to concerns regarding the compatility side effects this could create in a minor release. The change still exists on HEAD. Discussion: https://postgr.es/m/CA+TgmoZqRgeFTg4+Yf_CMRRXiHuNz1u6ZC4FvVk+rxw0RmOPnw@mail.gmail.com Backpatch-through: 13
-rw-r--r--doc/src/sgml/protocol.sgml21
-rw-r--r--src/backend/access/transam/xact.c13
-rw-r--r--src/backend/tcop/postgres.c18
-rw-r--r--src/bin/pgbench/t/001_pgbench_with_server.pl155
4 files changed, 23 insertions, 184 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 84eec5da7e3..59dbd13d6f6 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1070,17 +1070,16 @@ SELCT 1/0;<!-- this typo is intentional -->
<para>
If the client has not issued an explicit <command>BEGIN</command>,
- then an implicit transaction block is started and each Sync ordinarily
- causes an implicit <command>COMMIT</command> if the preceding step(s)
- succeeded, or an implicit <command>ROLLBACK</command> if they failed.
- This implicit transaction block will only be detected by the server
- when the first command ends without a sync. There are a few DDL
- commands (such as <command>CREATE DATABASE</command>) that cannot be
- executed inside a transaction block. If one of these is executed in a
- pipeline, it will fail unless it is the first command after a Sync.
- Furthermore, upon success it will force an immediate commit to preserve
- database consistency. Thus a Sync immediately following one of these
- commands has no effect except to respond with ReadyForQuery.
+ then each Sync ordinarily causes an implicit <command>COMMIT</command>
+ if the preceding step(s) succeeded, or an
+ implicit <command>ROLLBACK</command> if they failed. However, there
+ are a few DDL commands (such as <command>CREATE DATABASE</command>)
+ that cannot be executed inside a transaction block. If one of
+ these is executed in a pipeline, it will fail unless it is the first
+ command in the pipeline. Furthermore, upon success it will force an
+ immediate commit to preserve database consistency. Thus a Sync
+ immediately following one of these commands has no effect except to
+ respond with ReadyForQuery.
</para>
<para>
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index cb8bedc46df..4a2ea4adbaf 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -3501,6 +3501,16 @@ PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
stmtType)));
/*
+ * inside a pipeline that has started an implicit transaction?
+ */
+ if (MyXactFlags & XACT_FLAGS_PIPELINING)
+ ereport(ERROR,
+ (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+ /* translator: %s represents an SQL statement name */
+ errmsg("%s cannot be executed within a pipeline",
+ stmtType)));
+
+ /*
* inside a function call?
*/
if (!isTopLevel)
@@ -3611,6 +3621,9 @@ IsInTransactionBlock(bool isTopLevel)
if (IsSubTransaction())
return true;
+ if (MyXactFlags & XACT_FLAGS_PIPELINING)
+ return true;
+
if (!isTopLevel)
return true;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 26aaaf19e19..3f427f1b47f 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2780,17 +2780,6 @@ start_xact_command(void)
xact_started = true;
}
- else if (MyXactFlags & XACT_FLAGS_PIPELINING)
- {
- /*
- * When the first Execute message is completed, following commands
- * will be done in an implicit transaction block created via
- * pipelining. The transaction state needs to be updated to an
- * implicit block if we're not already in a transaction block (like
- * one started by an explicit BEGIN).
- */
- BeginImplicitTransactionBlock();
- }
/*
* Start statement timeout if necessary. Note that this'll intentionally
@@ -4929,13 +4918,6 @@ PostgresMain(const char *dbname, const char *username)
case 'S': /* sync */
pq_getmsgend(&input_message);
-
- /*
- * If pipelining was used, we may be in an implicit
- * transaction block. Close it before calling
- * finish_xact_command.
- */
- EndImplicitTransactionBlock();
finish_xact_command();
valgrind_report_error_query("SYNC message");
send_ready_for_query = true;
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 44a98b4d5df..afc9ecfaf77 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -897,161 +897,6 @@ $node->pgbench(
}
});
-# Try SET LOCAL as first pipeline command. This succeeds and the first
-# command is not executed inside an implicit transaction block, causing
-# a WARNING.
-$node->pgbench(
- '-t 1 -n -M extended',
- 0,
- [],
- [qr{WARNING: SET LOCAL can only be used in transaction blocks}],
- 'SET LOCAL outside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_set_local_1' => q{
-\startpipeline
-SET LOCAL statement_timeout='1h';
-\endpipeline
-}
- });
-
-# Try SET LOCAL as second pipeline command. This succeeds and the second
-# command does not cause a WARNING to be generated.
-$node->pgbench(
- '-t 1 -n -M extended',
- 0,
- [],
- [qr{^$}],
- 'SET LOCAL inside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_set_local_2' => q{
-\startpipeline
-SELECT 1;
-SET LOCAL statement_timeout='1h';
-\endpipeline
-}
- });
-
-# Try REINDEX CONCURRENTLY as first pipeline command. This succeeds
-# as the first command is outside the implicit transaction block of
-# a pipeline.
-$node->pgbench(
- '-t 1 -n -M extended',
- 0,
- [],
- [],
- 'REINDEX CONCURRENTLY outside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_reindex_1' => q{
-\startpipeline
-REINDEX TABLE CONCURRENTLY pgbench_accounts;
-SELECT 1;
-\endpipeline
-}
- });
-
-# Try REINDEX CONCURRENTLY as second pipeline command. This fails
-# as the second command is inside an implicit transaction block.
-$node->pgbench(
- '-t 1 -n -M extended',
- 2,
- [],
- [],
- 'error: REINDEX CONCURRENTLY inside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_reindex_2' => q{
-\startpipeline
-SELECT 1;
-REINDEX TABLE CONCURRENTLY pgbench_accounts;
-\endpipeline
-}
- });
-
-# Try VACUUM as first pipeline command. Like REINDEX CONCURRENTLY, this
-# succeeds as this is outside the implicit transaction block of a pipeline.
-$node->pgbench(
- '-t 1 -n -M extended',
- 0,
- [],
- [],
- 'VACUUM outside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_vacuum_1' => q{
-\startpipeline
-VACUUM pgbench_accounts;
-\endpipeline
-}
- });
-
-# Try VACUUM as second pipeline command. This fails, as the second command
-# of a pipeline is inside an implicit transaction block.
-$node->pgbench(
- '-t 1 -n -M extended',
- 2,
- [],
- [],
- 'error: VACUUM inside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_vacuum_2' => q{
-\startpipeline
-SELECT 1;
-VACUUM pgbench_accounts;
-\endpipeline
-}
- });
-
-# Try subtransactions in a pipeline. These are forbidden in implicit
-# transaction blocks.
-$node->pgbench(
- '-t 1 -n -M extended',
- 2,
- [],
- [],
- 'error: subtransactions not allowed in pipeline',
- {
- '001_pgbench_pipeline_subtrans' => q{
-\startpipeline
-SAVEPOINT a;
-SELECT 1;
-ROLLBACK TO SAVEPOINT a;
-SELECT 2;
-\endpipeline
-}
- });
-
-# Try LOCK TABLE as first pipeline command. This fails as LOCK is outside
-# an implicit transaction block.
-$node->pgbench(
- '-t 1 -n -M extended',
- 2,
- [],
- [],
- 'error: LOCK TABLE outside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_lock_1' => q{
-\startpipeline
-LOCK pgbench_accounts;
-SELECT 1;
-\endpipeline
-}
- });
-
-# Try LOCK TABLE as second pipeline command. This succeeds as LOCK is inside
-# an implicit transaction block.
-$node->pgbench(
- '-t 1 -n -M extended',
- 0,
- [],
- [],
- 'LOCK TABLE inside implicit transaction block of pipeline',
- {
- '001_pgbench_pipeline_lock_2' => q{
-\startpipeline
-SELECT 1;
-LOCK pgbench_accounts;
-\endpipeline
-}
- });
-
# Working \startpipeline in prepared query mode with serializable
$node->pgbench(
'-c4 -t 10 -n -M prepared',