1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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
This commit is contained in:
unknown
2004-10-11 09:20:04 +02:00
parent 9c6255b4eb
commit 44e30660df
7 changed files with 104 additions and 20 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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()
} }
#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;
}

View File

@ -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);
}

View File

@ -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)
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)
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)
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()

View File

@ -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
*/ */

View File

@ -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){
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);