@@ -450,7 +450,7 @@ bool MtmXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
450
450
for (i = 0 ;i < MAX_WAIT_LOOPS ;i ++ )
451
451
{
452
452
MtmTransState * ts = (MtmTransState * )hash_search (MtmXid2State ,& xid ,HASH_FIND ,NULL );
453
- if (ts != NULL /* && ts->status != TRANSACTION_STATUS_IN_PROGRESS*/ )
453
+ if (ts != NULL /* && ts->status != TRANSACTION_STATUS_IN_PROGRESS*/ )
454
454
{
455
455
if (ts -> csn > MtmTx .snapshot ) {
456
456
MTM_LOG4 ("%d: tuple with xid=%d(csn=%ld) is invisibile in snapshot %ld" ,
@@ -1242,13 +1242,17 @@ void MtmAbortTransaction(MtmTransState* ts)
1242
1242
{
1243
1243
Assert (MtmLockCount != 0 );/* should be invoked with exclsuive lock */
1244
1244
if (ts -> status != TRANSACTION_STATUS_ABORTED ) {
1245
- MTM_LOG1 ("Rollback active transaction %d:%d (local xid %d)" ,ts -> gtid .node ,ts -> gtid .xid ,ts -> xid );
1246
- ts -> status = TRANSACTION_STATUS_ABORTED ;
1247
- MtmAdjustSubtransactions (ts );
1248
- if (ts -> isActive ) {
1249
- ts -> isActive = false;
1250
- Assert (Mtm -> nActiveTransactions != 0 );
1251
- Mtm -> nActiveTransactions -= 1 ;
1245
+ if (ts -> status == TRANSACTION_STATUS_COMMITTED ) {
1246
+ elog (WARNING ,"Attempt to rollback already committed transaction %d (%s)" ,ts -> xid ,ts -> gid );
1247
+ }else {
1248
+ MTM_LOG1 ("Rollback active transaction %d:%d (local xid %d) status %d" ,ts -> gtid .node ,ts -> gtid .xid ,ts -> xid ,ts -> status );
1249
+ ts -> status = TRANSACTION_STATUS_ABORTED ;
1250
+ MtmAdjustSubtransactions (ts );
1251
+ if (ts -> isActive ) {
1252
+ ts -> isActive = false;
1253
+ Assert (Mtm -> nActiveTransactions != 0 );
1254
+ Mtm -> nActiveTransactions -= 1 ;
1255
+ }
1252
1256
}
1253
1257
}
1254
1258
}
@@ -1320,6 +1324,7 @@ static void MtmDisableNode(int nodeId)
1320
1324
elog (WARNING ,"Disable node %d at xlog position %lx, last status change time %d msec ago" ,nodeId ,GetXLogInsertRecPtr (),
1321
1325
(int )USEC_TO_MSEC (now - Mtm -> nodes [nodeId - 1 ].lastStatusChangeTime ));
1322
1326
BIT_SET (Mtm -> disabledNodeMask ,nodeId - 1 );
1327
+ Mtm -> nodes [nodeId - 1 ].timeline += 1 ;
1323
1328
Mtm -> nodes [nodeId - 1 ].lastStatusChangeTime = now ;
1324
1329
Mtm -> nodes [nodeId - 1 ].lastHeartbeat = 0 ;/* defuse watchdog until first heartbeat is received */
1325
1330
if (nodeId != MtmNodeId ) {
@@ -1343,8 +1348,8 @@ static void MtmEnableNode(int nodeId)
1343
1348
void MtmRecoveryCompleted (void )
1344
1349
{
1345
1350
int i ;
1346
- MTM_LOG1 ("Recovery of node %d is completed, disabled mask=%lx,reconnect mask=%lx, live nodes=%d" ,
1347
- MtmNodeId ,Mtm -> disabledNodeMask ,Mtm -> reconnectMask ,Mtm -> nLiveNodes );
1351
+ MTM_LOG1 ("Recovery of node %d is completed, disabled mask=%lx,connectivity mask=%lx, live nodes=%d" ,
1352
+ MtmNodeId ,Mtm -> disabledNodeMask ,Mtm -> connectivityMask ,Mtm -> nLiveNodes );
1348
1353
MtmLock (LW_EXCLUSIVE );
1349
1354
Mtm -> recoverySlot = 0 ;
1350
1355
BIT_CLEAR (Mtm -> disabledNodeMask ,MtmNodeId - 1 );
@@ -1902,6 +1907,7 @@ static void MtmInitialize()
1902
1907
Mtm -> nodes [i ].lastHeartbeat = 0 ;
1903
1908
Mtm -> nodes [i ].restartLsn = 0 ;
1904
1909
Mtm -> nodes [i ].originId = InvalidRepOriginId ;
1910
+ Mtm -> nodes [i ].timeline = 0 ;
1905
1911
}
1906
1912
PGSemaphoreCreate (& Mtm -> sendSemaphore );
1907
1913
PGSemaphoreReset (& Mtm -> sendSemaphore );