Commit 44e30660 authored by unknown's avatar unknown

wl1801 - Support for handling NF during dirty read


ndb/include/ndbapi/NdbConnection.hpp:
  Support for handling NF during dirty read
ndb/include/ndbapi/NdbReceiver.hpp:
  Support for handling NF during dirty read
ndb/src/ndbapi/NdbConnection.cpp:
  Support for handling NF during dirty read
ndb/src/ndbapi/NdbReceiver.cpp:
  Support for handling NF during dirty read
ndb/src/ndbapi/Ndbif.cpp:
  Support for handling NF during dirty read
ndb/src/ndbapi/ndberror.c:
  Support for handling NF during dirty read
ndb/test/ndbapi/testNodeRestart.cpp:
  Support for handling NF during dirty read
parent 9c6255b4
...@@ -658,6 +658,8 @@ private: ...@@ -658,6 +658,8 @@ private:
Uint32 m_db_nodes[2]; Uint32 m_db_nodes[2];
Uint32 m_failed_db_nodes[2]; Uint32 m_failed_db_nodes[2];
int report_node_failure(Uint32 id);
// Scan operations // Scan operations
bool m_waitForReply; bool m_waitForReply;
NdbIndexScanOperation* m_theFirstScanOperation; NdbIndexScanOperation* m_theFirstScanOperation;
......
...@@ -60,6 +60,7 @@ public: ...@@ -60,6 +60,7 @@ public:
inline void next(NdbReceiver* next) { m_next = next;} inline void next(NdbReceiver* next) { m_next = next;}
inline NdbReceiver* next() { return m_next; } inline NdbReceiver* next() { return m_next; }
void setErrorCode(int);
private: private:
Uint32 theMagicNumber; Uint32 theMagicNumber;
Ndb* m_ndb; Ndb* m_ndb;
......
...@@ -1537,16 +1537,20 @@ from other transactions. ...@@ -1537,16 +1537,20 @@ from other transactions.
const Uint32* tPtr = (Uint32 *)&keyConf->operations[0]; const Uint32* tPtr = (Uint32 *)&keyConf->operations[0];
Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoComp = theNoOfOpCompleted;
for (Uint32 i = 0; i < tNoOfOperations ; i++) { for (Uint32 i = 0; i < tNoOfOperations ; i++) {
tOp = theNdb->void2rec(theNdb->int2void(*tPtr)); tOp = theNdb->void2rec(theNdb->int2void(*tPtr++));
tPtr++; const Uint32 tAttrInfoLen = *tPtr++;
const Uint32 tAttrInfoLen = *tPtr;
tPtr++;
if (tOp && tOp->checkMagicNumber()) { if (tOp && tOp->checkMagicNumber()) {
tNoComp += tOp->execTCOPCONF(tAttrInfoLen); Uint32 done = tOp->execTCOPCONF(tAttrInfoLen);
if(tAttrInfoLen > TcKeyConf::SimpleReadBit){ if(tAttrInfoLen > TcKeyConf::SimpleReadBit){
NdbNodeBitmask::set(m_db_nodes, Uint32 node = tAttrInfoLen & (~TcKeyConf::SimpleReadBit);
tAttrInfoLen & (~TcKeyConf::SimpleReadBit)); NdbNodeBitmask::set(m_db_nodes, node);
if(NdbNodeBitmask::get(m_failed_db_nodes, node) && !done)
{
done = 1;
tOp->setErrorCode(4119);
}
} }
tNoComp += done;
} else { } else {
return -1; return -1;
}//if }//if
...@@ -1960,3 +1964,43 @@ NdbConnection::printState() ...@@ -1960,3 +1964,43 @@ NdbConnection::printState()
} }
#undef CASE #undef CASE
#endif #endif
int
NdbConnection::report_node_failure(Uint32 id){
NdbNodeBitmask::set(m_failed_db_nodes, id);
if(!NdbNodeBitmask::get(m_db_nodes, id))
{
return 0;
}
/**
* Arrived
* TCKEYCONF TRANSIDAI
* 1) - -
* 2) - X
* 3) X -
* 4) X X
*/
NdbOperation* tmp = theFirstExecOpInList;
const Uint32 len = TcKeyConf::SimpleReadBit | id;
Uint32 tNoComp = theNoOfOpCompleted;
Uint32 tNoSent = theNoOfOpSent;
while(tmp != 0)
{
if(tmp->theReceiver.m_expected_result_length == len &&
tmp->theReceiver.m_received_result_length == 0)
{
tNoComp++;
tmp->theError.code = 4119;
}
tmp = tmp->next();
}
theNoOfOpCompleted = tNoComp;
if(tNoComp == tNoSent)
{
theError.code = 4119;
theCompletionStatus = NdbConnection::CompletedFailure;
return 1;
}
return 0;
}
...@@ -274,3 +274,11 @@ NdbReceiver::execKEYINFO20(Uint32 info, const Uint32* aDataPtr, Uint32 aLength) ...@@ -274,3 +274,11 @@ NdbReceiver::execKEYINFO20(Uint32 info, const Uint32* aDataPtr, Uint32 aLength)
return (tmp == m_expected_result_length ? 1 : 0); return (tmp == m_expected_result_length ? 1 : 0);
} }
void
NdbReceiver::setErrorCode(int code)
{
theMagicNumber = 0;
NdbOperation* op = (NdbOperation*)getOwner();
op->setErrorCode(code);
}
...@@ -249,6 +249,7 @@ Ndb::report_node_failure(Uint32 node_id) ...@@ -249,6 +249,7 @@ Ndb::report_node_failure(Uint32 node_id)
*/ */
the_release_ind[node_id] = 1; the_release_ind[node_id] = 1;
theWaiter.nodeFail(node_id); theWaiter.nodeFail(node_id);
return;
}//Ndb::report_node_failure() }//Ndb::report_node_failure()
...@@ -271,9 +272,10 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) ...@@ -271,9 +272,10 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
Uint32 tNoSentTransactions = theNoOfSentTransactions; Uint32 tNoSentTransactions = theNoOfSentTransactions;
for (int i = tNoSentTransactions - 1; i >= 0; i--) { for (int i = tNoSentTransactions - 1; i >= 0; i--) {
NdbConnection* localCon = theSentTransactionsArray[i]; NdbConnection* localCon = theSentTransactionsArray[i];
if (localCon->getConnectedNodeId() == aNodeId ) { if (localCon->getConnectedNodeId() == aNodeId) {
const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus; const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus;
if (sendStatus == NdbConnection::sendTC_OP || sendStatus == NdbConnection::sendTC_COMMIT) { if (sendStatus == NdbConnection::sendTC_OP ||
sendStatus == NdbConnection::sendTC_COMMIT) {
/* /*
A transaction was interrupted in the prepare phase by a node A transaction was interrupted in the prepare phase by a node
failure. Since the transaction was not found in the phase failure. Since the transaction was not found in the phase
...@@ -293,7 +295,7 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) ...@@ -293,7 +295,7 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
printState("abortTransactionsAfterNodeFailure %x", this); printState("abortTransactionsAfterNodeFailure %x", this);
abort(); abort();
#endif #endif
}// }
/* /*
All transactions arriving here have no connection to the kernel All transactions arriving here have no connection to the kernel
intact since the node was failing and they were aborted. Thus we intact since the node was failing and they were aborted. Thus we
...@@ -302,7 +304,11 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) ...@@ -302,7 +304,11 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
localCon->theCommitStatus = NdbConnection::Aborted; localCon->theCommitStatus = NdbConnection::Aborted;
localCon->theReleaseOnClose = true; localCon->theReleaseOnClose = true;
completedTransaction(localCon); completedTransaction(localCon);
}//if }
else if(localCon->report_node_failure(aNodeId));
{
completedTransaction(localCon);
}
}//for }//for
return; return;
}//Ndb::abortTransactionsAfterNodeFailure() }//Ndb::abortTransactionsAfterNodeFailure()
......
...@@ -92,9 +92,10 @@ ErrorBundle ErrorCodes[] = { ...@@ -92,9 +92,10 @@ ErrorBundle ErrorCodes[] = {
{ 4031, NR, "Node failure caused abort of transaction" }, { 4031, NR, "Node failure caused abort of transaction" },
{ 4033, NR, "Send to NDB failed" }, { 4033, NR, "Send to NDB failed" },
{ 4115, NR, { 4115, NR,
"Transaction was committed but all read information was not " "Transaction was committed but all read information was not "
"received due to node crash" }, "received due to node crash" },
{ 4119, NR, "Simple/dirty read failed due to node failure" },
/** /**
* Node shutdown * Node shutdown
*/ */
......
...@@ -299,9 +299,11 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -299,9 +299,11 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){ int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK; int result = NDBT_OK;
int loops = ctx->getNumLoops(); int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
NdbRestarter restarter; NdbRestarter restarter;
HugoTransactions hugoTrans(*ctx->getTab()); HugoOperations hugoOps(*ctx->getTab());
Ndb* pNdb = GETNDB(step);
int i = 0; int i = 0;
while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){ while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
g_info << i << ": "; g_info << i << ": ";
...@@ -312,14 +314,34 @@ int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -312,14 +314,34 @@ int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){
restarter.insertErrorInNode(nodeId, 5041); restarter.insertErrorInNode(nodeId, 5041);
restarter.insertErrorInAllNodes(8048); restarter.insertErrorInAllNodes(8048);
if (hugoTrans.pkReadRecords(GETNDB(step), 1, 1, for(int j = 0; j<records; j++){
NdbOperation::LM_CommittedRead) != 0) if(hugoOps.startTransaction(pNdb) != 0)
{ return NDBT_FAILED;
return NDBT_FAILED;
if(hugoOps.pkReadRecord(pNdb, j, 1, NdbOperation::LM_CommittedRead) != 0)
goto err;
int res;
if((res = hugoOps.execute_Commit(pNdb)) == 4119)
goto done;
if(res != 0)
goto err;
if(hugoOps.closeTransaction(pNdb) != 0)
return NDBT_FAILED;
} }
done:
if(hugoOps.closeTransaction(pNdb) != 0)
return NDBT_FAILED;
i++; i++;
restarter.waitClusterStarted(60) ;
} }
return result; return result;
err:
hugoOps.closeTransaction(pNdb);
return NDBT_FAILED;
} }
NDBT_TESTSUITE(testNodeRestart); NDBT_TESTSUITE(testNodeRestart);
......
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