@@ -946,14 +946,20 @@ void MtmPrecommitTransaction(char const* gid)
946
946
} else {
947
947
MtmTransState * ts = tm -> state ;
948
948
Assert (ts != NULL );
949
- Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS );
950
- ts -> status = TRANSACTION_STATUS_UNKNOWN ;
951
- ts -> csn = MtmAssignCSN ();
952
- MtmAdjustSubtransactions (ts );
953
- MtmSend2PCMessage (ts , MSG_PRECOMMITTED );
954
- Assert (replorigin_session_origin != InvalidRepOriginId );
955
- MtmUnlock ();
956
- SetPreparedTransactionState (ts -> gid , MULTIMASTER_PRECOMMITTED );
949
+ if (ts -> status == TRANSACTION_STATUS_IN_PROGRESS ) {
950
+ ts -> status = TRANSACTION_STATUS_UNKNOWN ;
951
+ ts -> csn = MtmAssignCSN ();
952
+ MtmAdjustSubtransactions (ts );
953
+ if (Mtm -> status != MTM_RECOVERY ) {
954
+ MtmSend2PCMessage (ts , MSG_PRECOMMITTED );
955
+ }
956
+ MtmUnlock ();
957
+ Assert (replorigin_session_origin != InvalidRepOriginId );
958
+ SetPreparedTransactionState (ts -> gid , MULTIMASTER_PRECOMMITTED );
959
+ } else {
960
+ elog (WARNING , "MtmPrecommitTransaction: transaction '%s' is already in %s state" , gid , MtmTxnStatusMnem [ts -> status ]);
961
+ MtmUnlock ();
962
+ }
957
963
}
958
964
}
959
965
}
@@ -1038,7 +1044,8 @@ Mtm2PCVoting(MtmCurrentTrans* x, MtmTransState* ts)
1038
1044
// MtmSend2PCMessage(ts, MSG_PRECOMMIT);
1039
1045
elog (LOG , "Distributed transaction is not committed in %ld msec" , USEC_TO_MSEC (now - start ));
1040
1046
} else {
1041
- elog (WARNING , "Commit of distributed transaction is canceled because of %ld msec timeout expiration" , USEC_TO_MSEC (timeout ));
1047
+ elog (WARNING , "Commit of distributed transaction %s (%d) is canceled because of %ld msec timeout expiration" ,
1048
+ ts -> gid , ts -> xid , USEC_TO_MSEC (timeout ));
1042
1049
MtmAbortTransaction (ts );
1043
1050
break ;
1044
1051
}
@@ -1383,15 +1390,15 @@ static void MtmLoadPreparedTransactions(void)
1383
1390
if (!found ) {
1384
1391
TransactionId xid = GetNewTransactionId (false);
1385
1392
MtmTransState * ts = (MtmTransState * )hash_search (MtmXid2State , & xid , HASH_ENTER , & found );
1386
- MTM_LOG1 ("Recover prepared transaction %s xid %d " , gid , xid );
1393
+ MTM_LOG1 ("Recover prepared transaction %s xid=%d state=%s " , gid , xid , pxacts [ i ]. state_3pc );
1387
1394
MyPgXact -> xid = InvalidTransactionId ; /* dirty hack:((( */
1388
1395
Assert (!found );
1389
1396
Mtm -> nActiveTransactions += 1 ;
1390
1397
ts -> isEnqueued = false;
1391
1398
ts -> isActive = true;
1392
1399
ts -> status = strcmp (pxacts [i ].state_3pc , MULTIMASTER_PRECOMMITTED ) == 0 ? TRANSACTION_STATUS_UNKNOWN : TRANSACTION_STATUS_IN_PROGRESS ;
1393
1400
ts -> isLocal = true;
1394
- ts -> isPrepared = false ;
1401
+ ts -> isPrepared = true ;
1395
1402
ts -> isPinned = false;
1396
1403
ts -> snapshot = INVALID_CSN ;
1397
1404
ts -> isTwoPhase = false;
@@ -1491,6 +1498,10 @@ XidStatus MtmExchangeGlobalTransactionStatus(char const* gid, XidStatus new_stat
1491
1498
if (old_status != TRANSACTION_STATUS_ABORTED ) {
1492
1499
tm -> status = new_status ;
1493
1500
}
1501
+ if (tm -> state != NULL && old_status == TRANSACTION_STATUS_IN_PROGRESS ) {
1502
+ /* Return UNKNOWN to mark that transaction was prepared */
1503
+ old_status = TRANSACTION_STATUS_UNKNOWN ;
1504
+ }
1494
1505
} else {
1495
1506
tm -> state = NULL ;
1496
1507
tm -> status = new_status ;
@@ -1605,7 +1616,7 @@ static void MtmPollStatusOfPreparedTransactions(int disabledNodeId)
1605
1616
MtmBroadcastPollMessage (ts );
1606
1617
}
1607
1618
} else {
1608
- MTM_LOG1 ("Skip transaction %d (%s) with status %s gtid.node=%d gtid.xid=%d votedMask=%lx" ,
1619
+ MTM_LOG2 ("Skip transaction %d (%s) with status %s gtid.node=%d gtid.xid=%d votedMask=%lx" ,
1609
1620
ts -> xid , ts -> gid , MtmTxnStatusMnem [ts -> status ], ts -> gtid .node , ts -> gtid .xid , ts -> votedMask );
1610
1621
}
1611
1622
}
@@ -1656,7 +1667,8 @@ void MtmRecoveryCompleted(void)
1656
1667
Mtm -> nodes [i ].lastHeartbeat = 0 ; /* defuse watchdog until first heartbeat is received */
1657
1668
}
1658
1669
/* Mode will be changed to online once all logical receiver are connected */
1659
- MtmSwitchClusterMode (MTM_CONNECTED );
1670
+ elog (LOG , "Recovery completed with %d active receivers from %d" , Mtm -> nReceivers , Mtm -> nLiveNodes - 1 );
1671
+ MtmSwitchClusterMode (Mtm -> nReceivers == Mtm -> nLiveNodes - 1 ? MTM_ONLINE : MTM_CONNECTED );
1660
1672
MtmUnlock ();
1661
1673
}
1662
1674
@@ -2549,7 +2561,7 @@ _PG_init(void)
2549
2561
0 ,
2550
2562
INT_MAX ,
2551
2563
PGC_BACKEND ,
2552
- 0 ,
2564
+ 0 ,\
2553
2565
NULL ,
2554
2566
NULL ,
2555
2567
NULL
@@ -2894,6 +2906,7 @@ void MtmReceiverStarted(int nodeId)
2894
2906
MtmEnableNode (nodeId );
2895
2907
MtmCheckQuorum ();
2896
2908
}
2909
+ elog (LOG , "Start %d receivers from %d cluster status %s" , Mtm -> nReceivers + 1 , Mtm -> nLiveNodes - 1 , MtmNodeStatusMnem [Mtm -> status ]);
2897
2910
if (++ Mtm -> nReceivers == Mtm -> nLiveNodes - 1 ) {
2898
2911
if (Mtm -> status == MTM_CONNECTED ) {
2899
2912
MtmSwitchClusterMode (MTM_ONLINE );
@@ -3672,11 +3685,11 @@ Datum mtm_dump_lock_graph(PG_FUNCTION_ARGS)
3672
3685
{
3673
3686
size_t lockGraphSize ;
3674
3687
char * lockGraphData ;
3675
- MtmLockNode (i + MtmMaxNodes , LW_SHARED );
3688
+ MtmLockNode (i + 1 + MtmMaxNodes , LW_SHARED );
3676
3689
lockGraphSize = Mtm -> nodes [i ].lockGraphUsed ;
3677
3690
lockGraphData = palloc (lockGraphSize );
3678
3691
memcpy (lockGraphData , Mtm -> nodes [i ].lockGraphData , lockGraphSize );
3679
- MtmUnlockNode (i + MtmMaxNodes );
3692
+ MtmUnlockNode (i + 1 + MtmMaxNodes );
3680
3693
3681
3694
if (lockGraphData ) {
3682
3695
GlobalTransactionId * gtid = (GlobalTransactionId * ) lockGraphData ;
@@ -4602,11 +4615,11 @@ MtmDetectGlobalDeadLockForXid(TransactionId xid)
4602
4615
if (i + 1 != MtmNodeId && !BIT_CHECK (Mtm -> disabledNodeMask , i )) {
4603
4616
size_t lockGraphSize ;
4604
4617
void * lockGraphData ;
4605
- MtmLockNode (i + MtmMaxNodes , LW_SHARED );
4618
+ MtmLockNode (i + 1 + MtmMaxNodes , LW_SHARED );
4606
4619
lockGraphSize = Mtm -> nodes [i ].lockGraphUsed ;
4607
4620
lockGraphData = palloc (lockGraphSize );
4608
4621
memcpy (lockGraphData , Mtm -> nodes [i ].lockGraphData , lockGraphSize );
4609
- MtmUnlockNode (i + MtmMaxNodes );
4622
+ MtmUnlockNode (i + 1 + MtmMaxNodes );
4610
4623
4611
4624
if (lockGraphData == NULL ) {
4612
4625
return true;
0 commit comments