@@ -942,6 +942,7 @@ void MtmPrecommitTransaction(char const* gid)
942
942
ts -> csn = MtmAssignCSN ();
943
943
MtmAdjustSubtransactions (ts );
944
944
MtmSend2PCMessage (ts , MSG_PRECOMMITTED );
945
+ SetPrepareTransactionState (ts -> gid , "precommitted" );
945
946
}
946
947
}
947
948
MtmUnlock ();
@@ -1561,7 +1562,10 @@ void MtmHandleApplyError(void)
1561
1562
}
1562
1563
1563
1564
/**
1564
- * Check status of all prepared transactions with coordinator at disabled node
1565
+ * Check status of all prepared transactions with coordinator at disabled node.
1566
+ * Actually, if node is precommitted (state == UNKNOWN) at any of nodes, then is is prepared at all nodes and so can be committed.
1567
+ * But if coordinator of transaction is crashed, we made a decision about transaction commit only if transaction is precommitted at ALL live nodes.
1568
+ * The reason is that we want to avoid extra polling to obtain maximum CSN from all nodes to assign it to committed transaction.
1565
1569
* Called only from MtmDisableNode in critical section.
1566
1570
*/
1567
1571
static void MtmPollStatusOfPreparedTransactions (int disabledNodeId )
@@ -1602,9 +1606,12 @@ static void MtmDisableNode(int nodeId)
1602
1606
Mtm -> nodes [nodeId - 1 ].lastStatusChangeTime = now ;
1603
1607
Mtm -> nodes [nodeId - 1 ].lastHeartbeat = 0 ; /* defuse watchdog until first heartbeat is received */
1604
1608
if (nodeId != MtmNodeId ) {
1605
- Mtm -> nLiveNodes -= 1 ;
1609
+ Mtm -> nLiveNodes -= 1 ;
1610
+ }
1611
+ if (Mtm -> nLiveNodes >= Mtm -> nAllNodes /2 + 1 ) {
1612
+ /* Make decision about prepared transaction status only in quorum */
1613
+ MtmPollStatusOfPreparedTransactions (nodeId );
1606
1614
}
1607
- MtmPollStatusOfPreparedTransactions (nodeId );
1608
1615
}
1609
1616
1610
1617
static void MtmEnableNode (int nodeId )
0 commit comments