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