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