@@ -27663,17 +27663,26 @@ Dbdict::execSCHEMA_TRANS_BEGIN_REQ(Signal* signal)
27663
27663
break;
27664
27664
}
27665
27665
27666
- if (c_takeOverInProgress )
27666
+ if (!localTrans )
27667
27667
{
27668
- /**
27669
- * There is a dict takeover in progress. There may thus another
27670
- * transaction that should be rolled backward or forward before we
27671
- * can allow another transaction to start.
27672
- */
27673
- jam();
27674
- setError(error, SchemaTransBeginRef::Busy, __LINE__);
27675
- break;
27668
+ ndbassert(getOwnNodeId() == c_masterNodeId);
27669
+ NodeRecordPtr masterNodePtr;
27670
+ c_nodes.getPtr(masterNodePtr, c_masterNodeId);
27671
+
27672
+ if (masterNodePtr.p->nodeState == NodeRecord::NDB_MASTER_TAKEOVER)
27673
+ {
27674
+ jam();
27675
+ /**
27676
+ * There is a dict takeover in progress. There may thus be another
27677
+ * transaction that should be rolled backward or forward before we
27678
+ * can allow another transaction to start.
27679
+ * (Multiple concurrent schema transactions are not supported)
27680
+ */
27681
+ setError(error, SchemaTransBeginRef::Busy, __LINE__);
27682
+ break;
27683
+ }
27676
27684
}
27685
+ ndbassert(!c_takeOverInProgress);
27677
27686
27678
27687
if (!check_ndb_versions() && !localTrans)
27679
27688
{
@@ -27853,8 +27862,7 @@ Dbdict::execSCHEMA_TRANS_END_REQ(Signal* signal)
27853
27862
SchemaTransPtr trans_ptr;
27854
27863
ErrorInfo error;
27855
27864
do {
27856
- findSchemaTrans(trans_ptr, trans_key);
27857
- if (trans_ptr.isNull()) {
27865
+ if (!findSchemaTrans(trans_ptr, trans_key)) {
27858
27866
jam();
27859
27867
setError(error, SchemaTransEndRef::InvalidTransKey, __LINE__);
27860
27868
break;
@@ -27876,31 +27884,32 @@ Dbdict::execSCHEMA_TRANS_END_REQ(Signal* signal)
27876
27884
break;
27877
27885
}
27878
27886
27879
- if (c_takeOverInProgress )
27887
+ if (!localTrans )
27880
27888
{
27881
- /**
27882
- * There is a dict takeover in progress, and the transaction may thus
27883
- * be in an inconsistent state. Therefore we cannot process this request
27884
- * now.
27885
- */
27886
- jam();
27887
- setError(error, SchemaTransEndRef::Busy, __LINE__);
27888
- break;
27889
+ ndbassert(getOwnNodeId() == c_masterNodeId);
27890
+ NodeRecordPtr masterNodePtr;
27891
+ c_nodes.getPtr(masterNodePtr, c_masterNodeId);
27892
+
27893
+ if (masterNodePtr.p->nodeState == NodeRecord::NDB_MASTER_TAKEOVER)
27894
+ {
27895
+ jam();
27896
+ /**
27897
+ * There is a dict takeover in progress.
27898
+ * Transaction might be in an inconsistent state where its fate
27899
+ * has not been decided yet. When takeover eventually completes,
27900
+ * it will ::sendTransClientReply() which will inform the client
27901
+ * about the fate of the Txn in a TRANS_END_REP.
27902
+ * For now we don't send any reply, and let the client wait for
27903
+ * TRANS_END_REP.
27904
+ */
27905
+ return;
27906
+ }
27889
27907
}
27908
+
27890
27909
#ifdef MARTIN
27891
27910
ndbout_c("Dbdict::execSCHEMA_TRANS_END_REQ: trans %u, state %u", trans_ptr.i, trans_ptr.p->m_state);
27892
27911
#endif
27893
27912
27894
- //XXX Check state
27895
-
27896
- if (hasError(trans_ptr.p->m_error))
27897
- {
27898
- jam();
27899
- ndbassert(false);
27900
- setError(error, SchemaTransEndRef::InvalidTransState, __LINE__);
27901
- break;
27902
- }
27903
-
27904
27913
bool localTrans2 = requestInfo & DictSignal::RF_LOCAL_TRANS;
27905
27914
if (localTrans != localTrans2)
27906
27915
{
@@ -27910,6 +27919,11 @@ Dbdict::execSCHEMA_TRANS_END_REQ(Signal* signal)
27910
27919
break;
27911
27920
}
27912
27921
27922
+ // Assert that we are not in an inconsistent/incomplete state
27923
+ ndbassert(!hasError(trans_ptr.p->m_error));
27924
+ ndbassert(!c_takeOverInProgress);
27925
+ ndbassert(trans_ptr.p->m_counter.done());
27926
+
27913
27927
trans_ptr.p->m_clientState = TransClient::EndReq;
27914
27928
27915
27929
const bool doBackground = flags & SchemaTransEndReq::SchemaTransBackground;
0 commit comments