Loading storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +4 −13 Original line number Diff line number Diff line Loading @@ -5058,7 +5058,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) ptrAss(tcConnectptr, tcConnectRecord); TcConnectRecord * const regTcPtr = tcConnectptr.p; if (regTcPtr->tcConnectstate == OS_OPERATING) { apiConnectptr.i = regTcPtr->apiConnect; Uint32 save = apiConnectptr.i = regTcPtr->apiConnect; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); ApiConnectRecord * const regApiPtr = apiConnectptr.p; compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1; Loading Loading @@ -5182,7 +5182,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) regApiPtr->lqhkeyreqrec--; // Compensate for extra during read tcKeyRef->connectPtr = indexOp; EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength); apiConnectptr.i = regTcPtr->apiConnect; apiConnectptr.i = save; apiConnectptr.p = regApiPtr; } else { jam(); Loading @@ -5207,6 +5207,8 @@ void Dbtc::execLQHKEYREF(Signal* signal) jam(); sendtckeyconf(signal, 1); regApiPtr->apiConnectstate = CS_CONNECTED; regApiPtr->m_transaction_nodes.clear(); setApiConTimer(apiConnectptr.i, 0,__LINE__); } return; } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) { Loading Loading @@ -11864,17 +11866,6 @@ void Dbtc::execTCKEYREF(Signal* signal) case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): { jam(); // If we fail index access for a non-read operation during commit // we abort transaction if (commitFlg == 1) { jam(); releaseIndexOperation(regApiPtr, indexOp); apiConnectptr.i = indexOp->connectionIndex; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); terrorCode = tcKeyRef->errorCode; abortErrorLab(signal); break; } /** * Increase count as it will be decreased below... * (and the code is written to handle failing lookup on "real" table Loading storage/ndb/src/ndbapi/NdbTransaction.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -477,6 +477,7 @@ NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, * This timeout situation can occur if NDB crashes. */ ndbout << "This timeout should never occur, execute(..)" << endl; theError.code = 4012; setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure" DBUG_RETURN(-1); }//if Loading Loading @@ -1979,6 +1980,14 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, } } else if ((tNoComp >= tNoSent) && (theLastExecOpInList->theCommitIndicator == 1)){ if (m_abortOption == AO_IgnoreError && theError.code != 0){ /** * There's always a TCKEYCONF when using IgnoreError */ return -1; } /**********************************************************************/ // We sent the transaction with Commit flag set and received a CONF with // no Commit flag set. This is clearly an anomaly. Loading storage/ndb/src/ndbapi/Ndbif.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1089,6 +1089,7 @@ Ndb::check_send_timeout() //abort(); #endif a_con->theReleaseOnClose = true; a_con->theError.code = 4012; a_con->setOperationErrorCodeAbort(4012); a_con->theCommitStatus = NdbTransaction::NeedAbort; a_con->theCompletionStatus = NdbTransaction::CompletedFailure; Loading storage/ndb/test/ndbapi/testBasic.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -1250,6 +1250,29 @@ runInsertError2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } int runBug25090(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * dict = pNdb->getDictionary(); HugoOperations ops(*ctx->getTab()); int loops = ctx->getNumLoops(); const int rows = ctx->getNumRecords(); while (loops--) { ops.startTransaction(pNdb); ops.pkReadRecord(pNdb, 1, 1); ops.execute_Commit(pNdb, AO_IgnoreError); sleep(10); ops.closeTransaction(pNdb); } return NDBT_OK; } NDBT_TESTSUITE(testBasic); TESTCASE("PkInsert", "Verify that we can insert and delete from this table using PK" Loading Loading @@ -1510,6 +1533,16 @@ TESTCASE("InsertError", "" ){ TESTCASE("InsertError2", "" ){ INITIALIZER(runInsertError2); } TESTCASE("Fill", "Verify what happens when we fill the db" ){ INITIALIZER(runFillTable); INITIALIZER(runPkRead); FINALIZER(runClearTable2); } TESTCASE("Bug25090", "Verify what happens when we fill the db" ){ STEP(runBug25090); } NDBT_TESTSUITE_END(testBasic); #if 0 Loading storage/ndb/test/ndbapi/testIndex.cpp +66 −0 Original line number Diff line number Diff line Loading @@ -1239,7 +1239,65 @@ runBug21384(NDBT_Context* ctx, NDBT_Step* step) return NDBT_OK; } int runBug25059(NDBT_Context* ctx, NDBT_Step* step) { Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * dict = pNdb->getDictionary(); const NdbDictionary::Index * idx = dict->getIndex(pkIdxName, ctx->getTab()->getName()); HugoOperations ops(*ctx->getTab(), idx); int res = NDBT_OK; int loops = ctx->getNumLoops(); const int rows = ctx->getNumRecords(); while (res == NDBT_OK && loops--) { ops.startTransaction(pNdb); ops.pkReadRecord(pNdb, 10 + rand() % rows, rows); int tmp; if (tmp = ops.execute_Commit(pNdb, AO_IgnoreError)) { if (tmp == 4012) res = NDBT_FAILED; else if (ops.getTransaction()->getNdbError().code == 4012) res = NDBT_FAILED; } ops.closeTransaction(pNdb); } loops = ctx->getNumLoops(); while (res == NDBT_OK && loops--) { ops.startTransaction(pNdb); ops.pkUpdateRecord(pNdb, 10 + rand() % rows, rows); int tmp; int arg; switch(rand() % 2){ case 0: arg = AbortOnError; break; case 1: arg = AO_IgnoreError; ndbout_c("ignore error"); break; } if (tmp = ops.execute_Commit(pNdb, (AbortOption)arg)) { if (tmp == 4012) res = NDBT_FAILED; else if (ops.getTransaction()->getNdbError().code == 4012) res = NDBT_FAILED; } ops.closeTransaction(pNdb); } return res; } NDBT_TESTSUITE(testIndex); TESTCASE("CreateAll", Loading Loading @@ -1564,6 +1622,14 @@ TESTCASE("Bug21384", FINALIZER(createPkIndex_Drop); FINALIZER(runClearTable); } TESTCASE("Bug25059", "Test that unique indexes and nulls"){ TC_PROPERTY("LoggedIndexes", (unsigned)0); INITIALIZER(createPkIndex); INITIALIZER(runLoadTable); STEP(runBug25059); FINALIZER(createPkIndex_Drop); } NDBT_TESTSUITE_END(testIndex); int main(int argc, const char** argv){ Loading Loading
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +4 −13 Original line number Diff line number Diff line Loading @@ -5058,7 +5058,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) ptrAss(tcConnectptr, tcConnectRecord); TcConnectRecord * const regTcPtr = tcConnectptr.p; if (regTcPtr->tcConnectstate == OS_OPERATING) { apiConnectptr.i = regTcPtr->apiConnect; Uint32 save = apiConnectptr.i = regTcPtr->apiConnect; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); ApiConnectRecord * const regApiPtr = apiConnectptr.p; compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1; Loading Loading @@ -5182,7 +5182,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) regApiPtr->lqhkeyreqrec--; // Compensate for extra during read tcKeyRef->connectPtr = indexOp; EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength); apiConnectptr.i = regTcPtr->apiConnect; apiConnectptr.i = save; apiConnectptr.p = regApiPtr; } else { jam(); Loading @@ -5207,6 +5207,8 @@ void Dbtc::execLQHKEYREF(Signal* signal) jam(); sendtckeyconf(signal, 1); regApiPtr->apiConnectstate = CS_CONNECTED; regApiPtr->m_transaction_nodes.clear(); setApiConTimer(apiConnectptr.i, 0,__LINE__); } return; } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) { Loading Loading @@ -11864,17 +11866,6 @@ void Dbtc::execTCKEYREF(Signal* signal) case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): { jam(); // If we fail index access for a non-read operation during commit // we abort transaction if (commitFlg == 1) { jam(); releaseIndexOperation(regApiPtr, indexOp); apiConnectptr.i = indexOp->connectionIndex; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); terrorCode = tcKeyRef->errorCode; abortErrorLab(signal); break; } /** * Increase count as it will be decreased below... * (and the code is written to handle failing lookup on "real" table Loading
storage/ndb/src/ndbapi/NdbTransaction.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -477,6 +477,7 @@ NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, * This timeout situation can occur if NDB crashes. */ ndbout << "This timeout should never occur, execute(..)" << endl; theError.code = 4012; setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure" DBUG_RETURN(-1); }//if Loading Loading @@ -1979,6 +1980,14 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, } } else if ((tNoComp >= tNoSent) && (theLastExecOpInList->theCommitIndicator == 1)){ if (m_abortOption == AO_IgnoreError && theError.code != 0){ /** * There's always a TCKEYCONF when using IgnoreError */ return -1; } /**********************************************************************/ // We sent the transaction with Commit flag set and received a CONF with // no Commit flag set. This is clearly an anomaly. Loading
storage/ndb/src/ndbapi/Ndbif.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1089,6 +1089,7 @@ Ndb::check_send_timeout() //abort(); #endif a_con->theReleaseOnClose = true; a_con->theError.code = 4012; a_con->setOperationErrorCodeAbort(4012); a_con->theCommitStatus = NdbTransaction::NeedAbort; a_con->theCompletionStatus = NdbTransaction::CompletedFailure; Loading
storage/ndb/test/ndbapi/testBasic.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -1250,6 +1250,29 @@ runInsertError2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } int runBug25090(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * dict = pNdb->getDictionary(); HugoOperations ops(*ctx->getTab()); int loops = ctx->getNumLoops(); const int rows = ctx->getNumRecords(); while (loops--) { ops.startTransaction(pNdb); ops.pkReadRecord(pNdb, 1, 1); ops.execute_Commit(pNdb, AO_IgnoreError); sleep(10); ops.closeTransaction(pNdb); } return NDBT_OK; } NDBT_TESTSUITE(testBasic); TESTCASE("PkInsert", "Verify that we can insert and delete from this table using PK" Loading Loading @@ -1510,6 +1533,16 @@ TESTCASE("InsertError", "" ){ TESTCASE("InsertError2", "" ){ INITIALIZER(runInsertError2); } TESTCASE("Fill", "Verify what happens when we fill the db" ){ INITIALIZER(runFillTable); INITIALIZER(runPkRead); FINALIZER(runClearTable2); } TESTCASE("Bug25090", "Verify what happens when we fill the db" ){ STEP(runBug25090); } NDBT_TESTSUITE_END(testBasic); #if 0 Loading
storage/ndb/test/ndbapi/testIndex.cpp +66 −0 Original line number Diff line number Diff line Loading @@ -1239,7 +1239,65 @@ runBug21384(NDBT_Context* ctx, NDBT_Step* step) return NDBT_OK; } int runBug25059(NDBT_Context* ctx, NDBT_Step* step) { Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * dict = pNdb->getDictionary(); const NdbDictionary::Index * idx = dict->getIndex(pkIdxName, ctx->getTab()->getName()); HugoOperations ops(*ctx->getTab(), idx); int res = NDBT_OK; int loops = ctx->getNumLoops(); const int rows = ctx->getNumRecords(); while (res == NDBT_OK && loops--) { ops.startTransaction(pNdb); ops.pkReadRecord(pNdb, 10 + rand() % rows, rows); int tmp; if (tmp = ops.execute_Commit(pNdb, AO_IgnoreError)) { if (tmp == 4012) res = NDBT_FAILED; else if (ops.getTransaction()->getNdbError().code == 4012) res = NDBT_FAILED; } ops.closeTransaction(pNdb); } loops = ctx->getNumLoops(); while (res == NDBT_OK && loops--) { ops.startTransaction(pNdb); ops.pkUpdateRecord(pNdb, 10 + rand() % rows, rows); int tmp; int arg; switch(rand() % 2){ case 0: arg = AbortOnError; break; case 1: arg = AO_IgnoreError; ndbout_c("ignore error"); break; } if (tmp = ops.execute_Commit(pNdb, (AbortOption)arg)) { if (tmp == 4012) res = NDBT_FAILED; else if (ops.getTransaction()->getNdbError().code == 4012) res = NDBT_FAILED; } ops.closeTransaction(pNdb); } return res; } NDBT_TESTSUITE(testIndex); TESTCASE("CreateAll", Loading Loading @@ -1564,6 +1622,14 @@ TESTCASE("Bug21384", FINALIZER(createPkIndex_Drop); FINALIZER(runClearTable); } TESTCASE("Bug25059", "Test that unique indexes and nulls"){ TC_PROPERTY("LoggedIndexes", (unsigned)0); INITIALIZER(createPkIndex); INITIALIZER(runLoadTable); STEP(runBug25059); FINALIZER(createPkIndex_Drop); } NDBT_TESTSUITE_END(testIndex); int main(int argc, const char** argv){ Loading