@@ -1103,7 +1103,7 @@ MtmAbortPreparedTransaction(MtmCurrentTrans* x)
1103
1103
static void
1104
1104
MtmEndTransaction (MtmCurrentTrans * x , bool commit )
1105
1105
{
1106
- MTM_LOG1 ("%d: End transaction %d, prepared=%d, replicated=%d, distributed=%d, 2pc=%d, gid=%s -> %s" ,
1106
+ MTM_LOG2 ("%d: End transaction %d, prepared=%d, replicated=%d, distributed=%d, 2pc=%d, gid=%s -> %s" ,
1107
1107
MyProcPid , x -> xid , x -> isPrepared , x -> isReplicated , x -> isDistributed , x -> isTwoPhase , x -> gid , commit ? "commit" : "abort" );
1108
1108
if (x -> status != TRANSACTION_STATUS_ABORTED && x -> isDistributed && (x -> isPrepared || x -> isReplicated ) && !x -> isTwoPhase ) {
1109
1109
MtmTransState * ts = NULL ;
@@ -1121,7 +1121,7 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
1121
1121
}
1122
1122
if (ts != NULL ) {
1123
1123
if (* ts -> gid )
1124
- MTM_LOG1 ("TRANSLOG: %s transaction %s status %d" , (commit ? "commit" : "rollback" ), ts -> gid , ts -> status );
1124
+ MTM_LOG2 ("TRANSLOG: %s transaction %s status %d" , (commit ? "commit" : "rollback" ), ts -> gid , ts -> status );
1125
1125
if (commit ) {
1126
1126
if (!(ts -> status == TRANSACTION_STATUS_UNKNOWN
1127
1127
|| (ts -> status == TRANSACTION_STATUS_IN_PROGRESS && Mtm -> status == MTM_RECOVERY )))
@@ -1176,6 +1176,9 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
1176
1176
Mtm -> nActiveTransactions -= 1 ;
1177
1177
}
1178
1178
MtmTransactionListAppend (ts );
1179
+ if (* x -> gid ) {
1180
+ LogLogicalMessage ("A" , x -> gid , strlen (x -> gid ) + 1 , false);
1181
+ }
1179
1182
}
1180
1183
MtmSend2PCMessage (ts , MSG_ABORTED ); /* send notification to coordinator */
1181
1184
} else if (x -> status == TRANSACTION_STATUS_ABORTED && x -> isReplicated && !x -> isPrepared ) {
@@ -1229,7 +1232,7 @@ void MtmSend2PCMessage(MtmTransState* ts, MtmMessageCode cmd)
1229
1232
MtmSendMessage (& msg );
1230
1233
}
1231
1234
}
1232
- } else {
1235
+ } else if (! BIT_CHECK ( Mtm -> disabledNodeMask , ts -> gtid . node - 1 )) {
1233
1236
msg .node = ts -> gtid .node ;
1234
1237
msg .dxid = ts -> gtid .xid ;
1235
1238
MtmSendMessage (& msg );
@@ -1435,7 +1438,7 @@ static void MtmPollStatusOfPreparedTransactions(int disabledNodeId)
1435
1438
Assert (ts -> gid [0 ]);
1436
1439
if (ts -> status == TRANSACTION_STATUS_IN_PROGRESS ) {
1437
1440
elog (LOG , "Abort transaction %s because its coordinator is disabled and it is not prepared at node %d" , ts -> gid , MtmNodeId );
1438
- MtmFinishPreparedTransaction (disabledNodeId , ts , false);
1441
+ MtmFinishPreparedTransaction (ts , false);
1439
1442
} else {
1440
1443
MTM_LOG1 ("Poll state of transaction %d (%s)" , ts -> xid , ts -> gid );
1441
1444
MtmBroadcastPollMessage (ts );
@@ -1458,7 +1461,9 @@ static void MtmDisableNode(int nodeId)
1458
1461
if (nodeId != MtmNodeId ) {
1459
1462
Mtm -> nLiveNodes -= 1 ;
1460
1463
}
1464
+ MtmUnlock ();
1461
1465
MtmPollStatusOfPreparedTransactions (nodeId );
1466
+ MtmLock (LW_EXCLUSIVE );
1462
1467
}
1463
1468
1464
1469
static void MtmEnableNode (int nodeId )
@@ -2779,34 +2784,41 @@ void MtmReleaseRecoverySlot(int nodeId)
2779
2784
}
2780
2785
}
2781
2786
2782
- void MtmFinishPreparedTransaction ( int nodeId , MtmTransState * ts , bool commit )
2787
+ void MtmRollbackPreparedTransaction ( char const * gid )
2783
2788
{
2789
+ MTM_LOG1 ("Abort prepared transaction %s" , gid );
2790
+ if (MtmExchangeGlobalTransactionStatus (gid , TRANSACTION_STATUS_ABORTED ) == TRANSACTION_STATUS_UNKNOWN ) {
2791
+ MTM_LOG1 ("PGLOGICAL_ABORT_PREPARED commit: gid=%s #2" , gid );
2792
+ MtmResetTransaction ();
2793
+ StartTransactionCommand ();
2794
+ MtmBeginSession (MtmReplicationNodeId );
2795
+ MtmSetCurrentTransactionGID (gid );
2796
+ FinishPreparedTransaction (gid , false);
2797
+ CommitTransactionCommand ();
2798
+ MtmEndSession (MtmReplicationNodeId , true);
2799
+ }
2800
+ }
2801
+
2802
+
2803
+ void MtmFinishPreparedTransaction (MtmTransState * ts , bool commit )
2804
+ {
2805
+ if (Mtm -> nodes [MtmNodeId - 1 ].originId == InvalidRepOriginId ) {
2806
+ /* This dummy origin is used for local commits/aborts which should not be replicated */
2807
+ Mtm -> nodes [MtmNodeId - 1 ].originId = replorigin_create (psprintf (MULTIMASTER_SLOT_PATTERN , MtmNodeId ));
2808
+ }
2784
2809
Assert (ts -> votingCompleted );
2785
2810
Assert (!IsTransactionState ());
2786
2811
MtmResetTransaction ();
2787
2812
StartTransactionCommand ();
2788
- MtmBeginSession (nodeId );
2813
+ MtmBeginSession (MtmNodeId );
2789
2814
MtmSetCurrentTransactionCSN (ts -> csn );
2790
2815
MtmSetCurrentTransactionGID (ts -> gid );
2791
2816
FinishPreparedTransaction (ts -> gid , commit );
2792
2817
CommitTransactionCommand ();
2793
- MtmEndSession (nodeId , true);
2818
+ MtmEndSession (MtmNodeId , true);
2794
2819
Assert (ts -> status == commit ? TRANSACTION_STATUS_COMMITTED : TRANSACTION_STATUS_ABORTED );
2795
2820
}
2796
2821
2797
- #if 0
2798
- static void MtmFinishAllPreparedTransactions (void )
2799
- {
2800
- MtmTransState * ts ;
2801
- for (ts = Mtm -> transListHead ; ts != NULL ; ts = ts -> next ) {
2802
- if (ts -> status != TRANSACTION_STATUS_COMMITTED && ts -> status != TRANSACTION_STATUS_ABORTED ) {
2803
- MtmFinishPreparedTransaction (MtmReplicationNodeId , ts , false);
2804
- }
2805
- }
2806
- }
2807
- #endif
2808
-
2809
-
2810
2822
/*
2811
2823
* Determine when and how we should open replication slot.
2812
2824
* Druing recovery we need to open only one replication slot from which node should receive all transactions.
@@ -2840,11 +2852,6 @@ MtmReplicationMode MtmGetReplicationMode(int nodeId, sig_atomic_t volatile* shut
2840
2852
Mtm -> nodes [i ].restartLsn = InvalidXLogRecPtr ;
2841
2853
}
2842
2854
MtmUnlock ();
2843
- #if 0
2844
- MtmBeginSession (MtmReplicationNodeId );
2845
- FinishAllPreparedTransactions (false);
2846
- MtmEndSession (MtmReplicationNodeId , true);
2847
- #endif
2848
2855
return REPLMODE_RECOVERY ;
2849
2856
}
2850
2857
}
0 commit comments