diff options
author | unknown <jonas@perch.ndb.mysql.com> | 2007-10-15 11:35:30 +0200 |
---|---|---|
committer | unknown <jonas@perch.ndb.mysql.com> | 2007-10-15 11:35:30 +0200 |
commit | e8c4a6ba9f430dc4494c4869258321bebb02db04 (patch) | |
tree | 83e16ccbed21555836321df43655565e97a5582e /storage | |
parent | ffef8fc610b47428cbbd41437b7eedca69488ea3 (diff) | |
parent | 67b31b0fdbcd6c38cf4185ff50c4f735e1cd1eb7 (diff) | |
download | mariadb-git-e8c4a6ba9f430dc4494c4869258321bebb02db04.tar.gz |
Merge perch.ndb.mysql.com:/home/jonas/src/51-simple-read
into perch.ndb.mysql.com:/home/jonas/src/51-ndb
storage/ndb/include/ndbapi/NdbOperation.hpp:
Auto merged
Diffstat (limited to 'storage')
-rw-r--r-- | storage/ndb/include/kernel/signaldata/TcKeyConf.hpp | 2 | ||||
-rw-r--r-- | storage/ndb/include/ndbapi/NdbOperation.hpp | 3 | ||||
-rw-r--r-- | storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp | 4 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 1 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 76 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp | 12 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 199 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbBlob.cpp | 2 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbIndexOperation.cpp | 3 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbOperationDefine.cpp | 62 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbOperationExec.cpp | 17 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbReceiver.cpp | 2 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbScanOperation.cpp | 1 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbTransaction.cpp | 6 | ||||
-rw-r--r-- | storage/ndb/test/ndbapi/testBasic.cpp | 35 | ||||
-rw-r--r-- | storage/ndb/test/run-test/daily-basic-tests.txt | 8 | ||||
-rw-r--r-- | storage/ndb/test/src/HugoOperations.cpp | 1 |
17 files changed, 236 insertions, 198 deletions
diff --git a/storage/ndb/include/kernel/signaldata/TcKeyConf.hpp b/storage/ndb/include/kernel/signaldata/TcKeyConf.hpp index b8562875ef5..fd8932c3c87 100644 --- a/storage/ndb/include/kernel/signaldata/TcKeyConf.hpp +++ b/storage/ndb/include/kernel/signaldata/TcKeyConf.hpp @@ -46,7 +46,7 @@ public: */ STATIC_CONST( StaticLength = 5 ); STATIC_CONST( OperationLength = 2 ); - STATIC_CONST( SimpleReadBit = (((Uint32)1) << 31) ); + STATIC_CONST( DirtyReadBit = (((Uint32)1) << 31) ); private: diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp index 2f899d5b4bd..78dbadfd7ab 100644 --- a/storage/ndb/include/ndbapi/NdbOperation.hpp +++ b/storage/ndb/include/ndbapi/NdbOperation.hpp @@ -93,8 +93,9 @@ public: ,LM_CommittedRead ///< Ignore locks, read last committed value #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL = 2, - LM_Dirty = 2 + LM_Dirty = 2, #endif + LM_SimpleRead = 3 ///< Read with shared lock, but release lock directly }; /** diff --git a/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp b/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp index 65589f8cd6e..377863f9446 100644 --- a/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp +++ b/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp @@ -51,11 +51,11 @@ printTCKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receive (TcKeyConf::getMarkerFlag(confInfo) == 0)?"false":"true"); fprintf(output, "Operations:\n"); for(i = 0; i < noOfOp; i++) { - if(sig->operations[i].attrInfoLen > TcKeyConf::SimpleReadBit) + if(sig->operations[i].attrInfoLen > TcKeyConf::DirtyReadBit) fprintf(output, " apiOperationPtr: H'%.8x, simplereadnode: %u\n", sig->operations[i].apiOperationPtr, - sig->operations[i].attrInfoLen & (~TcKeyConf::SimpleReadBit)); + sig->operations[i].attrInfoLen & (~TcKeyConf::DirtyReadBit)); else fprintf(output, " apiOperationPtr: H'%.8x, attrInfoLen: %u\n", diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 6f8e5569831..1bed25fb5a8 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2025,7 +2025,6 @@ public: Uint8 reclenAiLqhkey; Uint8 m_offset_current_keybuf; Uint8 replicaType; - Uint8 simpleRead; Uint8 seqNoReplica; Uint8 tcNodeFailrec; Uint8 m_disk_table; diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 43d49e791be..f511e00afaa 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -3496,7 +3496,6 @@ void Dblqh::execLQHKEYREQ(Signal* signal) regTcPtr->dirtyOp = LqhKeyReq::getDirtyFlag(Treqinfo); regTcPtr->opExec = LqhKeyReq::getInterpretedFlag(Treqinfo); regTcPtr->opSimple = LqhKeyReq::getSimpleFlag(Treqinfo); - regTcPtr->simpleRead = op == ZREAD && regTcPtr->opSimple; regTcPtr->seqNoReplica = LqhKeyReq::getSeqNoReplica(Treqinfo); UintR TreclenAiLqhkey = LqhKeyReq::getAIInLqhKeyReq(Treqinfo); regTcPtr->apiVersionNo = 0; @@ -3513,9 +3512,15 @@ void Dblqh::execLQHKEYREQ(Signal* signal) regTcPtr->lockType = op == ZREAD_EX ? ZUPDATE : (Operation_t) op == ZWRITE ? ZINSERT : (Operation_t) op; } + + if (regTcPtr->dirtyOp) + { + ndbrequire(regTcPtr->opSimple); + } - CRASH_INSERTION2(5041, regTcPtr->simpleRead && - refToNode(signal->senderBlockRef()) != cownNodeid); + CRASH_INSERTION2(5041, (op == ZREAD && + (regTcPtr->opSimple || regTcPtr->dirtyOp) && + refToNode(signal->senderBlockRef()) != cownNodeid)); regTcPtr->reclenAiLqhkey = TreclenAiLqhkey; regTcPtr->currReclenAi = TreclenAiLqhkey; @@ -3687,8 +3692,8 @@ void Dblqh::execLQHKEYREQ(Signal* signal) Uint8 TdistKey = LqhKeyReq::getDistributionKey(TtotReclenAi); if ((tfragDistKey != TdistKey) && (regTcPtr->seqNoReplica == 0) && - (regTcPtr->dirtyOp == ZFALSE) && - (regTcPtr->simpleRead == ZFALSE)) { + (regTcPtr->dirtyOp == ZFALSE)) + { /* ---------------------------------------------------------------------- * WE HAVE DIFFERENT OPINION THAN THE DIH THAT STARTED THE TRANSACTION. * THE REASON COULD BE THAT THIS IS AN OLD DISTRIBUTION WHICH IS NO LONGER @@ -4778,7 +4783,18 @@ void Dblqh::tupkeyConfLab(Signal* signal) TRACE_OP(regTcPtr, "TUPKEYCONF"); - if (regTcPtr->simpleRead) { + if (readLen != 0) + { + jam(); + + /* SET BIT 15 IN REQINFO */ + LqhKeyReq::setApplicationAddressFlag(regTcPtr->reqinfo, 1); + regTcPtr->readlenAi = readLen; + }//if + + if (regTcPtr->operation == ZREAD && + (regTcPtr->opSimple || regTcPtr->dirtyOp)) + { jam(); /* ---------------------------------------------------------------------- * THE OPERATION IS A SIMPLE READ. @@ -4792,14 +4808,6 @@ void Dblqh::tupkeyConfLab(Signal* signal) commitContinueAfterBlockedLab(signal); return; }//if - if (readLen != 0) - { - jam(); - - /* SET BIT 15 IN REQINFO */ - LqhKeyReq::setApplicationAddressFlag(regTcPtr->reqinfo, 1); - regTcPtr->readlenAi = readLen; - }//if regTcPtr->totSendlenAi = writeLen; ndbrequire(regTcPtr->totSendlenAi == regTcPtr->currTupAiLen); @@ -5178,12 +5186,15 @@ void Dblqh::packLqhkeyreqLab(Signal* signal) /* */ /* ------------------------------------------------------------------------- */ sendLqhkeyconfTc(signal, regTcPtr->tcBlockref); - if (regTcPtr->dirtyOp != ZTRUE) { + if (! (regTcPtr->dirtyOp || + (regTcPtr->operation == ZREAD && regTcPtr->opSimple))) + { jam(); regTcPtr->transactionState = TcConnectionrec::PREPARED; releaseOprec(signal); } else { jam(); + /*************************************************************>*/ /* DIRTY WRITES ARE USED IN TWO SITUATIONS. THE FIRST */ /* SITUATION IS WHEN THEY ARE USED TO UPDATE COUNTERS AND*/ @@ -6406,8 +6417,8 @@ void Dblqh::commitContinueAfterBlockedLab(Signal* signal) Ptr<TcConnectionrec> regTcPtr = tcConnectptr; Ptr<Fragrecord> regFragptr = fragptr; Uint32 operation = regTcPtr.p->operation; - Uint32 simpleRead = regTcPtr.p->simpleRead; Uint32 dirtyOp = regTcPtr.p->dirtyOp; + Uint32 opSimple = regTcPtr.p->opSimple; if (regTcPtr.p->activeCreat != Fragrecord::AC_IGNORED) { if (operation != ZREAD) { TupCommitReq * const tupCommitReq = @@ -6465,20 +6476,29 @@ void Dblqh::commitContinueAfterBlockedLab(Signal* signal) EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1); } - if (simpleRead) { + if (dirtyOp) + { jam(); -/* ------------------------------------------------------------------------- */ -/*THE OPERATION WAS A SIMPLE READ THUS THE COMMIT PHASE IS ONLY NEEDED TO */ -/*RELEASE THE LOCKS. AT THIS POINT IN THE CODE THE LOCKS ARE RELEASED AND WE */ -/*ARE IN A POSITION TO SEND LQHKEYCONF TO TC. WE WILL ALSO RELEASE ALL */ -/*RESOURCES BELONGING TO THIS OPERATION SINCE NO MORE WORK WILL BE */ -/*PERFORMED. */ -/* ------------------------------------------------------------------------- */ + /** + * The dirtyRead does not send anything but TRANSID_AI from LDM + */ fragptr = regFragptr; tcConnectptr = regTcPtr; cleanUp(signal); return; - }//if + } + + /** + * The simpleRead will send a LQHKEYCONF + * but have already released the locks + */ + if (opSimple) + { + fragptr = regFragptr; + tcConnectptr = regTcPtr; + packLqhkeyreqLab(signal); + return; + } } }//if jamEntry(); @@ -7088,7 +7108,7 @@ void Dblqh::abortStateHandlerLab(Signal* signal) /* ------------------------------------------------------------------------- */ return; }//if - if (regTcPtr->simpleRead) { + if (regTcPtr->opSimple) { jam(); /* ------------------------------------------------------------------------- */ /*A SIMPLE READ IS CURRENTLY RELEASING THE LOCKS OR WAITING FOR ACCESS TO */ @@ -7356,7 +7376,8 @@ void Dblqh::continueAbortLab(Signal* signal) void Dblqh::continueAfterLogAbortWriteLab(Signal* signal) { TcConnectionrec * const regTcPtr = tcConnectptr.p; - if (regTcPtr->simpleRead) { + if (regTcPtr->operation == ZREAD && regTcPtr->dirtyOp) + { jam(); TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend(); @@ -19027,7 +19048,6 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) ndbout << " operation = " << tcRec.p->operation<<endl; ndbout << " tcNodeFailrec = " << tcRec.p->tcNodeFailrec << " seqNoReplica = " << tcRec.p->seqNoReplica - << " simpleRead = " << tcRec.p->simpleRead << endl; ndbout << " replicaType = " << tcRec.p->replicaType << " reclenAiLqhkey = " << tcRec.p->reclenAiLqhkey diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index 75d79ba737f..3d5e52a525d 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -786,6 +786,7 @@ public: UintR apiConnect; /* POINTER TO API CONNECT RECORD */ UintR nextTcConnect; /* NEXT TC RECORD*/ Uint8 dirtyOp; + Uint8 opSimple; Uint8 lastReplicaNo; /* NUMBER OF THE LAST REPLICA IN THE OPERATION */ Uint8 noOfNodes; /* TOTAL NUMBER OF NODES IN OPERATION */ Uint8 operation; /* OPERATION TYPE */ @@ -886,13 +887,8 @@ public: Uint8 opExec; Uint8 unused; + Uint8 unused1; - /** - * IS THE OPERATION A SIMPLE TRANSACTION - * 0 = NO, 1 = YES - */ - Uint8 opSimple; - //--------------------------------------------------- // Second 16 byte cache line in second 64 byte cache // line. Diverse use. @@ -1464,7 +1460,7 @@ private: void releaseAttrinfo(); void releaseGcp(Signal* signal); void releaseKeys(); - void releaseSimpleRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*); + void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*); void releaseDirtyWrite(Signal* signal); void releaseTcCon(); void releaseTcConnectFail(Signal* signal); @@ -1620,7 +1616,7 @@ private: void startphase1x010Lab(Signal* signal); void lqhKeyConf_checkTransactionState(Signal * signal, - ApiConnectRecord * const regApiPtr); + Ptr<ApiConnectRecord> regApiPtr); void checkDropTab(Signal* signal); diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 31f6a4eec08..ce20059e663 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -2791,9 +2791,9 @@ void Dbtc::execTCKEYREQ(Signal* signal) Uint8 TNoDiskFlag = TcKeyReq::getNoDiskFlag(Treqinfo); Uint8 TexecuteFlag = TexecFlag; - regCachePtr->opSimple = TSimpleFlag; - regCachePtr->opExec = TInterpretedFlag; regTcPtr->dirtyOp = TDirtyFlag; + regTcPtr->opSimple = TSimpleFlag; + regCachePtr->opExec = TInterpretedFlag; regCachePtr->distributionKeyIndicator = TDistrKeyFlag; regCachePtr->m_no_disk_flag = TNoDiskFlag; @@ -3247,9 +3247,10 @@ void Dbtc::sendlqhkeyreq(Signal* signal, LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd); Tdata10 = 0; - sig0 = regCachePtr->opSimple; + sig0 = regTcPtr->opSimple; sig1 = regTcPtr->operation; - bool simpleRead = (sig1 == ZREAD && sig0 == ZTRUE); + sig2 = regTcPtr->dirtyOp; + bool dirtyRead = (sig1 == ZREAD && sig2 == ZTRUE); LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen); LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo); if (unlikely(version < NDBD_ROWID_VERSION)) @@ -3262,7 +3263,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal, // Indicate Application Reference is present in bit 15 /* ---------------------------------------------------------------------- */ LqhKeyReq::setApplicationAddressFlag(Tdata10, 1); - LqhKeyReq::setDirtyFlag(Tdata10, regTcPtr->dirtyOp); + LqhKeyReq::setDirtyFlag(Tdata10, sig2); LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec); LqhKeyReq::setSimpleFlag(Tdata10, sig0); LqhKeyReq::setOperation(Tdata10, sig1); @@ -3323,7 +3324,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal, sig5 = regTcPtr->clientData; sig6 = regCachePtr->scanInfo; - if (! simpleRead) + if (! dirtyRead) { regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[0]); regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[1]); @@ -3396,7 +3397,6 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, BlockReference TBRef) { TcConnectRecord * const regTcPtr = tcConnectptr.p; - CacheRecord * const regCachePtr = cachePtr.p; #ifdef ERROR_INSERT ApiConnectRecord * const regApiPtr = apiConnectptr.p; if (ERROR_INSERTED(8009)) { @@ -3421,8 +3421,8 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, if (anAttrBufIndex == RNIL) { UintR TtcTimer = ctcTimer; UintR Tread = (regTcPtr->operation == ZREAD); - UintR Tsimple = (regCachePtr->opSimple == ZTRUE); - UintR Tboth = Tread & Tsimple; + UintR Tdirty = (regTcPtr->dirtyOp == ZTRUE); + UintR Tboth = Tread & Tdirty; setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__); jam(); /*-------------------------------------------------------------------- @@ -3431,7 +3431,7 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, releaseAttrinfo(); if (Tboth) { jam(); - releaseSimpleRead(signal, apiConnectptr, tcConnectptr.p); + releaseDirtyRead(signal, apiConnectptr, tcConnectptr.p); return; }//if regTcPtr->tcConnectstate = OS_OPERATING; @@ -3491,11 +3491,11 @@ void Dbtc::releaseAttrinfo() }//Dbtc::releaseAttrinfo() /* ========================================================================= */ -/* ------- RELEASE ALL RECORDS CONNECTED TO A SIMPLE OPERATION ------- */ +/* ------- RELEASE ALL RECORDS CONNECTED TO A DIRTY OPERATION ------- */ /* ========================================================================= */ -void Dbtc::releaseSimpleRead(Signal* signal, - ApiConnectRecordPtr regApiPtr, - TcConnectRecord* regTcPtr) +void Dbtc::releaseDirtyRead(Signal* signal, + ApiConnectRecordPtr regApiPtr, + TcConnectRecord* regTcPtr) { Uint32 Ttckeyrec = regApiPtr.p->tckeyrec; Uint32 TclientData = regTcPtr->clientData; @@ -3505,7 +3505,7 @@ void Dbtc::releaseSimpleRead(Signal* signal, ConnectionState state = regApiPtr.p->apiConnectstate; regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData; - regApiPtr.p->tcSendArray[Ttckeyrec + 1] = TcKeyConf::SimpleReadBit | Tnode; + regApiPtr.p->tcSendArray[Ttckeyrec + 1] = TcKeyConf::DirtyReadBit | Tnode; regApiPtr.p->tckeyrec = Ttckeyrec + 2; unlinkReadyTcCon(signal); @@ -3535,8 +3535,8 @@ void Dbtc::releaseSimpleRead(Signal* signal, /** * Emulate LQHKEYCONF */ - lqhKeyConf_checkTransactionState(signal, regApiPtr.p); -}//Dbtc::releaseSimpleRead() + lqhKeyConf_checkTransactionState(signal, regApiPtr); +}//Dbtc::releaseDirtyRead() /* ------------------------------------------------------------------------- */ /* ------- CHECK IF ALL TC CONNECTIONS ARE COMPLETED ------- */ @@ -3718,12 +3718,13 @@ void Dbtc::execLQHKEYCONF(Signal* signal) TCKEY_abort(signal, 29); return; }//if - ApiConnectRecord * const regApiPtr = - &localApiConnectRecord[TapiConnectptrIndex]; + Ptr<ApiConnectRecord> regApiPtr; + regApiPtr.i = TapiConnectptrIndex; + regApiPtr.p = &localApiConnectRecord[TapiConnectptrIndex]; apiConnectptr.i = TapiConnectptrIndex; - apiConnectptr.p = regApiPtr; - compare_transid1 = regApiPtr->transid[0] ^ Ttrans1; - compare_transid2 = regApiPtr->transid[1] ^ Ttrans2; + apiConnectptr.p = regApiPtr.p; + compare_transid1 = regApiPtr.p->transid[0] ^ Ttrans1; + compare_transid2 = regApiPtr.p->transid[1] ^ Ttrans2; compare_transid1 = compare_transid1 | compare_transid2; if (compare_transid1 != 0) { warningReport(signal, 24); @@ -3735,25 +3736,25 @@ void Dbtc::execLQHKEYCONF(Signal* signal) systemErrorLab(signal, __LINE__); }//if if (ERROR_INSERTED(8003)) { - if (regApiPtr->apiConnectstate == CS_STARTED) { + if (regApiPtr.p->apiConnectstate == CS_STARTED) { CLEAR_ERROR_INSERT_VALUE; return; }//if }//if if (ERROR_INSERTED(8004)) { - if (regApiPtr->apiConnectstate == CS_RECEIVING) { + if (regApiPtr.p->apiConnectstate == CS_RECEIVING) { CLEAR_ERROR_INSERT_VALUE; return; }//if }//if if (ERROR_INSERTED(8005)) { - if (regApiPtr->apiConnectstate == CS_REC_COMMITTING) { + if (regApiPtr.p->apiConnectstate == CS_REC_COMMITTING) { CLEAR_ERROR_INSERT_VALUE; return; }//if }//if if (ERROR_INSERTED(8006)) { - if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { + if (regApiPtr.p->apiConnectstate == CS_START_COMMITTING) { CLEAR_ERROR_INSERT_VALUE; return; }//if @@ -3768,10 +3769,12 @@ void Dbtc::execLQHKEYCONF(Signal* signal) regTcPtr->lastLqhNodeId = refToNode(tlastLqhBlockref); regTcPtr->noFiredTriggers = noFired; - UintR Ttckeyrec = (UintR)regApiPtr->tckeyrec; + UintR Ttckeyrec = (UintR)regApiPtr.p->tckeyrec; UintR TclientData = regTcPtr->clientData; UintR TdirtyOp = regTcPtr->dirtyOp; - ConnectionState TapiConnectstate = regApiPtr->apiConnectstate; + Uint32 TopSimple = regTcPtr->opSimple; + Uint32 Toperation = regTcPtr->operation; + ConnectionState TapiConnectstate = regApiPtr.p->apiConnectstate; if (Ttckeyrec > (ZTCOPCONF_SIZE - 2)) { TCKEY_abort(signal, 30); return; @@ -3796,23 +3799,34 @@ void Dbtc::execLQHKEYCONF(Signal* signal) * since they will enter execLQHKEYCONF a second time * Skip counting internally generated TcKeyReq */ - regApiPtr->tcSendArray[Ttckeyrec] = TclientData; - regApiPtr->tcSendArray[Ttckeyrec + 1] = treadlenAi; - regApiPtr->tckeyrec = Ttckeyrec + 2; + regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData; + regApiPtr.p->tcSendArray[Ttckeyrec + 1] = treadlenAi; + regApiPtr.p->tckeyrec = Ttckeyrec + 2; }//if }//if - if (TdirtyOp == ZTRUE) { - UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec; + if (TdirtyOp == ZTRUE) + { + UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec; jam(); releaseDirtyWrite(signal); - regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec - 1; - } else { + regApiPtr.p->lqhkeyreqrec = Tlqhkeyreqrec - 1; + } + else if (Toperation == ZREAD && TopSimple) + { + UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec; + jam(); + unlinkReadyTcCon(signal); + releaseTcCon(); + regApiPtr.p->lqhkeyreqrec = Tlqhkeyreqrec - 1; + } + else + { jam(); if (noFired == 0) { jam(); // No triggers to execute - UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec; - regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec + 1; + UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec; + regApiPtr.p->lqhkeyconfrec = Tlqhkeyconfrec + 1; regTcPtr->tcConnectstate = OS_PREPARED; } }//if @@ -3842,21 +3856,18 @@ void Dbtc::execLQHKEYCONF(Signal* signal) jam(); if (regTcPtr->isIndexOp) { jam(); - setupIndexOpReturn(regApiPtr, regTcPtr); + setupIndexOpReturn(regApiPtr.p, regTcPtr); } lqhKeyConf_checkTransactionState(signal, regApiPtr); } else { // We have fired triggers jam(); saveTriggeringOpState(signal, regTcPtr); - if (regTcPtr->noReceivedTriggers == noFired) { - ApiConnectRecordPtr transPtr; - + if (regTcPtr->noReceivedTriggers == noFired) + { // We have received all data jam(); - transPtr.i = TapiConnectptrIndex; - transPtr.p = regApiPtr; - executeTriggers(signal, &transPtr); + executeTriggers(signal, ®ApiPtr); } // else wait for more trigger data } @@ -3880,7 +3891,7 @@ void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr, */ void Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, - ApiConnectRecord * const apiConnectPtrP) + Ptr<ApiConnectRecord> regApiPtr) { /*---------------------------------------------------------------*/ /* IF THE COMMIT FLAG IS SET IN SIGNAL TCKEYREQ THEN DBTC HAS TO */ @@ -3891,9 +3902,9 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, /* FOR ALL OPERATIONS, AND THEN WAIT FOR THE API TO CONCLUDE THE */ /* TRANSACTION */ /*---------------------------------------------------------------*/ - ConnectionState TapiConnectstate = apiConnectPtrP->apiConnectstate; - UintR Tlqhkeyconfrec = apiConnectPtrP->lqhkeyconfrec; - UintR Tlqhkeyreqrec = apiConnectPtrP->lqhkeyreqrec; + ConnectionState TapiConnectstate = regApiPtr.p->apiConnectstate; + UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec; + UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec; int TnoOfOutStanding = Tlqhkeyreqrec - Tlqhkeyconfrec; switch (TapiConnectstate) { @@ -3903,11 +3914,11 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, diverify010Lab(signal); return; } else if (TnoOfOutStanding > 0) { - if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) { + if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) { jam(); sendtckeyconf(signal, 0); return; - } else if (apiConnectPtrP->indexOpReturn) { + } else if (regApiPtr.p->indexOpReturn) { jam(); sendtckeyconf(signal, 0); return; @@ -3926,11 +3937,11 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, sendtckeyconf(signal, 2); return; } else { - if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) { + if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) { jam(); sendtckeyconf(signal, 0); return; - } else if (apiConnectPtrP->indexOpReturn) { + } else if (regApiPtr.p->indexOpReturn) { jam(); sendtckeyconf(signal, 0); return; @@ -3940,11 +3951,11 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, return; case CS_REC_COMMITTING: if (TnoOfOutStanding > 0) { - if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) { + if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) { jam(); sendtckeyconf(signal, 0); return; - } else if (apiConnectPtrP->indexOpReturn) { + } else if (regApiPtr.p->indexOpReturn) { jam(); sendtckeyconf(signal, 0); return; @@ -3961,7 +3972,7 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, /* CONSISTING OF DIRTY WRITES AND ALL OF THOSE WERE */ /* COMPLETED. ENSURE TCKEYREC IS ZERO TO PREVENT ERRORS. */ /*---------------------------------------------------------------*/ - apiConnectPtrP->tckeyrec = 0; + regApiPtr.p->tckeyrec = 0; return; default: TCKEY_abort(signal, 46); @@ -4219,34 +4230,46 @@ void Dbtc::diverify010Lab(Signal* signal) jam(); systemErrorLab(signal, __LINE__); }//if - if (TfirstfreeApiConnectCopy != RNIL) { - seizeApiConnectCopy(signal); - regApiPtr->apiConnectstate = CS_PREPARE_TO_COMMIT; - /*----------------------------------------------------------------------- - * WE COME HERE ONLY IF THE TRANSACTION IS PREPARED ON ALL TC CONNECTIONS. - * THUS WE CAN START THE COMMIT PHASE BY SENDING DIVERIFY ON ALL TC - * CONNECTIONS AND THEN WHEN ALL DIVERIFYCONF HAVE BEEN RECEIVED THE - * COMMIT MESSAGE CAN BE SENT TO ALL INVOLVED PARTS. - *-----------------------------------------------------------------------*/ - EXECUTE_DIRECT(DBDIH, GSN_DIVERIFYREQ, signal, 1); - if (signal->theData[2] == 0) { - execDIVERIFYCONF(signal); + + if (regApiPtr->lqhkeyreqrec) + { + if (TfirstfreeApiConnectCopy != RNIL) { + seizeApiConnectCopy(signal); + regApiPtr->apiConnectstate = CS_PREPARE_TO_COMMIT; + /*----------------------------------------------------------------------- + * WE COME HERE ONLY IF THE TRANSACTION IS PREPARED ON ALL TC CONNECTIONS + * THUS WE CAN START THE COMMIT PHASE BY SENDING DIVERIFY ON ALL TC + * CONNECTIONS AND THEN WHEN ALL DIVERIFYCONF HAVE BEEN RECEIVED THE + * COMMIT MESSAGE CAN BE SENT TO ALL INVOLVED PARTS. + *---------------------------------------------------------------------*/ + EXECUTE_DIRECT(DBDIH, GSN_DIVERIFYREQ, signal, 1); + if (signal->theData[2] == 0) { + execDIVERIFYCONF(signal); + } + return; + } else { + /*----------------------------------------------------------------------- + * There were no free copy connections available. We must abort the + * transaction since otherwise we will have a problem with the report + * to the application. + * This should more or less not happen but if it happens we do + * not want to crash and we do not want to create code to handle it + * properly since it is difficult to test it and will be complex to + * handle a problem more or less not occurring. + *---------------------------------------------------------------------*/ + terrorCode = ZSEIZE_API_COPY_ERROR; + abortErrorLab(signal); + return; } - return; - } else { - /*----------------------------------------------------------------------- - * There were no free copy connections available. We must abort the - * transaction since otherwise we will have a problem with the report - * to the application. - * This should more or less not happen but if it happens we do not want to - * crash and we do not want to create code to handle it properly since - * it is difficult to test it and will be complex to handle a problem - * more or less not occurring. - *-----------------------------------------------------------------------*/ - terrorCode = ZSEIZE_API_COPY_ERROR; - abortErrorLab(signal); - return; - }//if + } + else + { + jam(); + sendtckeyconf(signal, 1); + regApiPtr->apiConnectstate = CS_CONNECTED; + regApiPtr->m_transaction_nodes.clear(); + setApiConTimer(apiConnectptr.i, 0,__LINE__); + } }//Dbtc::diverify010Lab() /* ------------------------------------------------------------------------- */ @@ -5261,16 +5284,8 @@ void Dbtc::execLQHKEYREF(Signal* signal) regApiPtr->lqhkeyreqrec--; if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) { if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { - if(regApiPtr->lqhkeyconfrec) { - jam(); - diverify010Lab(signal); - } else { - jam(); - sendtckeyconf(signal, 1); - regApiPtr->apiConnectstate = CS_CONNECTED; - regApiPtr->m_transaction_nodes.clear(); - setApiConTimer(apiConnectptr.i, 0,__LINE__); - } + jam(); + diverify010Lab(signal); return; } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) { jam(); diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp index 0fc96add084..f3d1dbe3dd1 100644 --- a/storage/ndb/src/ndbapi/NdbBlob.cpp +++ b/storage/ndb/src/ndbapi/NdbBlob.cpp @@ -1141,7 +1141,7 @@ NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count) * table tuple does not fully protect blob parts since DBTUP * commits each tuple separately. */ - tOp->readTuple() == -1 || + tOp->readTuple(NdbOperation::LM_SimpleRead) == -1 || setPartKeyValue(tOp, part + n) == -1 || tOp->getValue((Uint32)3, buf) == NULL) { setErrorCode(tOp); diff --git a/storage/ndb/src/ndbapi/NdbIndexOperation.cpp b/storage/ndb/src/ndbapi/NdbIndexOperation.cpp index fc19bd251d4..921769f09e3 100644 --- a/storage/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -85,6 +85,9 @@ int NdbIndexOperation::readTuple(NdbOperation::LockMode lm) case LM_CommittedRead: return readTuple(); break; + case LM_SimpleRead: + return readTuple(); + break; default: return -1; }; diff --git a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp index c9459ff911c..73778ab9bbe 100644 --- a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -131,6 +131,8 @@ NdbOperation::readTuple(NdbOperation::LockMode lm) case LM_CommittedRead: return committedRead(); break; + case LM_SimpleRead: + return simpleRead(); default: return -1; }; @@ -185,24 +187,22 @@ NdbOperation::readTupleExclusive() int NdbOperation::simpleRead() { - /** - * Currently/still disabled - */ - return readTuple(); -#if 0 + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; theOperationType = ReadRequest; theSimpleIndicator = 1; + theDirtyIndicator = 0; theErrorLine = tErrorLine++; - theLockMode = LM_Read; + theLockMode = LM_SimpleRead; + m_abortOption = AO_IgnoreError; + tNdbCon->theSimpleState = 0; return 0; } else { setErrorCode(4200); return -1; }//if -#endif }//NdbOperation::simpleRead() /***************************************************************************** @@ -338,28 +338,32 @@ NdbOperation::setReadLockMode(LockMode lockMode) { /* We only support changing lock mode for read operations at this time. */ assert(theOperationType == ReadRequest || theOperationType == ReadExclusive); - switch (lockMode) - { - case LM_CommittedRead: - theOperationType= ReadRequest; - theSimpleIndicator= 1; - theDirtyIndicator= 1; - break; - case LM_Read: - theNdbCon->theSimpleState= 0; - theOperationType= ReadRequest; - theSimpleIndicator= 0; - theDirtyIndicator= 0; - break; - case LM_Exclusive: - theNdbCon->theSimpleState= 0; - theOperationType= ReadExclusive; - theSimpleIndicator= 0; - theDirtyIndicator= 0; - break; - default: - /* Not supported / invalid. */ - assert(false); + switch (lockMode) { + case LM_CommittedRead: /* TODO, check theNdbCon->theSimpleState */ + theOperationType= ReadRequest; + theSimpleIndicator= 1; + theDirtyIndicator= 1; + break; + case LM_SimpleRead: /* TODO, check theNdbCon->theSimpleState */ + theOperationType= ReadRequest; + theSimpleIndicator= 1; + theDirtyIndicator= 0; + break; + case LM_Read: + theNdbCon->theSimpleState= 0; + theOperationType= ReadRequest; + theSimpleIndicator= 0; + theDirtyIndicator= 0; + break; + case LM_Exclusive: + theNdbCon->theSimpleState= 0; + theOperationType= ReadExclusive; + theSimpleIndicator= 0; + theDirtyIndicator= 0; + break; + default: + /* Not supported / invalid. */ + assert(false); } theLockMode= lockMode; } diff --git a/storage/ndb/src/ndbapi/NdbOperationExec.cpp b/storage/ndb/src/ndbapi/NdbOperationExec.cpp index 9fe85265a0c..27672e0458c 100644 --- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp @@ -175,12 +175,11 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint8 tInterpretIndicator = theInterpretIndicator; Uint8 tNoDisk = m_no_disk_flag; -//------------------------------------------------------------- -// Simple state is set if start and commit is set and it is -// a read request. Otherwise it is set to zero. -//------------------------------------------------------------- + /** + * A dirty read, can not abort the transaction + */ Uint8 tReadInd = (theOperationType == ReadRequest); - Uint8 tSimpleState = tReadInd & tSimpleIndicator; + Uint8 tDirtyState = tReadInd & tDirtyIndicator; tcKeyReq->transId1 = tTransId1; tcKeyReq->transId2 = tTransId2; @@ -206,8 +205,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, tcKeyReq->setOperationType(tReqInfo, tOperationType); tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen); - // A simple read is always ignore error - abortOption = tSimpleState ? (Uint8) AO_IgnoreError : (Uint8) abortOption; + // A dirty read is always ignore error + abortOption = tDirtyState ? (Uint8) AO_IgnoreError : (Uint8) abortOption; tcKeyReq->setAbortOption(tReqInfo, abortOption); m_abortOption = abortOption; @@ -549,8 +548,8 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) theStatus = Finished; theReceiver.m_received_result_length = ~0; - // not simple read - if(! (theOperationType == ReadRequest && theSimpleIndicator)) + // not dirty read + if(! (theOperationType == ReadRequest && theDirtyIndicator)) { theNdbCon->OpCompleteFailure(this); return -1; diff --git a/storage/ndb/src/ndbapi/NdbReceiver.cpp b/storage/ndb/src/ndbapi/NdbReceiver.cpp index 34b3a14ac6e..5a311bcbefe 100644 --- a/storage/ndb/src/ndbapi/NdbReceiver.cpp +++ b/storage/ndb/src/ndbapi/NdbReceiver.cpp @@ -283,7 +283,7 @@ NdbReceiver::execTRANSID_AI(const Uint32* aDataPtr, Uint32 aLength) Uint32 tmp = m_received_result_length + aLength; m_received_result_length = tmp; - return (tmp == exp || (exp > TcKeyConf::SimpleReadBit) ? 1 : 0); + return (tmp == exp || (exp > TcKeyConf::DirtyReadBit) ? 1 : 0); } int diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp index 055fbf28339..afbec070ac8 100644 --- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp @@ -237,6 +237,7 @@ NdbScanOperation::setReadLockMode(LockMode lockMode) lockHoldMode= false; readCommitted= true; break; + case LM_SimpleRead: case LM_Read: lockExcl= false; lockHoldMode= true; diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp index 55c6f0f4b99..bc59df722aa 100644 --- a/storage/ndb/src/ndbapi/NdbTransaction.cpp +++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp @@ -1787,8 +1787,8 @@ from other transactions. const Uint32 tAttrInfoLen = *tPtr++; if (tOp && tOp->checkMagicNumber()) { Uint32 done = tOp->execTCOPCONF(tAttrInfoLen); - if(tAttrInfoLen > TcKeyConf::SimpleReadBit){ - Uint32 node = tAttrInfoLen & (~TcKeyConf::SimpleReadBit); + if(tAttrInfoLen > TcKeyConf::DirtyReadBit){ + Uint32 node = tAttrInfoLen & (~TcKeyConf::DirtyReadBit); NdbNodeBitmask::set(m_db_nodes, node); if(NdbNodeBitmask::get(m_failed_db_nodes, node) && !done) { @@ -2182,7 +2182,7 @@ NdbTransaction::report_node_failure(Uint32 id){ * 4) X X */ NdbOperation* tmp = theFirstExecOpInList; - const Uint32 len = TcKeyConf::SimpleReadBit | id; + const Uint32 len = TcKeyConf::DirtyReadBit | id; Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; Uint32 count = 0; diff --git a/storage/ndb/test/ndbapi/testBasic.cpp b/storage/ndb/test/ndbapi/testBasic.cpp index 952b5a50dc5..ac23ceaad18 100644 --- a/storage/ndb/test/ndbapi/testBasic.cpp +++ b/storage/ndb/test/ndbapi/testBasic.cpp @@ -136,31 +136,13 @@ int runPkRead(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); int batchSize = ctx->getProperty("BatchSize", 1); + int lm = ctx->getProperty("LockMode", NdbOperation::LM_Read); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); while (i<loops) { g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize) != NDBT_OK){ - g_info << endl; - return NDBT_FAILED; - } - i++; - } - g_info << endl; - return NDBT_OK; -} - -int runPkDirtyRead(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - bool dirty = true; - HugoTransactions hugoTrans(*ctx->getTab()); - while (i<loops) { - g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize, - NdbOperation::LM_CommittedRead) != NDBT_OK){ + if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize, + (NdbOperation::LockMode)lm) != NDBT_OK){ g_info << endl; return NDBT_FAILED; } @@ -1552,14 +1534,23 @@ TESTCASE("PkInsert", } TESTCASE("PkRead", "Verify that we can insert, read and delete from this table using PK"){ + TC_PROPERTY("LockMode", NdbOperation::LM_Read); INITIALIZER(runLoadTable); STEP(runPkRead); FINALIZER(runClearTable); } TESTCASE("PkDirtyRead", "Verify that we can insert, dirty read and delete from this table using PK"){ + TC_PROPERTY("LockMode", NdbOperation::LM_Dirty); INITIALIZER(runLoadTable); - STEP(runPkDirtyRead); + STEP(runPkRead); + FINALIZER(runClearTable); +} +TESTCASE("PkSimpleRead", + "Verify that we can insert, simple read and delete from this table using PK"){ + TC_PROPERTY("LockMode", NdbOperation::LM_SimpleRead); + INITIALIZER(runLoadTable); + STEP(runPkRead); FINALIZER(runClearTable); } TESTCASE("PkUpdate", diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt index 0ca81b7f63b..450a9996101 100644 --- a/storage/ndb/test/run-test/daily-basic-tests.txt +++ b/storage/ndb/test/run-test/daily-basic-tests.txt @@ -65,6 +65,14 @@ args: -n PkRead max-time: 500 cmd: testBasic +args: -n PkSimpleRead + +max-time: 500 +cmd: testBasic +args: -n PkDirtyRead + +max-time: 500 +cmd: testBasic args: -n PkUpdate max-time: 500 diff --git a/storage/ndb/test/src/HugoOperations.cpp b/storage/ndb/test/src/HugoOperations.cpp index 1a2e5180f1f..93a9eaf435a 100644 --- a/storage/ndb/test/src/HugoOperations.cpp +++ b/storage/ndb/test/src/HugoOperations.cpp @@ -93,6 +93,7 @@ rand_lock_mode: case NdbOperation::LM_Read: case NdbOperation::LM_Exclusive: case NdbOperation::LM_CommittedRead: + case NdbOperation::LM_SimpleRead: if(idx && idx->getType() == NdbDictionary::Index::OrderedIndex && pIndexScanOp == 0) { |