#At file:///home/jonas/src/telco-6.3/
2659 jonas@stripped 2008-08-11 [merge]
ndb -
merge bug#30780 to 6.3
modified:
storage/ndb/src/kernel/blocks/ERROR_codes.txt
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
storage/ndb/src/kernel/vm/SimulatedBlock.cpp
storage/ndb/src/kernel/vm/pc.hpp
storage/ndb/test/ndbapi/test_event.cpp
storage/ndb/test/run-test/daily-basic-tests.txt
=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2008-05-30 08:09:43 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2008-08-11 11:24:12 +0000
@@ -5,7 +5,7 @@ Next DBACC 3002
Next DBTUP 4029
Next DBLQH 5051
Next DBDICT 6008
-Next DBDIH 7211
+Next DBDIH 7215
Next DBTC 8064
Next CMVMI 9000
Next BACKUP 10041
@@ -182,6 +182,9 @@ And crash when all have "not" been sent
7191: Crash when receiving LCP_COMPLETE_REP
7192: Crash in setLcpActiveStatusStart - when dead node missed to LCP's
+7213: in GCP_COMMIT Kill specified node and self, stop processing
+7214: in GCP_TCFINISHED kill specified node
+
ERROR CODES FOR TESTING NODE FAILURE, FAILURE IN COPY FRAGMENT PROCESS:
-----------------------------------------------------------------------
=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2008-06-09 14:31:19 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2008-08-11 11:24:12 +0000
@@ -5181,6 +5181,21 @@ void Dbdih::execMASTER_GCPREQ(Signal* si
case MicroGcp::M_GCP_COMMITTED:
jam();
gcpState = MasterGCPConf::GCP_COMMITTED;
+
+ /**
+ * Change state to GCP_COMMIT_RECEIVEDn and rerun GSN_GCP_NOMORETRANS
+ */
+ gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
+ m_micro_gcp.m_state = MicroGcp::M_GCP_COMMIT;
+
+ {
+ GCPNoMoreTrans* req2 = (GCPNoMoreTrans*)signal->getDataPtrSend();
+ req2->senderData = m_micro_gcp.m_master_ref;
+ req2->gci_hi = m_micro_gcp.m_old_gci >> 32;
+ req2->gci_lo = m_micro_gcp.m_old_gci & 0xFFFFFFFF;
+ sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal,
+ GCPNoMoreTrans::SignalLength, JBB);
+ }
break;
};
@@ -8429,6 +8444,28 @@ void Dbdih::execGCP_COMMIT(Signal* signa
}
Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
+#ifdef ERROR_INSERT
+ if (ERROR_INSERTED(7213))
+ {
+ ndbout_c("err 7213 killing %d", c_error_insert_extra);
+ Uint32 save = signal->theData[0];
+ signal->theData[0] = 5048;
+ sendSignal(numberToRef(DBLQH, c_error_insert_extra),
+ GSN_NDB_TAMPER, signal, 1, JBB);
+ signal->theData[0] = save;
+ CLEAR_ERROR_INSERT_VALUE;
+
+ signal->theData[0] = 9999;
+ sendSignal(numberToRef(CMVMI, c_error_insert_extra),
+ GSN_DUMP_STATE_ORD, signal, 1, JBB);
+
+ signal->theData[0] = save;
+ CLEAR_ERROR_INSERT_VALUE;
+
+ return;
+ }
+#endif
+
Uint32 masterRef = calcDihBlockRef(masterNodeId);
ndbrequire(masterNodeId = cmasterNodeId);
if (isMaster())
@@ -8507,6 +8544,19 @@ void Dbdih::execGCP_TCFINISHED(Signal* s
return;
}
+#ifdef ERROR_INSERT
+ if (ERROR_INSERTED(7214))
+ {
+ ndbout_c("err 7214 killing %d", c_error_insert_extra);
+ Uint32 save = signal->theData[0];
+ signal->theData[0] = 9999;
+ sendSignal(numberToRef(CMVMI, c_error_insert_extra),
+ GSN_NDB_TAMPER, signal, 1, JBB);
+ signal->theData[0] = save;
+ CLEAR_ERROR_INSERT_VALUE;
+ }
+#endif
+
#ifdef GCP_TIMER_HACK
NdbTick_getMicroTimer(&globalData.gcp_timer_commit[1]);
#endif
@@ -15155,7 +15205,6 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
if (signal->theData[0] == 7901)
globalData.gcp_timer_limit = signal->theData[1];
#endif
-
if (arg == 7023)
{
/**
@@ -15193,6 +15242,18 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
signal->theData[0] = arg;
signal->theData[1] = ptr.i;
}
+
+ DECLARE_DUMP0(DBDIH, 7213, "Set error 7213 with extra arg")
+ {
+ SET_ERROR_INSERT_VALUE2(7213, signal->theData[1]);
+ return;
+ }
+
+ DECLARE_DUMP0(DBDIH, 7214, "Set error 7214 with extra arg")
+ {
+ SET_ERROR_INSERT_VALUE2(7214, signal->theData[1]);
+ return;
+ }
}//Dbdih::execDUMP_STATE_ORD()
void
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-07-23 11:25:03 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-08-11 11:24:12 +0000
@@ -6162,9 +6162,8 @@ void Dblqh::execCOMPLETE(Signal* signal)
errorReport(signal, 1);
return;
}//if
- if (ERROR_INSERTED(5042)) {
- ndbrequire(false);
- }
+ CRASH_INSERTION(5042);
+
if (ERROR_INSERTED(5013)) {
CLEAR_ERROR_INSERT_VALUE;
sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
=== modified file 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2008-03-27 21:38:55 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2008-08-11 11:24:12 +0000
@@ -1437,10 +1437,10 @@ private:
void checkGcp(Signal* signal);
void commitGciHandling(Signal* signal, Uint64 Tgci);
- void copyApi(Signal* signal);
+ void copyApi(Ptr<ApiConnectRecord> dst, Ptr<ApiConnectRecord> src);
void DIVER_node_fail_handling(Signal* signal, Uint64 Tgci);
- void gcpTcfinished(Signal* signal);
- void handleGcp(Signal* signal);
+ void gcpTcfinished(Signal* signal, Uint64 gci);
+ void handleGcp(Signal* signal, Ptr<ApiConnectRecord>);
void hash(Signal* signal);
bool handle_special_hash(Uint32 dstHash[4],
Uint32* src, Uint32 srcLen,
@@ -1459,8 +1459,8 @@ private:
void initialiseScanOprec(Signal* signal);
void initTable(Signal* signal);
void initialiseTcConnect(Signal* signal);
- void linkApiToGcp(Signal* signal);
- void linkGciInGcilist(Signal* signal);
+ void linkApiToGcp(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
+ void linkGciInGcilist(Ptr<GcpRecord>);
void linkKeybuf(Signal* signal);
void linkTcInConnectionlist(Signal* signal);
void releaseAbortResources(Signal* signal);
@@ -1468,7 +1468,6 @@ private:
void releaseApiConCopy(Signal* signal);
void releaseApiConnectFail(Signal* signal);
void releaseAttrinfo();
- void releaseGcp(Signal* signal);
void releaseKeys();
void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*);
void releaseDirtyWrite(Signal* signal);
@@ -1480,10 +1479,10 @@ private:
void seizeApiConnectCopy(Signal* signal);
void seizeApiConnectFail(Signal* signal);
void seizeDatabuf(Signal* signal);
- void seizeGcp(Signal* signal);
+ void seizeGcp(Ptr<GcpRecord> & dst, Uint64 gci);
void seizeTcConnect(Signal* signal);
void seizeTcConnectFail(Signal* signal);
- void sendApiCommit(Signal* signal);
+ Ptr<ApiConnectRecord> sendApiCommit(Signal* signal);
void sendAttrinfo(Signal* signal,
UintR TattrinfoPtr,
AttrbufRecord * const regAttrPtr,
@@ -1494,8 +1493,8 @@ private:
void sendSystemError(Signal* signal, int line);
void sendtckeyconf(Signal* signal, UintR TcommitFlag);
void sendTcIndxConf(Signal* signal, UintR TcommitFlag);
- void unlinkApiConnect(Signal* signal);
- void unlinkGcp(Signal* signal);
+ void unlinkApiConnect(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
+ void unlinkGcp(Ptr<GcpRecord>);
void unlinkReadyTcCon(Signal* signal);
void handleFailedOperation(Signal* signal,
const LqhKeyRef * const lqhKeyRef,
@@ -1667,8 +1666,8 @@ private:
UintR chostFilesize;
NdbNodeBitmask c_alive_nodes;
+ Uint32 c_ongoing_take_over_cnt;
GcpRecord *gcpRecord;
- GcpRecordPtr gcpPtr;
UintR cgcpFilesize;
TableRecord *tableRecord;
@@ -1683,7 +1682,6 @@ private:
UintR ctcTimer;
UintR cDbHbInterval;
- ApiConnectRecordPtr tmpApiConnectptr;
Uint64 tcheckGcpId;
struct TransCounters {
=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp 2007-11-02 16:23:17 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp 2008-08-11 11:24:12 +0000
@@ -292,6 +292,7 @@ Dbtc::Dbtc(Block_context& ctx):
tcFailRecord = 0;
c_apiConTimer = 0;
c_apiConTimer_line = 0;
+ c_ongoing_take_over_cnt = 0;
#ifdef VM_TRACE
{
@@ -300,8 +301,6 @@ Dbtc::Dbtc(Block_context& ctx):
&cachePtr,
&attrbufptr,
&hostptr,
- &gcpPtr,
- &tmpApiConnectptr,
&timeOutptr,
&scanFragptr,
&databufptr,
=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2008-05-27 19:50:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2008-08-11 11:24:12 +0000
@@ -4402,22 +4402,21 @@ void Dbtc::commitGciHandling(Signal* sig
UintR TgcpFilesize = cgcpFilesize;
UintR Tfirstgcp = cfirstgcp;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
+ Ptr<ApiConnectRecord> regApiPtr = apiConnectptr;
GcpRecord *localGcpRecord = gcpRecord;
- regApiPtr->globalcheckpointid = Tgci;
+ regApiPtr.p->globalcheckpointid = Tgci;
if (Tfirstgcp != RNIL) {
/* IF THIS GLOBAL CHECKPOINT ALREADY EXISTS */
localGcpPointer.i = Tfirstgcp;
ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
do {
- if (regApiPtr->globalcheckpointid == localGcpPointer.p->gcpId) {
+ if (regApiPtr.p->globalcheckpointid == localGcpPointer.p->gcpId) {
jam();
- gcpPtr.i = localGcpPointer.i;
- gcpPtr.p = localGcpPointer.p;
- linkApiToGcp(signal);
+ linkApiToGcp(localGcpPointer, regApiPtr);
return;
} else {
+ ndbrequire(regApiPtr.p->globalcheckpointid > localGcpPointer.p->gcpId);
localGcpPointer.i = localGcpPointer.p->nextGcp;
jam();
if (localGcpPointer.i != RNIL) {
@@ -4426,14 +4425,14 @@ void Dbtc::commitGciHandling(Signal* sig
continue;
}//if
}//if
- seizeGcp(signal);
- linkApiToGcp(signal);
+ seizeGcp(localGcpPointer, Tgci);
+ linkApiToGcp(localGcpPointer, regApiPtr);
return;
} while (1);
} else {
jam();
- seizeGcp(signal);
- linkApiToGcp(signal);
+ seizeGcp(localGcpPointer, Tgci);
+ linkApiToGcp(localGcpPointer, regApiPtr);
}//if
}//Dbtc::commitGciHandling()
@@ -4442,46 +4441,43 @@ void Dbtc::commitGciHandling(Signal* sig
/* CHECKPOINTS. WHEN THE TRANSACTION I COMPLETED THE API CONNECT RECORD IS */
/* LINKED OUT OF THE LIST. */
/*---------------------------------------------------------------------------*/
-void Dbtc::linkApiToGcp(Signal* signal)
+void Dbtc::linkApiToGcp(Ptr<GcpRecord> regGcpPtr,
+ Ptr<ApiConnectRecord> regApiPtr)
{
ApiConnectRecordPtr localApiConnectptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- GcpRecord * const regGcpPtr = gcpPtr.p;
- UintR TapiConnectptrIndex = apiConnectptr.i;
ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- regApiPtr->nextGcpConnect = RNIL;
- if (regGcpPtr->firstApiConnect == RNIL) {
- regGcpPtr->firstApiConnect = TapiConnectptrIndex;
+ regApiPtr.p->nextGcpConnect = RNIL;
+ if (regGcpPtr.p->firstApiConnect == RNIL) {
+ regGcpPtr.p->firstApiConnect = regApiPtr.i;
jam();
} else {
UintR TapiConnectFilesize = capiConnectFilesize;
- localApiConnectptr.i = regGcpPtr->lastApiConnect;
+ localApiConnectptr.i = regGcpPtr.p->lastApiConnect;
jam();
ptrCheckGuard(localApiConnectptr,
TapiConnectFilesize, localApiConnectRecord);
- localApiConnectptr.p->nextGcpConnect = TapiConnectptrIndex;
+ localApiConnectptr.p->nextGcpConnect = regApiPtr.i;
}//if
- UintR TlastApiConnect = regGcpPtr->lastApiConnect;
- regApiPtr->gcpPointer = gcpPtr.i;
- regApiPtr->prevGcpConnect = TlastApiConnect;
- regGcpPtr->lastApiConnect = TapiConnectptrIndex;
+ UintR TlastApiConnect = regGcpPtr.p->lastApiConnect;
+ regApiPtr.p->gcpPointer = regGcpPtr.i;
+ regApiPtr.p->prevGcpConnect = TlastApiConnect;
+ regGcpPtr.p->lastApiConnect = regApiPtr.i;
}//Dbtc::linkApiToGcp()
-void Dbtc::seizeGcp(Signal* signal)
+void Dbtc::seizeGcp(Ptr<GcpRecord> & dst, Uint64 Tgci)
{
GcpRecordPtr tmpGcpPointer;
GcpRecordPtr localGcpPointer;
UintR Tfirstgcp = cfirstgcp;
- Uint64 Tglobalcheckpointid = apiConnectptr.p->globalcheckpointid;
UintR TgcpFilesize = cgcpFilesize;
GcpRecord *localGcpRecord = gcpRecord;
localGcpPointer.i = cfirstfreeGcp;
ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
UintR TfirstfreeGcp = localGcpPointer.p->nextGcp;
- localGcpPointer.p->gcpId = Tglobalcheckpointid;
+ localGcpPointer.p->gcpId = Tgci;
localGcpPointer.p->nextGcp = RNIL;
localGcpPointer.p->firstApiConnect = RNIL;
localGcpPointer.p->lastApiConnect = RNIL;
@@ -4498,7 +4494,7 @@ void Dbtc::seizeGcp(Signal* signal)
tmpGcpPointer.p->nextGcp = localGcpPointer.i;
}//if
clastgcp = localGcpPointer.i;
- gcpPtr = localGcpPointer;
+ dst = localGcpPointer;
}//Dbtc::seizeGcp()
/*---------------------------------------------------------------------------*/
@@ -4626,6 +4622,7 @@ void Dbtc::execCOMMITTED(Signal* signal)
{
TcConnectRecordPtr localTcConnectptr;
ApiConnectRecordPtr localApiConnectptr;
+ ApiConnectRecordPtr localCopyPtr;
UintR TtcConnectFilesize = ctcConnectFilesize;
UintR TapiConnectFilesize = capiConnectFilesize;
@@ -4701,14 +4698,14 @@ void Dbtc::execCOMMITTED(Signal* signal)
/*-------------------------------------------------------*/
apiConnectptr = localApiConnectptr;
- sendApiCommit(signal);
+ localCopyPtr = sendApiCommit(signal);
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- localTcConnectptr.i = regApiPtr->firstTcConnect;
- UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec;
+ localTcConnectptr.i = localCopyPtr.p->firstTcConnect;
+ UintR Tlqhkeyconfrec = localCopyPtr.p->lqhkeyconfrec;
ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- regApiPtr->counter = Tlqhkeyconfrec;
+ localCopyPtr.p->counter = Tlqhkeyconfrec;
+ apiConnectptr = localCopyPtr;
tcConnectptr = localTcConnectptr;
complete010Lab(signal);
return;
@@ -4719,9 +4716,10 @@ void Dbtc::execCOMMITTED(Signal* signal)
/* SEND_API_COMMIT */
/* SEND COMMIT DECISION TO THE API. */
/*-------------------------------------------------------*/
-void Dbtc::sendApiCommit(Signal* signal)
+Ptr<Dbtc::ApiConnectRecord>
+Dbtc::sendApiCommit(Signal* signal)
{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
+ ApiConnectRecordPtr regApiPtr = apiConnectptr;
if (ERROR_INSERTED(8055))
{
@@ -4732,16 +4730,19 @@ void Dbtc::sendApiCommit(Signal* signal)
*/
signal->theData[0] = 9999;
sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
-
- Uint32 node = refToNode(regApiPtr->ndbapiBlockref);
+ Uint32 node = refToNode(regApiPtr.p->ndbapiBlockref);
signal->theData[0] = node;
sendSignal(QMGR_REF, GSN_API_FAILREQ, signal, 1, JBB);
SET_ERROR_INSERT_VALUE(8056);
- return;
+
+ Ptr<ApiConnectRecord> copyPtr;
+ copyPtr.i = regApiPtr.p->apiCopyRecord;
+ ptrCheckGuard(copyPtr, capiConnectFilesize, apiConnectRecord);
+ return copyPtr;
}
- if (regApiPtr->returnsignal == RS_TCKEYCONF)
+ if (regApiPtr.p->returnsignal == RS_TCKEYCONF)
{
if (ERROR_INSERTED(8054))
{
@@ -4750,49 +4751,57 @@ void Dbtc::sendApiCommit(Signal* signal)
sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 5000, 1);
}
else
+ {
sendtckeyconf(signal, 1);
- } else if (regApiPtr->returnsignal == RS_TC_COMMITCONF) {
+ }
+ }
+ else if (regApiPtr.p->returnsignal == RS_TC_COMMITCONF)
+ {
jam();
TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
- if(regApiPtr->commitAckMarker == RNIL){
+ if(regApiPtr.p->commitAckMarker == RNIL)
+ {
jam();
- commitConf->apiConnectPtr = regApiPtr->ndbapiConnect;
- } else {
+ commitConf->apiConnectPtr = regApiPtr.p->ndbapiConnect;
+ }
+ else
+ {
jam();
- commitConf->apiConnectPtr = regApiPtr->ndbapiConnect | 1;
+ commitConf->apiConnectPtr = regApiPtr.p->ndbapiConnect | 1;
}
- commitConf->transId1 = regApiPtr->transid[0];
- commitConf->transId2 = regApiPtr->transid[1];
- commitConf->gci_hi = Uint32(regApiPtr->globalcheckpointid >> 32);
- commitConf->gci_lo = Uint32(regApiPtr->globalcheckpointid);
+ commitConf->transId1 = regApiPtr.p->transid[0];
+ commitConf->transId2 = regApiPtr.p->transid[1];
+ commitConf->gci_hi = Uint32(regApiPtr.p->globalcheckpointid >> 32);
+ commitConf->gci_lo = Uint32(regApiPtr.p->globalcheckpointid);
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
+ sendSignal(regApiPtr.p->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
TcCommitConf::SignalLength, JBB);
- } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
+ }
+ else if (regApiPtr.p->returnsignal == RS_NO_RETURN)
+ {
jam();
- } else {
+ }
+ else
+ {
TCKEY_abort(signal, 37);
- return;
+ return regApiPtr;
}//if
+ Ptr<ApiConnectRecord> copyPtr;
UintR TapiConnectFilesize = capiConnectFilesize;
UintR TcommitCount = c_counters.ccommitCount;
- UintR TapiIndex = apiConnectptr.i;
- UintR TnewApiIndex = regApiPtr->apiCopyRecord;
- UintR TapiFailState = regApiPtr->apiFailState;
+ copyPtr.i = regApiPtr.p->apiCopyRecord;
+ UintR TapiFailState = regApiPtr.p->apiFailState;
ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- tmpApiConnectptr.p = apiConnectptr.p;
- tmpApiConnectptr.i = TapiIndex;
c_counters.ccommitCount = TcommitCount + 1;
- apiConnectptr.i = TnewApiIndex;
- ptrCheckGuard(apiConnectptr, TapiConnectFilesize, localApiConnectRecord);
- copyApi(signal);
+ ptrCheckGuard(copyPtr, TapiConnectFilesize, localApiConnectRecord);
+ copyApi(copyPtr, regApiPtr);
if (TapiFailState != ZTRUE) {
- return;
+ return copyPtr;
} else {
jam();
- handleApiFailState(signal, tmpApiConnectptr.i);
- return;
+ handleApiFailState(signal, regApiPtr.i);
+ return copyPtr;
}//if
}//Dbtc::sendApiCommit()
@@ -4801,54 +4810,52 @@ void Dbtc::sendApiCommit(Signal* signal)
/* COPY API RECORD ALSO RESET THE OLD API RECORD SO THAT IT */
/* IS PREPARED TO RECEIVE A NEW TRANSACTION. */
/*===========================================================================*/
-void Dbtc::copyApi(Signal* signal)
+void Dbtc::copyApi(ApiConnectRecordPtr copyPtr, ApiConnectRecordPtr regApiPtr)
{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
-
- UintR TndbapiConnect = regTmpApiPtr->ndbapiConnect;
- UintR TfirstTcConnect = regTmpApiPtr->firstTcConnect;
- UintR Ttransid1 = regTmpApiPtr->transid[0];
- UintR Ttransid2 = regTmpApiPtr->transid[1];
- UintR Tlqhkeyconfrec = regTmpApiPtr->lqhkeyconfrec;
- UintR TgcpPointer = regTmpApiPtr->gcpPointer;
+ UintR TndbapiConnect = regApiPtr.p->ndbapiConnect;
+ UintR TfirstTcConnect = regApiPtr.p->firstTcConnect;
+ UintR Ttransid1 = regApiPtr.p->transid[0];
+ UintR Ttransid2 = regApiPtr.p->transid[1];
+ UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec;
+ UintR TgcpPointer = regApiPtr.p->gcpPointer;
UintR TgcpFilesize = cgcpFilesize;
- UintR TcommitAckMarker = regTmpApiPtr->commitAckMarker;
- NdbNodeBitmask Tnodes = regTmpApiPtr->m_transaction_nodes;
+ UintR TcommitAckMarker = regApiPtr.p->commitAckMarker;
+ NdbNodeBitmask Tnodes = regApiPtr.p->m_transaction_nodes;
GcpRecord *localGcpRecord = gcpRecord;
- regApiPtr->ndbapiBlockref = regTmpApiPtr->ndbapiBlockref;
- regApiPtr->ndbapiConnect = TndbapiConnect;
- regApiPtr->firstTcConnect = TfirstTcConnect;
- regApiPtr->apiConnectstate = CS_COMPLETING;
- regApiPtr->transid[0] = Ttransid1;
- regApiPtr->transid[1] = Ttransid2;
- regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
- regApiPtr->commitAckMarker = TcommitAckMarker;
- regApiPtr->m_transaction_nodes = Tnodes;
- regApiPtr->singleUserMode = 0;
+ copyPtr.p->ndbapiBlockref = regApiPtr.p->ndbapiBlockref;
+ copyPtr.p->ndbapiConnect = TndbapiConnect;
+ copyPtr.p->firstTcConnect = TfirstTcConnect;
+ copyPtr.p->apiConnectstate = CS_COMPLETING;
+ copyPtr.p->transid[0] = Ttransid1;
+ copyPtr.p->transid[1] = Ttransid2;
+ copyPtr.p->lqhkeyconfrec = Tlqhkeyconfrec;
+ copyPtr.p->commitAckMarker = TcommitAckMarker;
+ copyPtr.p->m_transaction_nodes = Tnodes;
+ copyPtr.p->singleUserMode = 0;
+ Ptr<GcpRecord> gcpPtr;
gcpPtr.i = TgcpPointer;
ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
- unlinkApiConnect(signal);
- linkApiToGcp(signal);
- setApiConTimer(tmpApiConnectptr.i, 0, __LINE__);
- regTmpApiPtr->apiConnectstate = CS_CONNECTED;
- regTmpApiPtr->commitAckMarker = RNIL;
- regTmpApiPtr->firstTcConnect = RNIL;
- regTmpApiPtr->lastTcConnect = RNIL;
- regTmpApiPtr->m_transaction_nodes.clear();
- regTmpApiPtr->singleUserMode = 0;
- releaseAllSeizedIndexOperations(regTmpApiPtr);
+ unlinkApiConnect(gcpPtr, regApiPtr);
+ linkApiToGcp(gcpPtr, copyPtr);
+ setApiConTimer(regApiPtr.i, 0, __LINE__);
+ regApiPtr.p->apiConnectstate = CS_CONNECTED;
+ regApiPtr.p->commitAckMarker = RNIL;
+ regApiPtr.p->firstTcConnect = RNIL;
+ regApiPtr.p->lastTcConnect = RNIL;
+ regApiPtr.p->m_transaction_nodes.clear();
+ regApiPtr.p->singleUserMode = 0;
+ releaseAllSeizedIndexOperations(regApiPtr.p);
}//Dbtc::copyApi()
-void Dbtc::unlinkApiConnect(Signal* signal)
+void Dbtc::unlinkApiConnect(Ptr<GcpRecord> gcpPtr,
+ Ptr<ApiConnectRecord> regApiPtr)
{
ApiConnectRecordPtr localApiConnectptr;
- ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
UintR TapiConnectFilesize = capiConnectFilesize;
- UintR TprevGcpConnect = regTmpApiPtr->prevGcpConnect;
- UintR TnextGcpConnect = regTmpApiPtr->nextGcpConnect;
+ UintR TprevGcpConnect = regApiPtr.p->prevGcpConnect;
+ UintR TnextGcpConnect = regApiPtr.p->nextGcpConnect;
ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
if (TprevGcpConnect == RNIL) {
@@ -5110,7 +5117,7 @@ void Dbtc::releaseTransResources(Signal*
localTcConnectptr.i = rtrTcConnectptrIndex;
releaseTcCon();
} while (localTcConnectptr.i != RNIL);
- handleGcp(signal);
+ handleGcp(signal, apiConnectptr);
releaseFiredTriggerData(&apiConnectptr.p->theFiredTriggers);
releaseAllSeizedIndexOperations(apiConnectptr.p);
releaseApiConCopy(signal);
@@ -5123,27 +5130,24 @@ void Dbtc::releaseTransResources(Signal*
/* SENDS GCP_TCFINISHED WHEN ALL TRANSACTIONS BELONGING TO A CERTAIN */
/* GLOBAL CHECKPOINT HAVE COMPLETED. */
/* *********************************************************************>> */
-void Dbtc::handleGcp(Signal* signal)
+void Dbtc::handleGcp(Signal* signal, Ptr<ApiConnectRecord> regApiPtr)
{
GcpRecord *localGcpRecord = gcpRecord;
GcpRecordPtr localGcpPtr;
- UintR TapiConnectptrIndex = apiConnectptr.i;
UintR TgcpFilesize = cgcpFilesize;
localGcpPtr.i = apiConnectptr.p->gcpPointer;
- tmpApiConnectptr.i = TapiConnectptrIndex;
- tmpApiConnectptr.p = apiConnectptr.p;
ptrCheckGuard(localGcpPtr, TgcpFilesize, localGcpRecord);
- gcpPtr.i = localGcpPtr.i;
- gcpPtr.p = localGcpPtr.p;
- unlinkApiConnect(signal);
+ unlinkApiConnect(localGcpPtr, regApiPtr);
if (localGcpPtr.p->firstApiConnect == RNIL) {
if (localGcpPtr.p->gcpNomoretransRec == ZTRUE) {
- jam();
- tcheckGcpId = localGcpPtr.p->gcpId;
- gcpTcfinished(signal);
- unlinkGcp(signal);
+ if (c_ongoing_take_over_cnt == 0)
+ {
+ jam();
+ gcpTcfinished(signal, localGcpPtr.p->gcpId);
+ unlinkGcp(localGcpPtr);
+ }
}//if
- }//if
+ }
}//Dbtc::handleGcp()
void Dbtc::releaseApiConCopy(Signal* signal)
@@ -7119,35 +7123,136 @@ void Dbtc::execGCP_NOMORETRANS(Signal* s
Uint32 gci_lo = req->gci_lo;
Uint32 gci_hi = req->gci_hi;
tcheckGcpId = gci_lo | (Uint64(gci_hi) << 32);
+
+ Ptr<GcpRecord> gcpPtr;
if (cfirstgcp != RNIL) {
jam();
/* A GLOBAL CHECKPOINT IS GOING ON */
gcpPtr.i = cfirstgcp; /* SET POINTER TO FIRST GCP IN QUEUE*/
ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
- if (gcpPtr.p->gcpId == tcheckGcpId) {
+ if (gcpPtr.p->gcpId == tcheckGcpId)
+ {
jam();
- if (gcpPtr.p->firstApiConnect != RNIL) {
+ bool empty = gcpPtr.p->firstApiConnect == RNIL;
+ bool nfhandling = c_ongoing_take_over_cnt;
+
+ if (empty && nfhandling)
+ {
+ jam();
+ ndbout_c("NOT returning gcpTcfinished due to nfhandling %u/%u",
+ gci_hi, gci_lo);
+ }
+
+ if (!empty || c_ongoing_take_over_cnt)
+ {
jam();
gcpPtr.p->gcpNomoretransRec = ZTRUE;
} else {
jam();
- gcpTcfinished(signal);
- unlinkGcp(signal);
+ gcpTcfinished(signal, tcheckGcpId);
+ unlinkGcp(gcpPtr);
}//if
- } else {
+ }
+ else if (c_ongoing_take_over_cnt == 0)
+ {
jam();
/*------------------------------------------------------------*/
/* IF IT IS NOT THE FIRST THEN THERE SHOULD BE NO */
/* RECORD FOR THIS GLOBAL CHECKPOINT. WE ALWAYS REMOVE */
/* THE GLOBAL CHECKPOINTS IN ORDER. */
/*------------------------------------------------------------*/
- gcpTcfinished(signal);
- }//if
- } else {
+ gcpTcfinished(signal, tcheckGcpId);
+ }
+ else
+ {
+ jam();
+ goto outoforder;
+ }
+ }
+ else if (c_ongoing_take_over_cnt == 0)
+ {
jam();
- gcpTcfinished(signal);
- }//if
+ gcpTcfinished(signal, tcheckGcpId);
+ }
+ else
+ {
+seize:
+ jam();
+ ndbout_c("execGCP_NOMORETRANS(%u/%u) c_ongoing_take_over_cnt -> seize",
+ gci_hi, gci_lo);
+ seizeGcp(gcpPtr, tcheckGcpId);
+ gcpPtr.p->gcpNomoretransRec = ZTRUE;
+ }
return;
+
+outoforder:
+ printf("ooo: execGCP_NOMORETRANS tcheckGcpId: %u/%u cfirstgcp: %u/%u",
+ gci_hi, gci_lo,
+ Uint32(gcpPtr.p->gcpId >> 32), Uint32(gcpPtr.p->gcpId));
+
+ if (tcheckGcpId < gcpPtr.p->gcpId)
+ {
+ jam();
+
+ Ptr<GcpRecord> tmp;
+ tmp.i = cfirstfreeGcp;
+ ptrCheckGuard(tmp, cgcpFilesize, gcpRecord);
+ cfirstfreeGcp = tmp.p->nextGcp;
+
+ tmp.p->gcpId = tcheckGcpId;
+ tmp.p->nextGcp = cfirstgcp;
+ tmp.p->firstApiConnect = RNIL;
+ tmp.p->lastApiConnect = RNIL;
+ tmp.p->gcpNomoretransRec = ZTRUE;
+ cfirstgcp = tmp.i;
+ ndbout_c("LINK FIRST");
+ return;
+ }
+ else
+ {
+ Ptr<GcpRecord> prev = gcpPtr;
+ while (tcheckGcpId > gcpPtr.p->gcpId)
+ {
+ jam();
+ if (gcpPtr.p->nextGcp == RNIL)
+ {
+ printf("nextGcp == RNIL -> ");
+ goto seize;
+ }
+
+ prev = gcpPtr;
+ gcpPtr.i = gcpPtr.p->nextGcp;
+ ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
+ }
+
+ if (tcheckGcpId == gcpPtr.p->gcpId)
+ {
+ jam();
+ gcpPtr.p->gcpNomoretransRec = ZTRUE;
+ ndbout_c("found");
+ return;
+ }
+ ndbrequire(prev.i != gcpPtr.i); // checked earlier with initial "<"
+ ndbrequire(prev.p->gcpId < tcheckGcpId);
+ ndbrequire(gcpPtr.p->gcpId > tcheckGcpId);
+
+ Ptr<GcpRecord> tmp;
+ tmp.i = cfirstfreeGcp;
+ ptrCheckGuard(tmp, cgcpFilesize, gcpRecord);
+ cfirstfreeGcp = tmp.p->nextGcp;
+
+ tmp.p->gcpId = tcheckGcpId;
+ tmp.p->nextGcp = gcpPtr.i;
+ tmp.p->firstApiConnect = RNIL;
+ tmp.p->lastApiConnect = RNIL;
+ tmp.p->gcpNomoretransRec = ZTRUE;
+ prev.p->nextGcp = tmp.i;
+ ndbout_c("link middle %u/%u < %u/%u < %u/%u",
+ Uint32(prev.p->gcpId >> 32), Uint32(prev.p->gcpId),
+ gci_hi, gci_lo,
+ Uint32(gcpPtr.p->gcpId >> 32), Uint32(gcpPtr.p->gcpId));
+ return;
+ }
}//Dbtc::execGCP_NOMORETRANS()
/*****************************************************************************/
@@ -7205,6 +7310,7 @@ void Dbtc::execNODE_FAILREP(Signal* sign
/*------------------------------------------------------------*/
hostptr.p->hostStatus = HS_DEAD;
hostptr.p->m_nf_bits = HostRecord::NF_NODE_FAIL_BITS;
+ c_ongoing_take_over_cnt++;
c_alive_nodes.clear(hostptr.i);
if (tcNodeFailptr.p->failStatus == FS_LISTENING)
@@ -7408,8 +7514,31 @@ void Dbtc::execTAKE_OVERTCCONF(Signal* s
tcNodeFailptr.p->queueList[i] = tcNodeFailptr.p->queueList[end-1];
tcNodeFailptr.p->queueIndex = end - 1;
}
-
+
+ Uint32 cnt = c_ongoing_take_over_cnt;
+ ndbrequire(cnt);
+ c_ongoing_take_over_cnt = cnt - 1;
checkNodeFailComplete(signal, hostptr.i, HostRecord::NF_TAKEOVER);
+
+ if (cnt == 1 && cfirstgcp != RNIL)
+ {
+ /**
+ * Check if there are any hanging GCP_NOMORETRANS
+ */
+ GcpRecordPtr tmpGcpPointer;
+ tmpGcpPointer.i = cfirstgcp;
+ ptrCheckGuard(tmpGcpPointer, cgcpFilesize, gcpRecord);
+ if (tmpGcpPointer.p->gcpNomoretransRec &&
+ tmpGcpPointer.p->firstApiConnect == RNIL)
+ {
+ jam();
+ ndbout_c("completing gcp %u/%u in execTAKE_OVERTCCONF",
+ Uint32(tmpGcpPointer.p->gcpId >> 32),
+ Uint32(tmpGcpPointer.p->gcpId));
+ gcpTcfinished(signal, tmpGcpPointer.p->gcpId);
+ unlinkGcp(tmpGcpPointer);
+ }
+ }
}//Dbtc::execTAKE_OVERTCCONF()
void Dbtc::execTAKE_OVERTCREQ(Signal* signal)
@@ -7461,7 +7590,16 @@ void Dbtc::startTakeOverLab(Signal* sign
signal->theData[0] = tcNodeFailptr.i;
signal->theData[1] = cownref;
signal->theData[2] = tfailedNodeId;
- sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+ if (ERROR_INSERTED(8064) && hostptr.i == getOwnNodeId())
+ {
+ ndbout_c("sending delayed GSN_LQH_TRANSREQ to self");
+ sendSignalWithDelay(tblockref, GSN_LQH_TRANSREQ, signal, 100, 3);
+ CLEAR_ERROR_INSERT_VALUE;
+ }
+ else
+ {
+ sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+ }
}//if
}//for
}//Dbtc::startTakeOverLab()
@@ -7715,6 +7853,7 @@ void Dbtc::completeTransAtTakeOverDoOne(
apiConnectptr.p->currentTcConnect = tcConnectptr.i;
apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
+ commitGciHandling(signal, apiConnectptr.p->globalcheckpointid);
toCompleteHandlingLab(signal);
return;
case CS_FAIL_COMMITTING:
@@ -7729,6 +7868,7 @@ void Dbtc::completeTransAtTakeOverDoOne(
apiConnectptr.p->currentTcConnect = tcConnectptr.i;
apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
+ commitGciHandling(signal, apiConnectptr.p->globalcheckpointid);
toCommitHandlingLab(signal);
return;
case CS_FAIL_ABORTING:
@@ -8189,7 +8329,7 @@ void Dbtc::toCommitHandlingLab(Signal* s
sendTCKEY_FAILCONF(signal, apiConnectptr.p);
} else {
jam();
- sendApiCommit(signal);
+ apiConnectptr = sendApiCommit(signal);
}//if
apiConnectptr.p->currentTcConnect = apiConnectptr.p->firstTcConnect;
tcConnectptr.i = apiConnectptr.p->firstTcConnect;
@@ -8325,6 +8465,7 @@ void Dbtc::toCompleteHandlingLab(Signal*
signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
signal->theData[2] = apiConnectptr.p->takeOverInd;
sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
+ handleGcp(signal, apiConnectptr);
releaseTakeOver(signal);
} else {
jam();
@@ -10322,12 +10463,12 @@ void Dbtc::sendScanTabConf(Signal* signa
}//Dbtc::sendScanTabConf()
-void Dbtc::gcpTcfinished(Signal* signal)
+void Dbtc::gcpTcfinished(Signal* signal, Uint64 gci)
{
GCPTCFinished* conf = (GCPTCFinished*)signal->getDataPtrSend();
conf->senderData = c_gcp_ref;
- conf->gci_hi = Uint32(tcheckGcpId >> 32);
- conf->gci_lo = Uint32(tcheckGcpId);
+ conf->gci_hi = Uint32(gci >> 32);
+ conf->gci_lo = Uint32(gci);
sendSignal(cdihblockref, GSN_GCP_TCFINISHED, signal,
GCPTCFinished::SignalLength, JBB);
}//Dbtc::gcpTcfinished()
@@ -10473,6 +10614,7 @@ void Dbtc::initdatabuf(Signal* signal)
void Dbtc::initgcp(Signal* signal)
{
+ Ptr<GcpRecord> gcpPtr;
ndbrequire(cgcpFilesize > 0);
for (gcpPtr.i = 0; gcpPtr.i < cgcpFilesize; gcpPtr.i++) {
ptrAss(gcpPtr, gcpRecord);
@@ -10674,7 +10816,7 @@ void Dbtc::initialiseTcConnect(Signal* s
/* ---- LINK A GLOBAL CHECKPOINT RECORD INTO THE LIST WITH TRANSACTIONS */
/* WAITING FOR COMPLETION. */
/* ------------------------------------------------------------------------- */
-void Dbtc::linkGciInGcilist(Signal* signal)
+void Dbtc::linkGciInGcilist(Ptr<GcpRecord> gcpPtr)
{
GcpRecordPtr tmpGcpPointer;
if (cfirstgcp == RNIL) {
@@ -10847,13 +10989,6 @@ void Dbtc::releaseApiConnectFail(Signal*
cfirstfreeApiConnectFail = apiConnectptr.i;
}//Dbtc::releaseApiConnectFail()
-void Dbtc::releaseGcp(Signal* signal)
-{
- ptrGuard(gcpPtr);
- gcpPtr.p->nextGcp = cfirstfreeGcp;
- cfirstfreeGcp = gcpPtr.i;
-}//Dbtc::releaseGcp()
-
void Dbtc::releaseKeys()
{
UintR Tmp;
@@ -11046,25 +11181,18 @@ void Dbtc::sendSystemError(Signal* signa
/* ========================================================================= */
/* ------- LINK ACTUAL GCP OUT OF LIST ------- */
/* ------------------------------------------------------------------------- */
-void Dbtc::unlinkGcp(Signal* signal)
+void Dbtc::unlinkGcp(Ptr<GcpRecord> tmpGcpPtr)
{
- if (cfirstgcp == gcpPtr.i) {
- jam();
- cfirstgcp = gcpPtr.p->nextGcp;
- if (gcpPtr.i == clastgcp) {
- jam();
- clastgcp = RNIL;
- }//if
- } else {
+ ndbrequire(cfirstgcp == tmpGcpPtr.i);
+
+ cfirstgcp = tmpGcpPtr.p->nextGcp;
+ if (tmpGcpPtr.i == clastgcp) {
jam();
- /* --------------------------------------------------------------------
- * WE ARE TRYING TO REMOVE A GLOBAL CHECKPOINT WHICH WAS NOT THE OLDEST.
- * THIS IS A SYSTEM ERROR.
- * ------------------------------------------------------------------- */
- sendSystemError(signal, __LINE__);
+ clastgcp = RNIL;
}//if
- gcpPtr.p->nextGcp = cfirstfreeGcp;
- cfirstfreeGcp = gcpPtr.i;
+
+ tmpGcpPtr.p->nextGcp = cfirstfreeGcp;
+ cfirstfreeGcp = tmpGcpPtr.i;
}//Dbtc::unlinkGcp()
void
=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp 2008-04-25 09:18:49 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp 2008-08-11 11:24:12 +0000
@@ -382,10 +382,6 @@ private:
void execREAD_CONFIG_CONF(Signal*);
friend struct UpgradeStartup;
-
-#ifdef ERROR_INSERT
- Uint32 c_error_insert_extra;
-#endif
};
#endif
=== modified file 'storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp 2008-04-25 09:17:15 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp 2008-08-11 10:41:11 +0000
@@ -456,10 +456,6 @@ private:
StopReq c_stopReq;
bool check_multi_node_shutdown(Signal* signal);
-#ifdef ERROR_INSERT
- Uint32 c_error_insert_extra;
-#endif
-
void recompute_version_info(Uint32 type);
void recompute_version_info(Uint32 type, Uint32 version);
void execNODE_VERSION_REP(Signal* signal);
=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.cpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2008-04-22 20:09:38 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2008-08-11 11:24:12 +0000
@@ -1147,7 +1147,14 @@ SimulatedBlock::execCHANGE_NODE_STATE_RE
void
SimulatedBlock::execNDB_TAMPER(Signal * signal){
- SET_ERROR_INSERT_VALUE(signal->theData[0]);
+ if (signal->getLength() == 1)
+ {
+ SET_ERROR_INSERT_VALUE(signal->theData[0]);
+ }
+ else
+ {
+ SET_ERROR_INSERT_VALUE2(signal->theData[0], signal->theData[1]);
+ }
}
void
=== modified file 'storage/ndb/src/kernel/vm/pc.hpp'
--- a/storage/ndb/src/kernel/vm/pc.hpp 2008-02-04 13:36:54 +0000
+++ b/storage/ndb/src/kernel/vm/pc.hpp 2008-08-11 10:41:11 +0000
@@ -122,19 +122,23 @@
// -------- ERROR INSERT MACROS -------
#ifdef ERROR_INSERT
-#define ERROR_INSERT_VARIABLE UintR cerrorInsert
+#define ERROR_INSERT_VARIABLE UintR cerrorInsert, c_error_insert_extra
#define ERROR_INSERTED(x) (cerrorInsert == (x))
#define ERROR_INSERTED_CLEAR(x) (cerrorInsert == (x) ? (cerrorInsert = 0, true) : false)
#define SET_ERROR_INSERT_VALUE(x) cerrorInsert = x
+#define SET_ERROR_INSERT_VALUE2(x,y) cerrorInsert = x; c_error_insert_extra = y
#define CLEAR_ERROR_INSERT_VALUE cerrorInsert = 0
#else
#define ERROR_INSERT_VARIABLE typedef void * cerrorInsert // Will generate compiler error
if used
#define ERROR_INSERTED(x) false
#define ERROR_INSERTED_CLEAR(x) false
#define SET_ERROR_INSERT_VALUE(x)
+#define SET_ERROR_INSERT_VALUE2(x,y)
#define CLEAR_ERROR_INSERT_VALUE
#endif
+#define DECLARE_DUMP0(BLOCK, CODE, DESC) if (arg == CODE)
+
/* ------------------------------------------------------------------------- */
/* COMMONLY USED CONSTANTS. */
/* ------------------------------------------------------------------------- */
=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp 2008-08-05 10:13:56 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp 2008-08-11 11:24:12 +0000
@@ -22,6 +22,7 @@
#include <NdbRestarter.hpp>
#include <NdbRestarts.hpp>
#include <signaldata/DumpStateOrd.hpp>
+#include <NdbEnv.h>
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
@@ -858,6 +859,82 @@ end:
DBUG_RETURN(result);
}
+int runEventConsumer(NDBT_Context* ctx, NDBT_Step* step)
+{
+ DBUG_ENTER("runEventConsumer");
+ int result = NDBT_OK;
+ const NdbDictionary::Table * table= ctx->getTab();
+ HugoTransactions hugoTrans(* table);
+
+ char buf[1024];
+ sprintf(buf, "%s_EVENT", table->getName());
+ NdbEventOperation *pOp, *pCreate = 0;
+ pCreate = pOp = GETNDB(step)->createEventOperation(buf);
+ if ( pOp == NULL ) {
+ g_err << "Event operation creation failed on %s" << buf << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ bool merge_events = ctx->getProperty("MergeEvents");
+ pOp->mergeEvents(merge_events);
+
+ int i;
+ int n_columns= table->getNoOfColumns();
+ NdbRecAttr* recAttr[1024];
+ NdbRecAttr* recAttrPre[1024];
+ for (i = 0; i < n_columns; i++) {
+ recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
+ recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+ }
+
+ if (pOp->execute()) { // This starts changes to "start flowing"
+ g_err << "execute operation execution failed: \n";
+ g_err << pOp->getNdbError().code << " "
+ << pOp->getNdbError().message << endl;
+ result = NDBT_FAILED;
+ goto end;
+ }
+
+ ctx->setProperty("LastGCI_hi", ~(Uint32)0);
+ ctx->broadcast();
+
+ while(!ctx->isTestStopped())
+ {
+ int count= 0;
+ Ndb* ndb= GETNDB(step);
+
+ Uint64 last_gci = 0;
+ while(!ctx->isTestStopped())
+ {
+ Uint32 count = 0;
+ Uint64 curr_gci;
+ ndb->pollEvents(100, &curr_gci);
+ if (curr_gci != last_gci)
+ {
+ while ((pOp= ndb->nextEvent()) != 0)
+ {
+ count++;
+ }
+ last_gci = curr_gci;
+ }
+ ndbout_c("Consumed gci: %u/%u, %d events",
+ Uint32(last_gci >> 32), Uint32(last_gci), count);
+ }
+ }
+
+end:
+ if(pCreate)
+ {
+ if (GETNDB(step)->dropEventOperation(pCreate)) {
+ g_err << "dropEventOperation execution failed "
+ << GETNDB(step)->getNdbError().code << " "
+ << GETNDB(step)->getNdbError().message << endl;
+ result = NDBT_FAILED;
+ }
+ }
+ ctx->stopTest();
+ DBUG_RETURN(result);
+}
+
int runEventListenerUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
{
@@ -1745,6 +1822,17 @@ runSubscribeUnsubscribe(NDBT_Context* ct
return NDBT_OK;
}
+int
+runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int records = ctx->getNumRecords();
+ HugoTransactions hugoTrans(*ctx->getTab());
+ if (hugoTrans.loadTable(GETNDB(step), records) != 0){
+ return NDBT_FAILED;
+ }
+ return NDBT_OK;
+}
+
int
runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
@@ -3039,6 +3127,83 @@ runBug37672(NDBT_Context* ctx, NDBT_Step
}
+int
+runBug30780(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+
+ NdbRestarter res;
+
+ if (res.getNumDbNodes() < 2)
+ {
+ ctx->stopTest();
+ return NDBT_OK;
+ }
+
+ const int cases = 4;
+ int loops = ctx->getNumLoops();
+ if (loops <= cases)
+ loops = cases + 1;
+ for (int i = 0; i<loops; i++)
+ {
+ int master = res.getMasterNodeId();
+ int next = res.getNextMasterNodeId(master);
+
+ res.insertErrorInNode(next, 8064);
+ int val1[] = { 7213, 0 };
+ int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+ if (res.dumpStateOneNode(master, val2, 2))
+ return NDBT_FAILED;
+
+ int c = i % cases;
+ {
+ char buf[100];
+ const char * off = NdbEnv_GetEnv("NDB_ERR", buf, sizeof(buf));
+ if (off)
+ {
+ c = atoi(off);
+ }
+ }
+ switch(c){
+ case 0:
+ ndbout_c("stopping %u", master);
+ res.restartOneDbNode(master,
+ /** initial */ false,
+ /** nostart */ true,
+ /** abort */ true);
+ break;
+ case 1:
+ ndbout_c("stopping %u, err 7213", master);
+ val1[0] = 7213;
+ val1[1] = master;
+ res.dumpStateOneNode(next, val1, 2);
+ break;
+ case 2:
+ ndbout_c("stopping %u, err 7214", master);
+ val1[0] = 7214;
+ val1[1] = master;
+ res.dumpStateOneNode(next, val1, 2);
+ break;
+ case 3:
+ ndbout_c("stopping %u, err 7007", master);
+ res.insertErrorInNode(master, 7007);
+ break;
+ }
+ ndbout_c("waiting for %u", master);
+ res.waitNodesNoStart(&master, 1);
+ ndbout_c("starting %u", master);
+ res.startNodes(&master, 1);
+ ndbout_c("waiting for cluster started");
+ if (res.waitClusterStarted())
+ {
+ return NDBT_FAILED;
+ }
+ }
+
+ ctx->stopTest();
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(test_event);
TESTCASE("BasicEventOperation",
"Verify that we can listen to Events"
@@ -3234,6 +3399,15 @@ TESTCASE("Bug37672", "NdbRecord option O
{
INITIALIZER(runBug37672);
}
+TESTCASE("Bug30780", "")
+{
+ INITIALIZER(runCreateEvent);
+ INITIALIZER(runLoadTable);
+ STEP(runEventConsumer);
+ STEPS(runScanUpdateUntilStopped, 3);
+ STEP(runBug30780);
+ FINALIZER(runDropEvent);
+}
NDBT_TESTSUITE_END(test_event);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-06 15:39:54 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-11 11:24:12 +0000
@@ -1177,3 +1177,9 @@ cmd: testScanFilter
args:
#EOF 2008-07-09
+
+max-time: 600
+cmd: test_event
+args -r 5000 -n Bug30780 T1
+
+#EOF 2008-08-11
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (jonas:2659) Bug#30780 | jonas | 11 Aug |