Commit e80d95a7 authored by unknown's avatar unknown

ndb - bug#21384

  handle error in TCKEYREQ during TCINDXREQ better


ndb/src/kernel/blocks/ERROR_codes.txt:
  new error code
ndb/src/kernel/blocks/dbtc/Dbtc.hpp:
  Add 3 values to isIndexOp
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  handle error in TCKEYREQ during TCINDXREQ
ndb/test/ndbapi/testIndex.cpp:
  Add testcase
ndb/test/run-test/daily-basic-tests.txt:
  Add testcase
parent 31e3e753
......@@ -6,7 +6,7 @@ Next DBTUP 4013
Next DBLQH 5043
Next DBDICT 6006
Next DBDIH 7174
Next DBTC 8037
Next DBTC 8038
Next CMVMI 9000
Next BACKUP 10022
Next DBUTIL 11002
......@@ -281,6 +281,7 @@ ABORT OF TCKEYREQ
8032: No free TC records any more
8037 : Invalid schema version in TCINDXREQ
CMVMI
-----
......
......@@ -718,7 +718,7 @@ public:
// Index data
bool isIndexOp; // Used to mark on-going TcKeyReq as indx table access
Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access
bool indexOpReturn;
UintR noIndexOp; // No outstanding index ops
......@@ -806,7 +806,7 @@ public:
UintR savedState[LqhKeyConf::SignalLength];
// Index data
bool isIndexOp; // Used to mark on-going TcKeyReq as index table access
Uint8 isIndexOp; // Used to mark on-going TcKeyReq as index table access
UintR indexOp;
UintR currentIndexId;
UintR attrInfoLen;
......
......@@ -1757,8 +1757,7 @@ void Dbtc::execKEYINFO(Signal* signal)
apiConnectptr.i = signal->theData[0];
tmaxData = 20;
if (apiConnectptr.i >= capiConnectFilesize) {
jam();
warningHandlerLab(signal);
TCKEY_abort(signal, 18);
return;
}//if
ptrAss(apiConnectptr, apiConnectRecord);
......@@ -1767,9 +1766,7 @@ void Dbtc::execKEYINFO(Signal* signal)
compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
compare_transid1 = compare_transid1 | compare_transid2;
if (compare_transid1 != 0) {
jam();
printState(signal, 10);
sendSignalErrorRefuseLab(signal);
TCKEY_abort(signal, 19);
return;
}//if
switch (apiConnectptr.p->apiConnectstate) {
......@@ -2467,7 +2464,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo);
Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
bool isIndexOp = regApiPtr->isIndexOp;
Uint8 isIndexOp = regApiPtr->isIndexOp;
bool isIndexOpReturn = regApiPtr->indexOpReturn;
regApiPtr->isIndexOp = false; // Reset marker
regApiPtr->m_exec_flag |= TexecFlag;
......@@ -3210,7 +3207,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16);
sig2 = regApiPtr->transid[0];
sig3 = regApiPtr->transid[1];
sig4 = regApiPtr->ndbapiBlockref;
sig4 = (regTcPtr->isIndexOp == 2) ? reference() : regApiPtr->ndbapiBlockref;
sig5 = regTcPtr->clientData;
sig6 = regCachePtr->scanInfo;
......@@ -8551,6 +8548,7 @@ void Dbtc::execSCAN_TABREQ(Signal* signal)
// left over from simple/dirty read
} else {
jam();
jamLine(transP->apiConnectstate);
errCode = ZSTATE_ERROR;
goto SCAN_TAB_error_no_state_change;
}
......@@ -11915,13 +11913,17 @@ void Dbtc::readIndexTable(Signal* signal,
opType == ZREAD ? ZREAD : ZREAD_EX);
TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo
TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0);
BlockReference originalReceiver = regApiPtr->ndbapiBlockref;
regApiPtr->ndbapiBlockref = reference(); // Send result to me
tcKeyReq->senderData = indexOp->indexOpId;
indexOp->indexOpState = IOS_INDEX_ACCESS;
regApiPtr->executingIndexOp = regApiPtr->accumulatingIndexOp;
regApiPtr->accumulatingIndexOp = RNIL;
regApiPtr->isIndexOp = true;
regApiPtr->isIndexOp = 2;
if (ERROR_INSERTED(8037))
{
ndbout_c("shifting index version");
tcKeyReq->tableSchemaVersion = ~(Uint32)indexOp->tcIndxReq.indexSchemaVersion;
}
Uint32 remainingKey = indexOp->keyInfo.getSize();
bool moreKeyData = indexOp->keyInfo.first(keyIter);
......@@ -11941,21 +11943,13 @@ void Dbtc::readIndexTable(Signal* signal,
ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0);
ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0);
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
jamEntry();
/**
* "Fool" TC not to start commiting transaction since it always will
* have one outstanding lqhkeyreq
* This is later decreased when the index read is complete
*/
regApiPtr->lqhkeyreqrec++;
/**
* Remember ptr to index read operation
* (used to set correct save point id on index operation later)
*/
indexOp->indexReadTcConnect = regApiPtr->lastTcConnect;
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
goto err;
}
jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
jam();
......@@ -11975,6 +11969,10 @@ void Dbtc::readIndexTable(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
goto err;
}
dataPos = 0;
dataPtr = (Uint32 *) &keyInfo->keyData;
}
......@@ -11985,10 +11983,32 @@ void Dbtc::readIndexTable(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
goto err;
}
}
}
regApiPtr->ndbapiBlockref = originalReceiver; // reset original receiver
/**
* "Fool" TC not to start commiting transaction since it always will
* have one outstanding lqhkeyreq
* This is later decreased when the index read is complete
*/
regApiPtr->lqhkeyreqrec++;
/**
* Remember ptr to index read operation
* (used to set correct save point id on index operation later)
*/
indexOp->indexReadTcConnect = regApiPtr->lastTcConnect;
done:
return;
err:
jam();
goto done;
}
/**
......@@ -12039,7 +12059,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
tcKeyReq->transId2 = regApiPtr->transid[1];
tcKeyReq->senderData = tcIndxReq->senderData; // Needed for TRANSID_AI to API
indexOp->indexOpState = IOS_INDEX_OPERATION;
regApiPtr->isIndexOp = true;
regApiPtr->isIndexOp = 1;
regApiPtr->executingIndexOp = indexOp->indexOpId;;
regApiPtr->noIndexOp++; // Increase count
......@@ -12112,9 +12132,16 @@ void Dbtc::executeIndexOperation(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = tmp.p->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
regApiPtr->currSavePointId = currSavePointId;
jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
jam();
......@@ -12135,6 +12162,13 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPos = 0;
dataPtr = (Uint32 *) &keyInfo->keyData;
}
......@@ -12145,6 +12179,12 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
}
}
......@@ -12174,6 +12214,13 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
attrInfoPos = 0;
dataPtr = (Uint32 *) &attrInfo->attrData;
}
......@@ -12573,9 +12620,16 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = opRecord->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
regApiPtr->currSavePointId = currSavePointId;
tcConnectptr.p->currentIndexId = indexData->indexId;
jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
......@@ -12605,6 +12659,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
......@@ -12640,6 +12700,13 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
......@@ -12657,6 +12724,11 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
}
}
......@@ -12692,6 +12764,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &attrInfo->attrData;
attrInfoPos = 0;
}
......@@ -12728,6 +12806,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &attrInfo->attrData;
attrInfoPos = 0;
}
......@@ -12873,9 +12957,16 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = opRecord->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
jamEntry();
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
regApiPtr->currSavePointId = currSavePointId;
tcConnectptr.p->currentIndexId = indexData->indexId;
jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
......@@ -12906,6 +12997,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
......@@ -12942,6 +13039,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
{
jam();
return;
}
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
......
......@@ -1201,6 +1201,48 @@ int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
int
runBug21384(NDBT_Context* ctx, NDBT_Step* step)
{
Ndb* pNdb = GETNDB(step);
HugoTransactions hugoTrans(*ctx->getTab());
NdbRestarter restarter;
int loops = ctx->getNumLoops();
const int rows = ctx->getNumRecords();
const int batchsize = ctx->getProperty("BatchSize", 50);
while (loops--)
{
if(restarter.insertErrorInAllNodes(8037) != 0)
{
g_err << "Failed to error insert(8037)" << endl;
return NDBT_FAILED;
}
if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) == 0)
{
g_err << "Index succeded (it should have failed" << endl;
return NDBT_FAILED;
}
if(restarter.insertErrorInAllNodes(0) != 0)
{
g_err << "Failed to error insert(0)" << endl;
return NDBT_FAILED;
}
if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) != 0){
g_err << "Index read failed" << endl;
return NDBT_FAILED;
}
}
return NDBT_OK;
}
NDBT_TESTSUITE(testIndex);
TESTCASE("CreateAll",
"Test that we can create all various indexes on each table\n"
......@@ -1507,6 +1549,16 @@ TESTCASE("UniqueNull",
FINALIZER(createPkIndex_Drop);
FINALIZER(runClearTable);
}
TESTCASE("Bug21384",
"Test that unique indexes and nulls"){
TC_PROPERTY("LoggedIndexes", (unsigned)0);
INITIALIZER(runClearTable);
INITIALIZER(createPkIndex);
INITIALIZER(runLoadTable);
STEP(runBug21384);
FINALIZER(createPkIndex_Drop);
FINALIZER(runClearTable);
}
NDBT_TESTSUITE_END(testIndex);
int main(int argc, const char** argv){
......
......@@ -474,6 +474,10 @@ max-time: 1000
cmd: testNodeRestart
args: -n Bug20185 T1
max-time: 1000
cmd: testIndex
args: -n Bug21384
# OLD FLEX
max-time: 500
cmd: flexBench
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment