From 874f1252a296351c6f64f751bc7aeb940b8e039f Mon Sep 17 00:00:00 2001 From: Koval Dmitry Date: Tue, 30 Nov 2021 22:34:48 +0300 Subject: [PATCH 1/2] [PGPRO-5893] Fixed processing of error for DDL-queries in PgPlSQL block Tags: atx, multimaster --- src/commit.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/commit.c b/src/commit.c index 0018c0b467..877d64215a 100644 --- a/src/commit.c +++ b/src/commit.c @@ -135,14 +135,39 @@ mtm_commit_cleanup(int status, Datum arg) /* there was no precommit, we can abort */ PG_TRY(); { - AbortOutOfAnyTransaction(); - StartTransactionCommand(); +#ifdef PGPRO_EE + int atxLevel = DatumGetInt32(arg); + + /* + * If we are inside ATX transaction, we can not call + * AbortOutOfAnyTransaction() because this call will abort + * ALL transactions and we will have problems if the + * calling code is not designed for this case. + */ + if (atxLevel) + { + /* Abort (current ATX transaction only): */ + AbortCurrentTransaction(); + /* Restart ATX transaction if it was resumed: */ + if (atxLevel > getNestLevelATX()) + SuspendTransaction(); + } + else +#endif + { + AbortOutOfAnyTransaction(); + StartTransactionCommand(); + } FinishPreparedTransaction(mtm_commit_state.gid, false, false); mtm_commit_state.gtx->state.status = GTXAborted; mtm_log(MtmTxFinish, "%s aborted as own orphaned not precomitted", mtm_commit_state.gid); CommitTransactionCommand(); - +#ifdef PGPRO_EE + /* Restart ATX transaction if it was resumed: */ + if (atxLevel > getNestLevelATX()) + SuspendTransaction(); +#endif } /* * this should be extremely unlikely, but if we fail, don't @@ -218,7 +243,7 @@ MtmBeginTransaction() * register gtx hook first (it will be called last) */ GlobalTxEnsureBeforeShmemExitHook(); - before_shmem_exit(mtm_commit_cleanup, Int32GetDatum(1)); + before_shmem_exit(mtm_commit_cleanup, Int32GetDatum(0)); mtm_commit_state.mctx = AllocSetContextCreate(TopMemoryContext, "MtmCommitContext", ALLOCSET_DEFAULT_SIZES); @@ -373,6 +398,9 @@ MtmTwoPhaseCommit(void) MtmGeneration xact_gen; char dmq_stream_name[DMQ_STREAM_NAME_MAXLEN]; GTxState gtx_state; +#ifdef PGPRO_EE + int atxLevel = getNestLevelATX(); +#endif if (MtmNo3PC) { @@ -714,7 +742,7 @@ MtmTwoPhaseCommit(void) } PG_CATCH(); { - mtm_commit_cleanup(0, Int32GetDatum(0)); + mtm_commit_cleanup(0, Int32GetDatum(atxLevel)); PG_RE_THROW(); } From 85daead75a784730abcc37ebb6c4fc9da627faf2 Mon Sep 17 00:00:00 2001 From: Mikhail Rutman Date: Tue, 20 Sep 2022 14:11:59 +0700 Subject: [PATCH 2/2] [PGPRO-5893] update regression_ee.diff --- expected/regression_ee.diff | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/expected/regression_ee.diff b/expected/regression_ee.diff index a54758b41f..566f0c1b7f 100644 --- a/expected/regression_ee.diff +++ b/expected/regression_ee.diff @@ -638,6 +638,38 @@ diff ../../../src/test/regress/expected/atx.out ../tmp_check/regress_outdir/resu \c regression_atx_test_database create table atx_test as select 1 as id; begin; +diff ../../../src/test/regress/expected/atx3.out ../tmp_check/regress_outdir/results/atx3.out +--- ../../../src/test/regress/expected/atx3.out CENSORED ++++ ../tmp_check/regress_outdir/results/atx3.out CENSORED +@@ -69,12 +69,14 @@ + return 1; + end$$; + select * from test_func5893(10); ++NOTICE: other exception 42703, [MTM] failed to prepare transaction at peer node + test_func5893 + --------------- + 1 + (1 row) + + drop table mmm5893; ++ERROR: table "mmm5893" does not exist + drop function test_func5893(i int); + -- test without 'exception' block + create or replace function test_func5893(i int) returns int language plpgsql as $$ +@@ -88,10 +90,8 @@ + return 1; + end$$; + select * from test_func5893(10); +- test_func5893 +---------------- +- 1 +-(1 row) +- ++ERROR: [MTM] failed to prepare transaction at peer node ++CONTEXT: PL/pgSQL function test_func5893(integer) line 5 during autonomous statement block exit + drop table mmm5893; ++ERROR: table "mmm5893" does not exist + drop function test_func5893(i int); diff ../../../src/test/regress/expected/atx5.out ../tmp_check/regress_outdir/results/atx5.out --- ../../../src/test/regress/expected/atx5.out CENSORED +++ ../tmp_check/regress_outdir/results/atx5.out CENSORED