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