Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 756c6e9

Browse files
committed
Commit stalled precommited transactions in case of single node alive
1 parent 9e8de2e commit 756c6e9

File tree

4 files changed

+24
-9
lines changed

4 files changed

+24
-9
lines changed

multimaster.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,9 +1958,11 @@ void MtmHandleApplyError(void)
19581958
* Actually, if node is precommitted (state == UNKNOWN) at any of nodes, then is is prepared at all nodes and so can be committed.
19591959
* But if coordinator of transaction is crashed, we made a decision about transaction commit only if transaction is precommitted at ALL live nodes.
19601960
* The reason is that we want to avoid extra polling to obtain maximum CSN from all nodes to assign it to committed transaction.
1961-
* Called only from MtmDisableNode in critical section.
1961+
* Called only from MtmDisableNode and in major mode.
1962+
*
1963+
* commitPrecommited is used when nnodes=2 and we are switching to major/referee mode.
19621964
*/
1963-
void MtmPollStatusOfPreparedTransactionsForDisabledNode(int disabledNodeId)
1965+
void MtmPollStatusOfPreparedTransactionsForDisabledNode(int disabledNodeId, bool commitPrecommited)
19641966
{
19651967
MtmTransState *ts;
19661968
for (ts = Mtm->transListHead; ts != NULL; ts = ts->next) {
@@ -1974,8 +1976,15 @@ void MtmPollStatusOfPreparedTransactionsForDisabledNode(int disabledNodeId)
19741976
MTM_ELOG(LOG, "Abort transaction %s because its coordinator is disabled and it is not prepared at node %d", ts->gid, MtmNodeId);
19751977
MtmFinishPreparedTransaction(ts, false);
19761978
} else {
1977-
MTM_LOG1("Poll state of transaction %s (%llu)", ts->gid, (long64)ts->xid);
1978-
MtmBroadcastPollMessage(ts);
1979+
if (commitPrecommited)
1980+
{
1981+
MtmFinishPreparedTransaction(ts, true);
1982+
}
1983+
else
1984+
{
1985+
MTM_LOG1("Poll state of transaction %s (%llu)", ts->gid, (long64)ts->xid);
1986+
MtmBroadcastPollMessage(ts);
1987+
}
19791988
}
19801989
} else {
19811990
MTM_LOG2("Skip transaction %s (%llu) with status %s gtid.node=%d gtid.xid=%llu votedMask=%llx",

multimaster.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ extern void MtmReleaseLocks(void);
445445
extern void MtmInitMessage(MtmArbiterMessage* msg, MtmMessageCode code);
446446
extern void MtmSetSnapshot(csn_t snapshot);
447447
extern void MtmRefereeInitialize(void);
448-
extern void MtmPollStatusOfPreparedTransactionsForDisabledNode(int disabledNodeId);
448+
extern void MtmPollStatusOfPreparedTransactionsForDisabledNode(int disabledNodeId, bool commitPrecommited);
449449
extern int MtmGetNumberOfVotingNodes(void);
450450

451451
#endif

state.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ MtmSetClusterStatus(MtmNodeStatus status)
7171
Mtm->recoverySlot = 0;
7272
Mtm->pglogicalReceiverMask = 0;
7373
Mtm->pglogicalSenderMask = 0;
74-
// XXXX: better to enable, but not now. It requires better testing
75-
// Mtm->recoveryCount++; /* this will restart replication connection */
74+
Mtm->recoveryCount++; /* this will restart replication connection */
7675
}
7776

7877
Mtm->status = status;
@@ -270,7 +269,7 @@ void MtmDisableNode(int nodeId)
270269
if (Mtm->status == MTM_ONLINE) {
271270
/* Make decision about prepared transaction status only in quorum */
272271
MtmLock(LW_EXCLUSIVE);
273-
MtmPollStatusOfPreparedTransactionsForDisabledNode(nodeId);
272+
MtmPollStatusOfPreparedTransactionsForDisabledNode(nodeId, false);
274273
MtmUnlock();
275274
}
276275
}
@@ -411,6 +410,13 @@ MtmRefreshClusterStatus()
411410
winner_node_id);
412411
Mtm->refereeGrant = true;
413412
MtmLock(LW_EXCLUSIVE);
413+
if (countZeroBits(SELF_CONNECTIVITY_MASK, Mtm->nAllNodes) == 1)
414+
{
415+
// XXXX: that is valid for two nodes. Better idea is to parametrize MtmPollStatus*
416+
// functions.
417+
int neighbor_node_id = MtmNodeId == 1 ? 2 : 1;
418+
MtmPollStatusOfPreparedTransactionsForDisabledNode(neighbor_node_id, true);
419+
}
414420
MtmEnableNode(MtmNodeId);
415421
MtmCheckState();
416422
MtmUnlock();

tests2/lib/bank_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ def total_tx(self, conn, cur, agg, conn_i):
255255
total = yield from cur.fetchone()
256256
if total[0] != self.total:
257257
agg.isolation += 1
258+
print(datetime.datetime.utcnow(), 'Isolation error, total ', self.total, ' -> ', total[0], ', node ', conn_i+1)
258259
self.total = total[0]
259260
print(self.oops)
260-
print(datetime.datetime.utcnow(), 'Isolation error, total = ', total, ', node ', conn_i+1)
261261
# yield from cur.execute('select * from mtm.get_nodes_state()')
262262
# nodes_state = yield from cur.fetchall()
263263
# for i, col in enumerate(self.nodes_state_fields):

0 commit comments

Comments
 (0)