@@ -210,6 +210,8 @@ bool MtmUseRaftable;
210
210
bool MtmUseDtm ;
211
211
bool MtmVolksWagenMode ;
212
212
213
+ TransactionId MtmUtilityProcessedInXid ;
214
+
213
215
static char * MtmConnStrs ;
214
216
static int MtmQueueSize ;
215
217
static int MtmWorkers ;
@@ -688,7 +690,12 @@ MtmXactCallback(XactEvent event, void *arg)
688
690
static bool
689
691
MtmIsUserTransaction ()
690
692
{
691
- return !IsAutoVacuumLauncherProcess () && IsNormalProcessingMode () && MtmDoReplication && !am_walsender && !IsBackgroundWorker && !IsAutoVacuumWorkerProcess ();
693
+ return !IsAutoVacuumLauncherProcess () &&
694
+ IsNormalProcessingMode () &&
695
+ MtmDoReplication &&
696
+ !am_walsender &&
697
+ !IsBackgroundWorker &&
698
+ !IsAutoVacuumWorkerProcess ();
692
699
}
693
700
694
701
void
@@ -700,7 +707,6 @@ MtmResetTransaction()
700
707
x -> gtid .xid = InvalidTransactionId ;
701
708
x -> isDistributed = false;
702
709
x -> isPrepared = false;
703
- x -> isPrepared = false;
704
710
x -> status = TRANSACTION_STATUS_UNKNOWN ;
705
711
}
706
712
@@ -3335,20 +3341,20 @@ MtmGenerateGid(char* gid)
3335
3341
3336
3342
static bool MtmTwoPhaseCommit (MtmCurrentTrans * x )
3337
3343
{
3338
- if (MyXactAccessedTempRel )
3339
- {
3340
- /*
3341
- * XXX: this tx anyway goes to subscribers later, but without
3342
- * surrounding begin/commit. Now it will be filtered out on receiver side.
3343
- * Probably there is more clever way to do that.
3344
- */
3345
- x -> isDistributed = false;
3346
- if (!MtmVolksWagenMode )
3347
- elog (NOTICE , "MTM: Transaction was not replicated as it accesed temporary relation" );
3348
- return false;
3349
- }
3350
-
3351
- if (!x -> isReplicated && ( x -> isDistributed && x -> containsDML )) {
3344
+ // if (MyXactAccessedTempRel)
3345
+ // {
3346
+ // /*
3347
+ // * XXX: this tx anyway goes to subscribers later, but without
3348
+ // * surrounding begin/commit. Now it will be filtered out on receiver side.
3349
+ // * Probably there is more clever way to do that.
3350
+ // */
3351
+ // x->isDistributed = false;
3352
+ // if (!MtmVolksWagenMode)
3353
+ // elog(NOTICE, "MTM: Transaction was not replicated as it accesed temporary relation");
3354
+ // return false;
3355
+ // }
3356
+
3357
+ if (!x -> isReplicated && x -> isDistributed && x -> containsDML ) {
3352
3358
MtmGenerateGid (x -> gid );
3353
3359
if (!x -> isTransactionBlock ) {
3354
3360
BeginTransactionBlock ();
@@ -3358,7 +3364,8 @@ static bool MtmTwoPhaseCommit(MtmCurrentTrans* x)
3358
3364
}
3359
3365
if (!PrepareTransactionBlock (x -> gid ))
3360
3366
{
3361
- elog (WARNING , "Failed to prepare transaction %s" , x -> gid );
3367
+ if (!MtmVolksWagenMode )
3368
+ elog (WARNING , "Failed to prepare transaction %s" , x -> gid );
3362
3369
/* ??? Should we do explicit rollback */
3363
3370
} else {
3364
3371
CommitTransactionCommand ();
@@ -3551,6 +3558,7 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3551
3558
switch (stmt -> kind )
3552
3559
{
3553
3560
case TRANS_STMT_BEGIN :
3561
+ case TRANS_STMT_START :
3554
3562
MtmTx .isTransactionBlock = true;
3555
3563
break ;
3556
3564
case TRANS_STMT_COMMIT :
@@ -3587,16 +3595,34 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3587
3595
case T_LoadStmt :
3588
3596
case T_ClusterStmt :
3589
3597
case T_VacuumStmt :
3590
- case T_ExplainStmt :
3591
3598
case T_VariableShowStmt :
3592
3599
case T_ReassignOwnedStmt :
3593
3600
case T_LockStmt :
3594
3601
case T_CheckPointStmt :
3595
3602
case T_ReindexStmt :
3596
- case T_RefreshMatViewStmt :
3597
3603
skipCommand = true;
3598
3604
break ;
3599
3605
3606
+ case T_ExplainStmt :
3607
+ /*
3608
+ * EXPLAIN ANALYZE can create side-effects.
3609
+ * Better to catch that by some general mechanism of detecting
3610
+ * catalog and heap writes.
3611
+ */
3612
+ {
3613
+ ExplainStmt * stmt = (ExplainStmt * ) parsetree ;
3614
+ ListCell * lc ;
3615
+
3616
+ skipCommand = true;
3617
+ foreach (lc , stmt -> options )
3618
+ {
3619
+ DefElem * opt = (DefElem * ) lfirst (lc );
3620
+ if (strcmp (opt -> defname , "analyze" ) == 0 )
3621
+ skipCommand = false;
3622
+ }
3623
+ }
3624
+ break ;
3625
+
3600
3626
/* Save GUC context for consequent DDL execution */
3601
3627
case T_DiscardStmt :
3602
3628
{
@@ -3657,12 +3683,15 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3657
3683
break ;
3658
3684
}
3659
3685
3660
- if (context == PROCESS_UTILITY_TOPLEVEL ) // || context == PROCESS_UTILITY_QUERY)
3686
+ /* XXX: dirty. Clear on new tx */
3687
+ if (!skipCommand && (context == PROCESS_UTILITY_TOPLEVEL || MtmUtilityProcessedInXid != GetCurrentTransactionId ()))
3688
+ MtmUtilityProcessedInXid = InvalidTransactionId ;
3689
+
3690
+ if (context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY )
3661
3691
{
3662
- if (!skipCommand && !MtmTx .isReplicated ) {
3663
- if (MtmProcessDDLCommand (queryString )) {
3664
- return ;
3665
- }
3692
+ if (!skipCommand && !MtmTx .isReplicated && (MtmUtilityProcessedInXid == InvalidTransactionId )) {
3693
+ MtmUtilityProcessedInXid = GetCurrentTransactionId ();
3694
+ MtmProcessDDLCommand (queryString );
3666
3695
}
3667
3696
}
3668
3697
@@ -3676,12 +3705,22 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3676
3705
standard_ProcessUtility (parsetree , queryString , context ,
3677
3706
params , dest , completionTag );
3678
3707
}
3708
+
3709
+ if (MyXactAccessedTempRel )
3710
+ {
3711
+ MTM_LOG1 ("Xact accessed temp table, stopping replication" );
3712
+ MtmTx .isDistributed = false; /* Skip */
3713
+ }
3714
+
3679
3715
}
3680
3716
3681
3717
3682
3718
static void
3683
3719
MtmExecutorFinish (QueryDesc * queryDesc )
3684
3720
{
3721
+ /*
3722
+ * If tx didn't wrote to XLOG then there is nothing to commit on other nodes.
3723
+ */
3685
3724
if (MtmDoReplication ) {
3686
3725
CmdType operation = queryDesc -> operation ;
3687
3726
EState * estate = queryDesc -> estate ;
@@ -3699,12 +3738,20 @@ MtmExecutorFinish(QueryDesc *queryDesc)
3699
3738
continue ;
3700
3739
}
3701
3740
}
3741
+ MTM_LOG1 ("MtmTx.containsDML = true // WAL" );
3702
3742
MtmTx .containsDML = true;
3703
3743
break ;
3704
3744
}
3705
3745
}
3706
3746
}
3707
3747
}
3748
+
3749
+ // if (MyXactAccessedRel)
3750
+ // {
3751
+ // MTM_LOG1("MtmTx.containsDML = true");
3752
+ // MtmTx.containsDML = true;
3753
+ // }
3754
+
3708
3755
if (PreviousExecutorFinishHook != NULL )
3709
3756
{
3710
3757
PreviousExecutorFinishHook (queryDesc );
0 commit comments