summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2004-10-11 09:20:04 +0200
committerunknown <joreland@mysql.com>2004-10-11 09:20:04 +0200
commit44e30660dff0cfd300c9e1c2ac127bee06151dd9 (patch)
tree7b5ad106dfec7389788e92964209c0a04419bf46 /ndb
parent9c6255b4eb4a29f170e975c18fdee0adbda00d0d (diff)
downloadmariadb-git-44e30660dff0cfd300c9e1c2ac127bee06151dd9.tar.gz
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
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/ndbapi/NdbConnection.hpp2
-rw-r--r--ndb/include/ndbapi/NdbReceiver.hpp1
-rw-r--r--ndb/src/ndbapi/NdbConnection.cpp58
-rw-r--r--ndb/src/ndbapi/NdbReceiver.cpp8
-rw-r--r--ndb/src/ndbapi/Ndbif.cpp14
-rw-r--r--ndb/src/ndbapi/ndberror.c7
-rw-r--r--ndb/test/ndbapi/testNodeRestart.cpp34
7 files changed, 104 insertions, 20 deletions
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index 53ebffb69f3..92b940e96f7 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -658,6 +658,8 @@ private:
Uint32 m_db_nodes[2];
Uint32 m_failed_db_nodes[2];
+ int report_node_failure(Uint32 id);
+
// Scan operations
bool m_waitForReply;
NdbIndexScanOperation* m_theFirstScanOperation;
diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp
index e08e349b4fd..6f577380728 100644
--- a/ndb/include/ndbapi/NdbReceiver.hpp
+++ b/ndb/include/ndbapi/NdbReceiver.hpp
@@ -60,6 +60,7 @@ public:
inline void next(NdbReceiver* next) { m_next = next;}
inline NdbReceiver* next() { return m_next; }
+ void setErrorCode(int);
private:
Uint32 theMagicNumber;
Ndb* m_ndb;
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index c6a88e10f54..082526059d0 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -1537,16 +1537,20 @@ from other transactions.
const Uint32* tPtr = (Uint32 *)&keyConf->operations[0];
Uint32 tNoComp = theNoOfOpCompleted;
for (Uint32 i = 0; i < tNoOfOperations ; i++) {
- tOp = theNdb->void2rec(theNdb->int2void(*tPtr));
- tPtr++;
- const Uint32 tAttrInfoLen = *tPtr;
- tPtr++;
+ tOp = theNdb->void2rec(theNdb->int2void(*tPtr++));
+ const Uint32 tAttrInfoLen = *tPtr++;
if (tOp && tOp->checkMagicNumber()) {
- tNoComp += tOp->execTCOPCONF(tAttrInfoLen);
+ Uint32 done = tOp->execTCOPCONF(tAttrInfoLen);
if(tAttrInfoLen > TcKeyConf::SimpleReadBit){
- NdbNodeBitmask::set(m_db_nodes,
- tAttrInfoLen & (~TcKeyConf::SimpleReadBit));
+ Uint32 node = 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 {
return -1;
}//if
@@ -1960,3 +1964,43 @@ NdbConnection::printState()
}
#undef CASE
#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;
+}
diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp
index 6208b842371..3a1ea9c10d1 100644
--- a/ndb/src/ndbapi/NdbReceiver.cpp
+++ b/ndb/src/ndbapi/NdbReceiver.cpp
@@ -274,3 +274,11 @@ NdbReceiver::execKEYINFO20(Uint32 info, const Uint32* aDataPtr, Uint32 aLength)
return (tmp == m_expected_result_length ? 1 : 0);
}
+
+void
+NdbReceiver::setErrorCode(int code)
+{
+ theMagicNumber = 0;
+ NdbOperation* op = (NdbOperation*)getOwner();
+ op->setErrorCode(code);
+}
diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp
index 5c91467f2e5..3d80041ab4f 100644
--- a/ndb/src/ndbapi/Ndbif.cpp
+++ b/ndb/src/ndbapi/Ndbif.cpp
@@ -249,6 +249,7 @@ Ndb::report_node_failure(Uint32 node_id)
*/
the_release_ind[node_id] = 1;
theWaiter.nodeFail(node_id);
+ return;
}//Ndb::report_node_failure()
@@ -271,9 +272,10 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
Uint32 tNoSentTransactions = theNoOfSentTransactions;
for (int i = tNoSentTransactions - 1; i >= 0; i--) {
NdbConnection* localCon = theSentTransactionsArray[i];
- if (localCon->getConnectedNodeId() == aNodeId ) {
+ if (localCon->getConnectedNodeId() == aNodeId) {
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
failure. Since the transaction was not found in the phase
@@ -293,7 +295,7 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
printState("abortTransactionsAfterNodeFailure %x", this);
abort();
#endif
- }//
+ }
/*
All transactions arriving here have no connection to the kernel
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->theReleaseOnClose = true;
completedTransaction(localCon);
- }//if
+ }
+ else if(localCon->report_node_failure(aNodeId));
+ {
+ completedTransaction(localCon);
+ }
}//for
return;
}//Ndb::abortTransactionsAfterNodeFailure()
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index fdfd8a15fb0..d93a96c86c0 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -92,9 +92,10 @@ ErrorBundle ErrorCodes[] = {
{ 4031, NR, "Node failure caused abort of transaction" },
{ 4033, NR, "Send to NDB failed" },
{ 4115, NR,
- "Transaction was committed but all read information was not "
- "received due to node crash" },
-
+ "Transaction was committed but all read information was not "
+ "received due to node crash" },
+ { 4119, NR, "Simple/dirty read failed due to node failure" },
+
/**
* Node shutdown
*/
diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp
index 0ba0d170984..fd841e6ede5 100644
--- a/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/ndb/test/ndbapi/testNodeRestart.cpp
@@ -299,9 +299,11 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
NdbRestarter restarter;
- HugoTransactions hugoTrans(*ctx->getTab());
-
+ HugoOperations hugoOps(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
int i = 0;
while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
g_info << i << ": ";
@@ -312,14 +314,34 @@ int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){
restarter.insertErrorInNode(nodeId, 5041);
restarter.insertErrorInAllNodes(8048);
- if (hugoTrans.pkReadRecords(GETNDB(step), 1, 1,
- NdbOperation::LM_CommittedRead) != 0)
- {
- return NDBT_FAILED;
+ for(int j = 0; j<records; j++){
+ if(hugoOps.startTransaction(pNdb) != 0)
+ 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++;
+ restarter.waitClusterStarted(60) ;
}
return result;
+err:
+ hugoOps.closeTransaction(pNdb);
+ return NDBT_FAILED;
}
NDBT_TESTSUITE(testNodeRestart);