@@ -114,6 +114,7 @@ PG_FUNCTION_INFO_V1(mtm_get_cluster_state);
114
114
PG_FUNCTION_INFO_V1 (mtm_get_cluster_info );
115
115
PG_FUNCTION_INFO_V1 (mtm_make_table_local );
116
116
PG_FUNCTION_INFO_V1 (mtm_dump_lock_graph );
117
+ PG_FUNCTION_INFO_V1 (mtm_inject_2pc_error );
117
118
118
119
static Snapshot MtmGetSnapshot (Snapshot snapshot );
119
120
static void MtmInitialize (void );
@@ -688,6 +689,10 @@ MtmPrePrepareTransaction(MtmCurrentTrans* x)
688
689
return ;
689
690
}
690
691
692
+ if (Mtm -> inject2PCError == 1 ) {
693
+ Mtm -> inject2PCError = 0 ;
694
+ elog (ERROR , "ERROR INJECTION for transaction %d (%s)" , x -> xid , x -> gid );
695
+ }
691
696
x -> xid = GetCurrentTransactionId ();
692
697
Assert (TransactionIdIsValid (x -> xid ));
693
698
@@ -742,6 +747,10 @@ MtmPostPrepareTransaction(MtmCurrentTrans* x)
742
747
{
743
748
MtmTransState * ts ;
744
749
750
+ if (Mtm -> inject2PCError == 2 ) {
751
+ Mtm -> inject2PCError = 0 ;
752
+ elog (ERROR , "ERROR INJECTION for transaction %d (%s)" , x -> xid , x -> gid );
753
+ }
745
754
MtmLock (LW_EXCLUSIVE );
746
755
ts = hash_search (MtmXid2State , & x -> xid , HASH_FIND , NULL );
747
756
Assert (ts != NULL );
@@ -783,6 +792,10 @@ MtmPostPrepareTransaction(MtmCurrentTrans* x)
783
792
MTM_LOG3 ("%d: Result of vote: %d" , MyProcPid , ts -> status );
784
793
MtmUnlock ();
785
794
}
795
+ if (Mtm -> inject2PCError == 3 ) {
796
+ Mtm -> inject2PCError = 0 ;
797
+ elog (ERROR , "ERROR INJECTION for transaction %d (%s)" , x -> xid , x -> gid );
798
+ }
786
799
}
787
800
788
801
@@ -1484,6 +1497,7 @@ static void MtmInitialize()
1484
1497
Mtm -> gcCount = 0 ;
1485
1498
Mtm -> nConfigChanges = 0 ;
1486
1499
Mtm -> localTablesHashLoaded = false;
1500
+ Mtm -> inject2PCError = 0 ;
1487
1501
for (i = 0 ; i < MtmNodes ; i ++ ) {
1488
1502
Mtm -> nodes [i ].oldestSnapshot = 0 ;
1489
1503
Mtm -> nodes [i ].transDelay = 0 ;
@@ -2427,12 +2441,13 @@ mtm_get_cluster_info(PG_FUNCTION_ARGS)
2427
2441
usrfctx = (MtmGetClusterInfoCtx * )palloc (sizeof (MtmGetNodeStateCtx ));
2428
2442
get_call_result_type (fcinfo , NULL , & desc );
2429
2443
funcctx -> attinmeta = TupleDescGetAttInMetadata (desc );
2430
- usrfctx -> nodeId = 1 ;
2444
+ usrfctx -> nodeId = 0 ;
2431
2445
funcctx -> user_fctx = usrfctx ;
2432
2446
MemoryContextSwitchTo (oldcontext );
2433
2447
}
2434
2448
funcctx = SRF_PERCALL_SETUP ();
2435
2449
usrfctx = (MtmGetClusterInfoCtx * )funcctx -> user_fctx ;
2450
+ while (++ usrfctx -> nodeId <= Mtm -> nAllNodes && BIT_CHECK (Mtm -> disabledNodeMask , usrfctx -> nodeId - 1 ));
2436
2451
if (usrfctx -> nodeId > Mtm -> nAllNodes ) {
2437
2452
SRF_RETURN_DONE (funcctx );
2438
2453
}
@@ -2528,6 +2543,12 @@ Datum mtm_dump_lock_graph(PG_FUNCTION_ARGS)
2528
2543
return CStringGetTextDatum (s -> data );
2529
2544
}
2530
2545
2546
+ Datum mtm_inject_2pc_error (PG_FUNCTION_ARGS )
2547
+ {
2548
+ Mtm -> inject2PCError = PG_GETARG_INT32 (0 );
2549
+ PG_RETURN_VOID ();
2550
+ }
2551
+
2531
2552
/*
2532
2553
* -------------------------------------------
2533
2554
* Broadcast utulity statements
@@ -2800,9 +2821,12 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
2800
2821
}
2801
2822
break ;
2802
2823
case TRANS_STMT_PREPARE :
2824
+ elog (ERROR , "Two phase commit is not supported by multimaster" );
2825
+ break ;
2803
2826
case TRANS_STMT_COMMIT_PREPARED :
2804
2827
case TRANS_STMT_ROLLBACK_PREPARED :
2805
- elog (ERROR , "Two phase commit is not supported by multimaster" );
2828
+ skipCommand = true;
2829
+ break ;
2806
2830
default :
2807
2831
break ;
2808
2832
}
0 commit comments