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