From abf8c93d80111a3dc9f31a8033f75707b2cc28ff Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 7 Jul 2004 13:40:53 +0200 Subject: [PATCH] testIndex -n NFNR1 Bugs in scan(tc) nf-handling(api) exec-handling(tc) ndb/include/ndbapi/NdbConnection.hpp: Allow dropped signal during NF handling ndb/include/ndbapi/NdbOperation.hpp: Add option to allow dropped signals ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: 1) Printer for state 2) New option to sendtckeyconf (index) - clear exec flag 3) Moved init of *global* apiConnectptr to prevent errornous scan_tabconf ARGH!!! ndb/src/ndbapi/NdbConnection.cpp: Move abort from checkState_trans since it can be ok with "illegal" signals during NF handling ndb/src/ndbapi/NdbConnectionScan.cpp: Move abort from checkState_trans since it can be ok with "illegal" signals during NF handling ndb/src/ndbapi/Ndbif.cpp: 1) Indentation 2) Better handling of TCKEY_FAILCONF - always ack commit ack marker even if transaction has already been removed 3) abort on 4012 (VM_TRACE) ndb/src/ndbapi/TransporterFacade.cpp: Don't trace APIREG_REQ/CONF by default ndb/test/include/NDBT_Test.hpp: Atomic decProperty (used for semaphore impl.) ndb/test/ndbapi/testIndex.cpp: Impl. option to sync restarts ndb/test/src/NDBT_Test.cpp: Atomic decProperty --- ndb/include/ndbapi/NdbConnection.hpp | 3 - ndb/include/ndbapi/NdbOperation.hpp | 6 +- ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 91 ++++++++--- ndb/src/ndbapi/NdbConnection.cpp | 51 +++++- ndb/src/ndbapi/NdbConnectionScan.cpp | 9 ++ ndb/src/ndbapi/Ndbif.cpp | 199 +++++++++++++----------- ndb/src/ndbapi/TransporterFacade.cpp | 26 ++-- ndb/test/include/NDBT_Test.hpp | 2 + ndb/test/ndbapi/testIndex.cpp | 43 ++++- ndb/test/src/NDBT_Test.cpp | 12 ++ 10 files changed, 301 insertions(+), 141 deletions(-) diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index e57bb5c2465..5d73058cc24 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -693,9 +693,6 @@ NdbConnection::checkState_TransId(const Uint32 * transId) const { const Uint32 tTmp2 = transId[1]; Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); bool b = theStatus == Connected && theTransactionId == tRecTransId; -#ifdef NDB_NO_DROPPED_SIGNAL - if(!b) abort(); -#endif return b; } diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 6185225f6d1..625fc8b233a 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -755,7 +755,7 @@ protected: int receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength); - int checkMagicNumber(); // Verify correct object + int checkMagicNumber(bool b = true); // Verify correct object int checkState_TransId(NdbApiSignal* aSignal); @@ -900,11 +900,11 @@ protected: inline int -NdbOperation::checkMagicNumber() +NdbOperation::checkMagicNumber(bool b) { if (theMagicNumber != 0xABCDEF01){ #ifdef NDB_NO_DROPPED_SIGNAL - abort(); + if(b) abort(); #endif return -1; } diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 05dffadc058..5da2b7551a8 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -79,7 +79,36 @@ #ifdef VM_TRACE NdbOut & operator<<(NdbOut& out, Dbtc::ConnectionState state){ - out << (int)state; + switch(state){ + case Dbtc::CS_CONNECTED: out << "CS_CONNECTED"; break; + case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break; + case Dbtc::CS_STARTED: out << "CS_STARTED"; break; + case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break; + case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break; + case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break; + case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break; + case Dbtc::CS_RESTART: out << "CS_RESTART"; break; + case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break; + case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break; + case Dbtc::CS_COMPLETE_SENT: out << "CS_COMPLETE_SENT"; break; + case Dbtc::CS_PREPARE_TO_COMMIT: out << "CS_PREPARE_TO_COMMIT"; break; + case Dbtc::CS_COMMIT_SENT: out << "CS_COMMIT_SENT"; break; + case Dbtc::CS_START_COMMITTING: out << "CS_START_COMMITTING"; break; + case Dbtc::CS_COMMITTING: out << "CS_COMMITTING"; break; + case Dbtc::CS_REC_COMMITTING: out << "CS_REC_COMMITTING"; break; + case Dbtc::CS_WAIT_ABORT_CONF: out << "CS_WAIT_ABORT_CONF"; break; + case Dbtc::CS_WAIT_COMPLETE_CONF: out << "CS_WAIT_COMPLETE_CONF"; break; + case Dbtc::CS_WAIT_COMMIT_CONF: out << "CS_WAIT_COMMIT_CONF"; break; + case Dbtc::CS_FAIL_ABORTING: out << "CS_FAIL_ABORTING"; break; + case Dbtc::CS_FAIL_ABORTED: out << "CS_FAIL_ABORTED"; break; + case Dbtc::CS_FAIL_PREPARED: out << "CS_FAIL_PREPARED"; break; + case Dbtc::CS_FAIL_COMMITTING: out << "CS_FAIL_COMMITTING"; break; + case Dbtc::CS_FAIL_COMMITTED: out << "CS_FAIL_COMMITTED"; break; + case Dbtc::CS_FAIL_COMPLETED: out << "CS_FAIL_COMPLETED"; break; + case Dbtc::CS_START_SCAN: out << "CS_START_SCAN"; break; + default: + out << "Unknown: " << (int)state; break; + } return out; } NdbOut & @@ -949,7 +978,7 @@ Dbtc::handleFailedApiNode(Signal* signal, scanPtr.i = apiConnectptr.p->apiScanRec; ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord); close_scan_req(signal, scanPtr, true); - + TloopCount += 64; break; case CS_CONNECTED: @@ -1240,13 +1269,13 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) jam(); /* JUST REPLY OK */ releaseApiCon(signal, apiConnectptr.i); signal->theData[0] = tuserpointer; - sendSignal(apiConnectptr.p->ndbapiBlockref, + sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB); } else { jam(); signal->theData[0] = tuserpointer; signal->theData[1] = ZINVALID_CONNECTION; - sendSignal(apiConnectptr.p->ndbapiBlockref, + sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 2, JBB); } } else { @@ -3683,7 +3712,7 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, case CS_RECEIVING: if (TnoOfOutStanding == 0) { jam(); - sendtckeyconf(signal, 0); + sendtckeyconf(signal, 2); return; } else { if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) { @@ -3742,7 +3771,7 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) ptrAss(localHostptr, hostRecord); UintR TcurrLen = localHostptr.p->noOfWordsTCKEYCONF; UintR confInfo = 0; - TcKeyConf::setCommitFlag(confInfo, TcommitFlag); + TcKeyConf::setCommitFlag(confInfo, TcommitFlag == 1); TcKeyConf::setMarkerFlag(confInfo, Tmarker); const UintR TpacketLen = 6 + TopWords; regApiPtr->tckeyrec = 0; @@ -3767,8 +3796,10 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) return; // No queued TcKeyConf }//if }//if - - regApiPtr->m_exec_flag = 0; + if(TcommitFlag){ + jam(); + regApiPtr->m_exec_flag = 0; + } TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1)); if ((TpacketLen > 25) || !is_api){ TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend(); @@ -4481,6 +4512,8 @@ void Dbtc::copyApi(Signal* signal) setApiConTimer(tmpApiConnectptr.i, 0, __LINE__); regTmpApiPtr->apiConnectstate = CS_CONNECTED; regTmpApiPtr->commitAckMarker = RNIL; + regTmpApiPtr->firstTcConnect = RNIL; + regTmpApiPtr->lastTcConnect = RNIL; }//Dbtc::copyApi() void Dbtc::unlinkApiConnect(Signal* signal) @@ -5003,7 +5036,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) return; } else if (regApiPtr->tckeyrec > 0) { jam(); - sendtckeyconf(signal, 0); + sendtckeyconf(signal, 2); return; }//if }//if @@ -5991,7 +6024,9 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) /* THIS TRANSACTION HAVE EXPERIENCED A TIME-OUT AND WE NEED TO*/ /* FIND OUT WHAT WE NEED TO DO BASED ON THE STATE INFORMATION.*/ /*------------------------------------------------------------------*/ - DEBUG("Time-out in state = " << apiConnectptr.p->apiConnectstate + DEBUG("[ H'" << hex << apiConnectptr.p->transid[0] + << " H'" << apiConnectptr.p->transid[1] << "] " << dec + << "Time-out in state = " << apiConnectptr.p->apiConnectstate << " apiConnectptr.i = " << apiConnectptr.i << " - exec: " << apiConnectptr.p->m_exec_flag); switch (apiConnectptr.p->apiConnectstate) { @@ -8789,6 +8824,10 @@ void Dbtc::releaseScanResources(ScanRecordPtr scanPtr) ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty()); ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty()); + + ndbassert(scanPtr.p->scanApiRec == apiConnectptr.i); + ndbassert(apiConnectptr.p->apiScanRec == scanPtr.i); + // link into free list scanPtr.p->nextScan = cfirstfreeScanrec; scanPtr.p->scanState = ScanRecord::IDLE; @@ -8984,17 +9023,17 @@ void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode) DEBUG("scanError, errorCode = "<< errorCode << ", scanState = " << scanptr.p->scanState); + apiConnectptr.i = scanP->scanApiRec; + ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); + ndbrequire(apiConnectptr.p->apiScanRec == scanptr.i); + if(scanP->scanState == ScanRecord::CLOSING_SCAN){ jam(); close_scan_req_send_conf(signal, scanptr); return; } - + ndbrequire(scanP->scanState == ScanRecord::RUNNING); - - apiConnectptr.i = scanP->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - ndbrequire(apiConnectptr.p->apiScanRec == scanptr.i); /** * Close scan wo/ having received an order to do so @@ -9072,7 +9111,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal) close_scan_req_send_conf(signal, scanptr); return; } - + if(status == ZCLOSED && scanptr.p->scanNextFragId < scanptr.p->scanNoFrag){ /** * Start on next fragment @@ -9114,7 +9153,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal) scanFragptr.p->m_totalLen = totalLen; scanFragptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY; scanFragptr.p->stopFragTimer(); - + if(scanptr.p->m_queued_count > /** Min */ 0){ jam(); sendScanTabConf(signal, scanptr.p); @@ -9249,7 +9288,9 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal) void Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){ + ScanRecord* scanP = scanPtr.p; + ndbrequire(scanPtr.p->scanState != ScanRecord::IDLE); scanPtr.p->scanState = ScanRecord::CLOSING_SCAN; scanPtr.p->m_close_scan_req = req_received; @@ -9990,6 +10031,8 @@ void Dbtc::releaseApiCon(Signal* signal, UintR TapiConnectPtr) cfirstfreeApiConnect = TlocalApiConnectptr.i; setApiConTimer(TlocalApiConnectptr.i, 0, __LINE__); TlocalApiConnectptr.p->apiConnectstate = CS_DISCONNECTED; + ndbassert(TlocalApiConnectptr.p->apiScanRec == RNIL); + TlocalApiConnectptr.p->ndbapiBlockref = 0; }//Dbtc::releaseApiCon() void Dbtc::releaseApiConnectFail(Signal* signal) @@ -10042,12 +10085,12 @@ void Dbtc::seizeApiConnect(Signal* signal) apiConnectptr.p->nextApiConnect = RNIL; setApiConTimer(apiConnectptr.i, 0, __LINE__); apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */ + apiConnectptr.p->triggerPending = false; + apiConnectptr.p->isIndexOp = false; } else { jam(); terrorCode = ZNO_FREE_API_CONNECTION; }//if - apiConnectptr.p->triggerPending = false; - apiConnectptr.p->isIndexOp = false; }//Dbtc::seizeApiConnect() void Dbtc::seizeApiConnectFail(Signal* signal) @@ -10997,12 +11040,16 @@ void Dbtc::sendTcIndxConf(Signal* signal, UintR TcommitFlag) UintR TcurrLen = localHostptr.p->noOfWordsTCINDXCONF; UintR confInfo = 0; TcIndxConf::setNoOfOperations(confInfo, (TopWords >> 1)); - TcIndxConf::setCommitFlag(confInfo, TcommitFlag); + TcIndxConf::setCommitFlag(confInfo, TcommitFlag == 1); TcIndxConf::setMarkerFlag(confInfo, Tmarker); const UintR TpacketLen = 6 + TopWords; regApiPtr->tcindxrec = 0; - regApiPtr->m_exec_flag = 0; - + + if(TcommitFlag || (regApiPtr->lqhkeyreqrec == regApiPtr->lqhkeyconfrec)){ + jam(); + regApiPtr->m_exec_flag = 0; + } + if ((TpacketLen > 25) || !is_api){ TcIndxConf * const tcIndxConf = (TcIndxConf *)signal->getDataPtrSend(); diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index c7fe4a86fe3..6f9dbd23372 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -1296,6 +1296,10 @@ NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) theCommitStatus = Committed; theCompletionStatus = CompletedSuccess; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } return -1; }//NdbConnection::receiveTC_COMMITCONF() @@ -1317,7 +1321,12 @@ NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; }//NdbConnection::receiveTC_COMMITREF() @@ -1336,7 +1345,12 @@ NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) theCommitStatus = Aborted; theCompletionStatus = CompletedSuccess; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; }//NdbConnection::receiveTCROLLBACKCONF() @@ -1356,7 +1370,12 @@ NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; }//NdbConnection::receiveTCROLLBACKREF() @@ -1390,7 +1409,12 @@ transactions. theCompletionStatus = CompletedFailure; theCommitStatus = Aborted; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; }//NdbConnection::receiveTCROLLBACKREP() @@ -1451,7 +1475,12 @@ from other transactions. return 0; // No more operations to wait for }//if // Not completed the reception yet. - }//if + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif + } + return -1; }//NdbConnection::receiveTCKEYCONF() @@ -1505,6 +1534,10 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) }//while theReleaseOnClose = true; return 0; + } else { +#ifdef VM_TRACE + ndbout_c("Recevied TCKEY_FAILCONF wo/ operation"); +#endif } return -1; }//NdbConnection::receiveTCKEY_FAILCONF() @@ -1544,6 +1577,10 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) theReleaseOnClose = true; theCommitStatus = NdbConnection::Aborted; return 0; + } else { +#ifdef VM_TRACE + ndbout_c("Recevied TCKEY_FAILREF wo/ operation"); +#endif } return -1; }//NdbConnection::receiveTCKEY_FAILREF() @@ -1599,7 +1636,12 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, return 0; // No more operations to wait for }//if // Not completed the reception yet. - }//if + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif + } + return -1; }//NdbConnection::receiveTCINDXCONF() @@ -1628,7 +1670,12 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) theCompletionStatus = NdbConnection::CompletedFailure; theCommitStatus = NdbConnection::Aborted; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; }//NdbConnection::receiveTCINDXREF() diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp index 43b7d8eaccb..1684a0e44bd 100644 --- a/ndb/src/ndbapi/NdbConnectionScan.cpp +++ b/ndb/src/ndbapi/NdbConnectionScan.cpp @@ -69,7 +69,12 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ assert(theScanningOp->m_sent_receivers_count); theScanningOp->m_conf_receivers_count++; return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } + return -1; } @@ -120,6 +125,10 @@ NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal, } } return 0; + } else { +#ifdef NDB_NO_DROPPED_SIGNAL + abort(); +#endif } return -1; diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index e24f09fc90b..f561a641961 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -77,7 +77,7 @@ Ndb::init(int aMaxNoOfTransactions) executeMessage, statusMessage); - + if ( tBlockNo == -1 ) { theError.code = 4105; theFacade->unlock_mutex(); @@ -373,8 +373,10 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) switch(tRec->getType()){ case NdbReceiver::NDB_OPERATION: case NdbReceiver::NDB_INDEX_OPERATION: - if(tCon->OpCompleteSuccess() != -1) + if(tCon->OpCompleteSuccess() != -1){ completedTransaction(tCon); + return; + } break; case NdbReceiver::NDB_SCANRECEIVER: tCon->theScanningOp->receiver_delivered(tRec); @@ -392,26 +394,28 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) case GSN_TCKEY_FAILCONF: { tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - const TcKeyFailConf * const failConf = (TcKeyFailConf *)tDataPtr; + const TcKeyFailConf * failConf = (TcKeyFailConf *)tDataPtr; const BlockReference aTCRef = aSignal->theSendersBlockRef; - - tOp = void2rec_op(tFirstDataPtr); - - if (tOp->checkMagicNumber() == 0) { - tCon = tOp->theNdbCon; - if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { - tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf); - if (tReturnCode != -1) { - completedTransaction(tCon); + if (tFirstDataPtr != 0){ + tOp = void2rec_op(tFirstDataPtr); + + if (tOp->checkMagicNumber(false) == 0) { + tCon = tOp->theNdbCon; + if (tCon != NULL) { + if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || + (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf); + if (tReturnCode != -1) { + completedTransaction(tCon); + }//if }//if - }//if - }//if - }//if - + } + } + } else { +#ifdef VM_TRACE + ndbout_c("Recevied TCKEY_FAILCONF wo/ operation"); +#endif + } if(tFirstData & 1){ NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, failConf->transId1, @@ -423,23 +427,27 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) case GSN_TCKEY_FAILREF: { tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - tOp = void2rec_op(tFirstDataPtr); - if (tOp->checkMagicNumber() == 0) { - tCon = tOp->theNdbCon; - if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { - tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal); - if (tReturnCode != -1) { - completedTransaction(tCon); - return; - }//if - }//if - }//if - }//if - return; + if(tFirstDataPtr != 0){ + tOp = void2rec_op(tFirstDataPtr); + if (tOp->checkMagicNumber() == 0) { + tCon = tOp->theNdbCon; + if (tCon != NULL) { + if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || + (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal); + if (tReturnCode != -1) { + completedTransaction(tCon); + return; + }//if + }//if + }//if + }//if + } else { +#ifdef VM_TRACE + ndbout_c("Recevied TCKEY_FAILREF wo/ operation"); +#endif + } + break; } case GSN_TCKEYREF: { @@ -454,8 +462,9 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tReturnCode = tOp->receiveTCKEYREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); + return; }//if - return; + break; }//if }//if } //if @@ -501,7 +510,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tReturnCode = tCon->receiveTC_COMMITREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); - return; }//if }//if return; @@ -532,7 +540,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tReturnCode = tCon->receiveTCROLLBACKREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); - return; }//if }//if return; @@ -665,66 +672,66 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) case GSN_DIHNDBTAMPER: { - tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - if (tWaitState != WAIT_NDB_TAMPER) - return; - tCon = void2con(tFirstDataPtr); - if (tCon->checkMagicNumber() != 0) - return; - tReturnCode = tCon->receiveDIHNDBTAMPER(aSignal); - if (tReturnCode != -1) - theWaiter.m_state = NO_WAIT; - break; - } - case GSN_SCAN_TABCONF: - { - tFirstDataPtr = int2void(tFirstData); - assert(tFirstDataPtr); - assert(void2con(tFirstDataPtr)); - assert(void2con(tFirstDataPtr)->checkMagicNumber() == 0); - if(tFirstDataPtr && - (tCon = void2con(tFirstDataPtr)) && (tCon->checkMagicNumber() == 0)){ + tFirstDataPtr = int2void(tFirstData); + if (tFirstDataPtr == 0) goto InvalidSignal; - if(aSignal->m_noOfSections > 0){ - tReturnCode = tCon->receiveSCAN_TABCONF(aSignal, ptr[0].p, ptr[0].sz); - } else { - tReturnCode = - tCon->receiveSCAN_TABCONF(aSignal, - tDataPtr + ScanTabConf::SignalLength, - tLen - ScanTabConf::SignalLength); - } + if (tWaitState != WAIT_NDB_TAMPER) + return; + tCon = void2con(tFirstDataPtr); + if (tCon->checkMagicNumber() != 0) + return; + tReturnCode = tCon->receiveDIHNDBTAMPER(aSignal); if (tReturnCode != -1) theWaiter.m_state = NO_WAIT; break; - } else { + } + case GSN_SCAN_TABCONF: + { + tFirstDataPtr = int2void(tFirstData); + assert(tFirstDataPtr); + assert(void2con(tFirstDataPtr)); + assert(void2con(tFirstDataPtr)->checkMagicNumber() == 0); + if(tFirstDataPtr && + (tCon = void2con(tFirstDataPtr)) && (tCon->checkMagicNumber() == 0)){ + + if(aSignal->m_noOfSections > 0){ + tReturnCode = tCon->receiveSCAN_TABCONF(aSignal, ptr[0].p, ptr[0].sz); + } else { + tReturnCode = + tCon->receiveSCAN_TABCONF(aSignal, + tDataPtr + ScanTabConf::SignalLength, + tLen - ScanTabConf::SignalLength); + } + if (tReturnCode != -1) + theWaiter.m_state = NO_WAIT; + break; + } else { + goto InvalidSignal; + } + } + case GSN_SCAN_TABREF: + { + tFirstDataPtr = int2void(tFirstData); + if (tFirstDataPtr == 0) goto InvalidSignal; + + tCon = void2con(tFirstDataPtr); + + assert(tFirstDataPtr != 0 && + void2con(tFirstDataPtr)->checkMagicNumber() == 0); + + if (tCon->checkMagicNumber() == 0){ + tReturnCode = tCon->receiveSCAN_TABREF(aSignal); + if (tReturnCode != -1){ + theWaiter.m_state = NO_WAIT; + } + break; + } goto InvalidSignal; } - } - case GSN_SCAN_TABREF: - { - tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - tCon = void2con(tFirstDataPtr); - - assert(tFirstDataPtr != 0 && - void2con(tFirstDataPtr)->checkMagicNumber() == 0); - - if (tCon->checkMagicNumber() == 0){ - tReturnCode = tCon->receiveSCAN_TABREF(aSignal); - if (tReturnCode != -1){ - theWaiter.m_state = NO_WAIT; - } - break; - } - goto InvalidSignal; - } case GSN_SCAN_TABINFO: - { - goto InvalidSignal; - } + { + goto InvalidSignal; + } case GSN_KEYINFO20: { tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; @@ -777,7 +784,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) indxConf->transId2, aTCRef); } - break; + return; } case GSN_TCINDXREF:{ tFirstDataPtr = int2void(tFirstData); @@ -940,6 +947,10 @@ Ndb::check_send_timeout() WAITFOR_RESPONSE_TIMEOUT) { #ifdef VM_TRACE a_con->printState(); + Uint32 t1 = a_con->theTransactionId; + Uint32 t2 = a_con->theTransactionId >> 32; + ndbout_c("[%.8x %.8x]", t1, t2); + abort(); #endif a_con->setOperationErrorCodeAbort(4012); a_con->theCommitStatus = NdbConnection::Aborted; diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index bc59b287c11..293136b9783 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -161,6 +161,11 @@ setSignalLog(){ } return false; } +#ifdef TRACE_APIREGREQ +#define TRACE_GSN(gsn) true +#else +#define TRACE_GSN(gsn) (gsn != GSN_API_REGREQ && gsn != GSN_API_REGCONF) +#endif #endif // These symbols are needed, but not used in the API @@ -168,7 +173,7 @@ int g_sectionSegmentPool; struct ErrorReporter { void handleAssert(const char*, const char*, int); }; -void ErrorReporter::handleAssert(const char* message, const char* file, int line) {} +void ErrorReporter::handleAssert(const char*, const char*, int) {} /** * The execute function : Handle received signal @@ -183,9 +188,7 @@ execute(void * callbackObj, SignalHeader * const header, Uint32 tRecBlockNo = header->theReceiversBlockNumber; #ifdef API_TRACE - if(setSignalLog()){ - // header->theVerId_signalNumber != GSN_API_REGREQ && - // header->theVerId_signalNumber != GSN_API_REGCONF){ + if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){ signalLogger.executeSignal(* header, prio, theData, @@ -765,8 +768,7 @@ TransporterFacade::checkForceSend(Uint32 block_number) { /****************************************************************************** * SEND SIGNAL METHODS - ******************************************************************************/ - + *****************************************************************************/ int TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ Uint32* tDataPtr = aSignal->getDataPtrSend(); @@ -774,9 +776,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ Uint32 TBno = aSignal->theReceiversBlockNumber; if(getIsNodeSendable(aNode) == true){ #ifdef API_TRACE - if(setSignalLog()){ - // aSignal->theVerId_signalNumber != GSN_API_REGREQ && - // aSignal->theVerId_signalNumber != GSN_API_REGCONF){ + if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ Uint32 tmp = aSignal->theSendersBlockRef; aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); LinearSectionPtr ptr[3]; @@ -810,9 +810,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ int TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){ #ifdef API_TRACE - if(setSignalLog()){ - //aSignal->theVerId_signalNumber != GSN_API_REGREQ && - //aSignal->theVerId_signalNumber != GSN_API_REGCONF + if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ Uint32 tmp = aSignal->theSendersBlockRef; aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); LinearSectionPtr ptr[3]; @@ -842,7 +840,7 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode, aSignal->m_noOfSections = secs; if(getIsNodeSendable(aNode) == true){ #ifdef API_TRACE - if(setSignalLog()){ + if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ Uint32 tmp = aSignal->theSendersBlockRef; aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); signalLogger.sendSignal(* aSignal, @@ -878,7 +876,7 @@ TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal, aSignal->m_noOfSections = secs; #ifdef API_TRACE - if(setSignalLog()){ + if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ Uint32 tmp = aSignal->theSendersBlockRef; aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); signalLogger.sendSignal(* aSignal, diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp index 7a5d14689bc..2f47c366f4e 100644 --- a/ndb/test/include/NDBT_Test.hpp +++ b/ndb/test/include/NDBT_Test.hpp @@ -63,6 +63,8 @@ public: bool getPropertyWait(const char*, Uint32); const char* getPropertyWait(const char*, const char* ); + void decProperty(const char *); + // Communicate with other tests void stopTest(); bool isTestStopped(); diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index d93c7f6a8a0..566da7a939d 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -380,6 +380,25 @@ runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int +sync_down(NDBT_Context* ctx){ + Uint32 threads = ctx->getProperty("PauseThreads", (unsigned)0); + if(threads){ + ctx->decProperty("PauseThreads"); + } +} + +int +sync_up_and_wait(NDBT_Context* ctx){ + Uint32 threads = ctx->getProperty("Threads", (unsigned)0); + ndbout_c("Setting PauseThreads to %d", threads); + ctx->setProperty("PauseThreads", threads); + ctx->getPropertyWait("PauseThreads", (unsigned)0); + if(threads){ + ndbout_c("wait completed"); + } +} + int runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ // Verify that data in index match @@ -394,10 +413,17 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); + if(ctx->isTestStopped()) + break; + if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); } return NDBT_OK; } @@ -418,7 +444,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif - + sync_down(ctx); if(ctx->isTestStopped()) break; #if 1 @@ -427,6 +453,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif + sync_down(ctx); } return NDBT_OK; } @@ -447,6 +474,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Load table failed" << endl; return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -454,7 +482,8 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } - + + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -463,6 +492,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -471,6 +501,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -479,6 +510,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -486,12 +518,15 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Clear table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); if(ctx->isTestStopped()) break; - + int count = -1; if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) return NDBT_FAILED; + sync_down(ctx); } return NDBT_OK; } @@ -510,6 +545,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ result = NDBT_FAILED; break; } + sync_up_and_wait(ctx); i++; } ctx->stopTest(); @@ -1259,6 +1295,7 @@ TESTCASE("CreateLoadDrop_O", TESTCASE("NFNR1", "Test that indexes are correctly maintained during node fail and node restart"){ TC_PROPERTY("LoggedIndexes", (unsigned)0); + //TC_PROPERTY("Threads", 2); INITIALIZER(runClearTable); INITIALIZER(createRandomIndex); INITIALIZER(runLoadTable); diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index 4cd2c96486b..af4e3ff3550 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -132,6 +132,17 @@ void NDBT_Context::setProperty(const char* _name, Uint32 _val){ assert(b == true); NdbMutex_Unlock(propertyMutexPtr); } +void +NDBT_Context::decProperty(const char * name){ + NdbMutex_Lock(propertyMutexPtr); + Uint32 val = 0; + if(props.get(name, &val)){ + assert(val > 0); + props.put(name, (val - 1), true); + } + NdbCondition_Broadcast(propertyCondPtr); + NdbMutex_Unlock(propertyMutexPtr); +} void NDBT_Context::setProperty(const char* _name, const char* _val){ NdbMutex_Lock(propertyMutexPtr); @@ -994,6 +1005,7 @@ int NDBT_TestSuite::execute(int argc, const char** argv){ res = executeAll(_testname); } else { testSuiteTimer.doStart(); + Ndb ndb("TEST_DB"); ndb.init(); for(int i = optind; i