summaryrefslogtreecommitdiff
path: root/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp')
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp2337
1 files changed, 798 insertions, 1539 deletions
diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index 4211645ace6..b5a5d0948bb 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -23,13 +23,10 @@
#include <signaldata/DictTabInfo.hpp>
#include <signaldata/CreateTable.hpp>
#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/CntrMasterReq.hpp>
-#include <signaldata/CntrMasterConf.hpp>
#include <signaldata/NodeFailRep.hpp>
#include <signaldata/TcKeyReq.hpp>
#include <signaldata/TcKeyConf.hpp>
#include <signaldata/EventReport.hpp>
-#include <signaldata/SetVarReq.hpp>
#include <signaldata/NodeStateSignalData.hpp>
#include <signaldata/StopPerm.hpp>
#include <signaldata/StopMe.hpp>
@@ -39,9 +36,11 @@
#include <signaldata/AbortAll.hpp>
#include <signaldata/SystemError.hpp>
#include <signaldata/NdbSttor.hpp>
+#include <signaldata/CntrStart.hpp>
#include <signaldata/DumpStateOrd.hpp>
#include <signaldata/FsRemoveReq.hpp>
+#include <signaldata/ReadConfig.hpp>
#include <AttributeHeader.hpp>
#include <Configuration.hpp>
@@ -50,8 +49,6 @@
#include <NdbOut.hpp>
#include <NdbTick.h>
-#define ZSYSTEM_RUN 256
-
/**
* ALL_BLOCKS Used during start phases and while changing node state
*
@@ -60,25 +57,27 @@
struct BlockInfo {
BlockReference Ref; // BlockReference
Uint32 NextSP; // Next start phase
+ Uint32 ErrorInsertStart;
+ Uint32 ErrorInsertStop;
};
static BlockInfo ALL_BLOCKS[] = {
- { DBTC_REF, 1 },
- { DBDIH_REF, 1 },
- { DBLQH_REF, 1 },
- { DBACC_REF, 1 },
- { DBTUP_REF, 1 },
- { DBDICT_REF, 1 },
- { NDBFS_REF, 0 },
- { NDBCNTR_REF, 0 },
- { QMGR_REF, 1 },
- { CMVMI_REF, 1 },
+ { DBTC_REF, 1 , 8000, 8035 },
+ { DBDIH_REF, 1 , 7000, 7173 },
+ { DBLQH_REF, 1 , 5000, 5030 },
+ { DBACC_REF, 1 , 3000, 3999 },
+ { DBTUP_REF, 1 , 4000, 4007 },
+ { DBDICT_REF, 1 , 6000, 6003 },
+ { NDBFS_REF, 0 , 2000, 2999 },
+ { NDBCNTR_REF, 0 , 1000, 1999 },
+ { QMGR_REF, 1 , 1, 999 },
+ { CMVMI_REF, 1 , 9000, 9999 },
{ TRIX_REF, 1 },
- { BACKUP_REF, 1 },
- { DBUTIL_REF, 1 },
- { SUMA_REF, 1 },
+ { BACKUP_REF, 1 , 10000, 10999 },
+ { DBUTIL_REF, 1 , 11000, 11999 },
+ { SUMA_REF, 1 , 13000, 13999 },
{ GREP_REF, 1 },
- { DBTUX_REF, 1 }
+ { DBTUX_REF, 1 , 12000, 12999 }
};
static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo);
@@ -91,33 +90,27 @@ void Ndbcntr::execCONTINUEB(Signal* signal)
jamEntry();
UintR Ttemp1 = signal->theData[0];
switch (Ttemp1) {
- case ZCONTINUEB_1:
- jam();
- if (cwaitContinuebFlag == ZFALSE) {
- jam();
-/*******************************/
-/* SIGNAL NOT WANTED ANYMORE */
-/*******************************/
- return;
- } else {
+ case ZSTARTUP:{
+ if(getNodeState().startLevel == NodeState::SL_STARTED){
jam();
-/*******************************/
-/* START ALREADY IN PROGRESS */
-/*******************************/
- if (cstartProgressFlag == ZVOTING) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- if (ctypeOfStart == NodeState::ST_NODE_RESTART) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- ph2ELab(signal);
return;
- }//if
+ }
+
+ if(cmasterNodeId == getOwnNodeId() && c_start.m_starting.isclear()){
+ jam();
+ trySystemRestart(signal);
+ // Fall-through
+ }
+
+ Uint64 now = NdbTick_CurrentMillisecond();
+ if(c_start.m_startFailureTimeout > now){
+ ndbrequire(false);
+ }
+
+ signal->theData[0] = ZSTARTUP;
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
break;
+ }
case ZSHUTDOWN:
jam();
c_stopRec.checkTimeout(signal);
@@ -189,28 +182,18 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal)
return;
}//Ndbcntr::execSYSTEM_ERROR()
-/*---------------------------------------------------------------------------*/
-/* The STTOR signal is on level C, we use CONTINUEB to get into level B */
-/*---------------------------------------------------------------------------*/
-/**************************** >----------------------------------------------*/
-/* STTOR > SENDER : MISSRA */
-/**************************** >------------------+ RECEIVER : NDBCNTR */
- /* INPUT : CSTART_PHASE */
- /* CSIGNAL_KEY */
- /*---------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
void Ndbcntr::execSTTOR(Signal* signal)
{
jamEntry();
cstartPhase = signal->theData[1];
- csignalKey = signal->theData[6];
NodeState newState(NodeState::SL_STARTING, cstartPhase,
(NodeState::StartType)ctypeOfStart);
updateNodeState(signal, newState);
+ cndbBlocksCount = 0;
+ cinternalStartphase = cstartPhase - 1;
+
switch (cstartPhase) {
case 0:
if(theConfiguration.getInitialStart()){
@@ -244,6 +227,7 @@ void Ndbcntr::execSTTOR(Signal* signal)
case 6:
jam();
getNodeGroup(signal);
+ // Fall through
break;
case ZSTART_PHASE_8:
jam();
@@ -327,80 +311,37 @@ void Ndbcntr::execNDB_STTORRY(Signal* signal)
}//switch
}//Ndbcntr::execNDB_STTORRY()
-/*
-4.2 START PHASE 1 */
-/*###########################################################################*/
-/*LOAD OUR BLOCK REFERENCE AND OUR NODE ID. LOAD NODE IDS OF ALL NODES IN */
-/* CLUSTER CALCULATE BLOCK REFERENCES OF ALL BLOCKS IN THIS NODE */
-/*---------------------------------------------------------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
void Ndbcntr::startPhase1Lab(Signal* signal)
{
jamEntry();
initData(signal);
- cownBlockref = calcNdbCntrBlockRef(0);
- cnoRunNodes = 0;
- cnoRegNodes = 0;
-
- NdbBlocksRecPtr ndbBlocksPtr;
cdynamicNodeId = 0;
- cownBlockref = calcNdbCntrBlockRef(getOwnNodeId());
- cqmgrBlockref = calcQmgrBlockRef(getOwnNodeId());
- cdictBlockref = calcDictBlockRef(getOwnNodeId());
- cdihBlockref = calcDihBlockRef(getOwnNodeId());
- clqhBlockref = calcLqhBlockRef(getOwnNodeId());
- ctcBlockref = calcTcBlockRef(getOwnNodeId());
- ccmvmiBlockref = numberToRef(CMVMI, getOwnNodeId());
+ NdbBlocksRecPtr ndbBlocksPtr;
ndbBlocksPtr.i = 0;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = clqhBlockref;
+ ndbBlocksPtr.p->blockref = DBLQH_REF;
ndbBlocksPtr.i = 1;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = cdictBlockref;
+ ndbBlocksPtr.p->blockref = DBDICT_REF;
ndbBlocksPtr.i = 2;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = calcTupBlockRef(getOwnNodeId());
+ ndbBlocksPtr.p->blockref = DBTUP_REF;
ndbBlocksPtr.i = 3;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = calcAccBlockRef(getOwnNodeId());
+ ndbBlocksPtr.p->blockref = DBACC_REF;
ndbBlocksPtr.i = 4;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = ctcBlockref;
+ ndbBlocksPtr.p->blockref = DBTC_REF;
ndbBlocksPtr.i = 5;
ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = cdihBlockref;
+ ndbBlocksPtr.p->blockref = DBDIH_REF;
sendSttorry(signal);
return;
}
-/*
-4.3 START PHASE 2 */
-/*###########################################################################*/
-// SEND A REGISTATION REQUEST TO QMGR AND WAIT FOR REPLY APPL_REGCONF OR
-// APPL_REGREF COLLECT ALL OTHER NDB NODES
-// AND THEIR STATES FIND OUT WHAT KIND OF START THIS NODE ARE GOING TO PERFORM
-// IF THIS IS A SYSTEM OR INITIAL
-// RESTART THEN FIND OUT WHO IS THE MASTER IF THIS NODE BECOME THE CNTR MASTER
-// THEN COLLECT CNTR_MASTERREQ FROM
-// ALL OTHER REGISTRATED CNTR THE MASTER WILL SEND BACK A CNTR_MASTERCONF WITH
-// FINAL DECISSION ABOUT WHAT TYPE
-// OF START AND WHICH NODES ARE APPROVED TO PARTICIPATE IN THE START IF THE
-// RECEIVER OF CNTR_MASTERREQ HAVE A
-// BETTER CHOICE OF MASTER THEN SEND CNTR_MASTERREF. NEW NODES ARE ALWAYS
-// ALLOWED TO REGISTER, EVEN DURING
-// RESTART BUT THEY WILL BE IGNORED UNTIL THE START HAVE FINISHED.
-// SEND SIGNAL NDBSTTOR TO ALL BLOCKS, ACC, DICT, DIH, LQH, TC AND TUP
-// SEND SIGNAL APPL_REGREQ TO QMGR IN THIS NODE AND WAIT FOR REPLY
-// APPL_REGCONF OR APPL_REGREF */
-/*--------------------------------------------------------------------------*/
-/*******************************/
-/* READ_NODESREF */
-/*******************************/
void Ndbcntr::execREAD_NODESREF(Signal* signal)
{
jamEntry();
@@ -408,25 +349,6 @@ void Ndbcntr::execREAD_NODESREF(Signal* signal)
return;
}//Ndbcntr::execREAD_NODESREF()
-/*******************************/
-/* APPL_REGREF */
-/*******************************/
-void Ndbcntr::execAPPL_REGREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal);
- return;
-}//Ndbcntr::execAPPL_REGREF()
-
-/*******************************/
-/* CNTR_MASTERREF */
-/*******************************/
-void Ndbcntr::execCNTR_MASTERREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal);
- return;
-}//Ndbcntr::execCNTR_MASTERREF()
/*******************************/
/* NDB_STARTREF */
@@ -443,17 +365,11 @@ void Ndbcntr::execNDB_STARTREF(Signal* signal)
/*******************************/
void Ndbcntr::startPhase2Lab(Signal* signal)
{
- cinternalStartphase = cstartPhase - 1;
-/*--------------------------------------*/
-/* CASE: CSTART_PHASE = ZSTART_PHASE_2 */
-/*--------------------------------------*/
- cndbBlocksCount = 0;
- cwaitContinuebFlag = ZFALSE;
-/* NOT WAITING FOR SIGNAL CONTINUEB */
-
- clastGci = 0;
- signal->theData[0] = cownBlockref;
- sendSignal(cdihBlockref, GSN_DIH_RESTARTREQ, signal, 1, JBB);
+ c_start.m_lastGci = 0;
+ c_start.m_lastGciNodeId = getOwnNodeId();
+
+ signal->theData[0] = reference();
+ sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB);
return;
}//Ndbcntr::startPhase2Lab()
@@ -463,8 +379,8 @@ void Ndbcntr::startPhase2Lab(Signal* signal)
void Ndbcntr::execDIH_RESTARTCONF(Signal* signal)
{
jamEntry();
- cmasterDihId = signal->theData[0];
- clastGci = signal->theData[1];
+ //cmasterDihId = signal->theData[0];
+ c_start.m_lastGci = signal->theData[1];
ctypeOfStart = NodeState::ST_SYSTEM_RESTART;
ph2ALab(signal);
return;
@@ -488,370 +404,449 @@ void Ndbcntr::ph2ALab(Signal* signal)
/* from QMGR */
/* READ_NODESREQ */
/******************************/
- signal->theData[0] = cownBlockref;
- sendSignal(cqmgrBlockref, GSN_READ_NODESREQ, signal, 1, JBB);
+ signal->theData[0] = reference();
+ sendSignal(QMGR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
return;
}//Ndbcntr::ph2ALab()
+inline
+Uint64
+setTimeout(Uint64 time, Uint32 timeoutValue){
+ if(timeoutValue == 0)
+ return ~0;
+ return time + timeoutValue;
+}
+
/*******************************/
/* READ_NODESCONF */
/*******************************/
void Ndbcntr::execREAD_NODESCONF(Signal* signal)
{
jamEntry();
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
+ const ReadNodesConf * readNodes = (ReadNodesConf *)&signal->theData[0];
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if(NodeBitmask::get(readNodes->allNodes, nodePtr.i)){
- jam();
- nodePtr.p->nodeDefined = ZTRUE;
- } else {
- jam();
- nodePtr.p->nodeDefined = ZFALSE;
- }//if
- }//for
+ cmasterNodeId = readNodes->masterNodeId;
+ cdynamicNodeId = readNodes->ndynamicId;
+
+ /**
+ * All defined nodes...
+ */
+ c_allDefinedNodes.assign(NdbNodeBitmask::Size, readNodes->allNodes);
+ c_clusterNodes.assign(NdbNodeBitmask::Size, readNodes->clusterNodes);
- CfgBlockRecPtr cfgBlockPtr;
+ Uint32 to_1 = 30000;
+ Uint32 to_2 = 0;
+ Uint32 to_3 = 0;
+
+ const ndb_mgm_configuration_iterator * p =
+ theConfiguration.getOwnConfigIterator();
+
+ ndbrequire(p != 0);
+ ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, &to_1);
+ ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT, &to_2);
+ ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3);
+
+ c_start.m_startPartialTimeout = setTimeout(c_start.m_startTime, to_1);
+ c_start.m_startPartitionedTimeout = setTimeout(c_start.m_startTime, to_2);
+ c_start.m_startFailureTimeout = setTimeout(c_start.m_startTime, to_3);
+
+ if(getNodeInfo(cmasterNodeId).m_version < MAKE_VERSION(3,5,0)){
+ /**
+ * Old NDB running
+ */
+ UpgradeStartup::sendCmAppChg(* this, signal, 0); // ADD
+ return;
+ }
+
+ sendCntrStartReq(signal);
- cfgBlockPtr.i = 0;
- ptrAss(cfgBlockPtr, cfgBlockRec);
- signal->theData[0] = cownBlockref;
- signal->theData[1] = cfgBlockPtr.i;
- sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB);
return;
}
-/*******************************/
-/* CMVMI_CFGCONF */
-/*******************************/
-void Ndbcntr::execCMVMI_CFGCONF(Signal* signal)
-{
- CfgBlockRecPtr cfgBlockPtr;
+void
+Ndbcntr::execCM_ADD_REP(Signal* signal){
+ jamEntry();
+ c_clusterNodes.set(signal->theData[0]);
+}
+
+void
+Ndbcntr::sendCntrStartReq(Signal * signal){
jamEntry();
- CmvmiCfgConf * const cfgConf = (CmvmiCfgConf *)&signal->theData[0];
+ CntrStartReq * req = (CntrStartReq*)signal->getDataPtrSend();
+ req->startType = ctypeOfStart;
+ req->lastGci = c_start.m_lastGci;
+ req->nodeId = getOwnNodeId();
+ sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_START_REQ,
+ signal, CntrStartReq::SignalLength, JBB);
+}
- cfgBlockPtr.i = cfgConf->startPhase;
- ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec);
- for(unsigned int i = 0; i<CmvmiCfgConf::NO_OF_WORDS; i++)
- cfgBlockPtr.p->cfgData[i] = cfgConf->theData[i];
+void
+Ndbcntr::execCNTR_START_REF(Signal * signal){
+ jamEntry();
+ const CntrStartRef * ref = (CntrStartRef*)signal->getDataPtr();
- if (cfgBlockPtr.i < 4) {
+ switch(ref->errorCode){
+ case CntrStartRef::NotMaster:
jam();
- cfgBlockPtr.i = cfgBlockPtr.i + 1;
- signal->theData[0] = cownBlockref;
- signal->theData[1] = cfgBlockPtr.i;
- sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB);
+ cmasterNodeId = ref->masterNodeId;
+ sendCntrStartReq(signal);
return;
- }
+ }
+ ndbrequire(false);
+}
+
+void
+Ndbcntr::StartRecord::reset(){
+ m_starting.clear();
+ m_waiting.clear();
+ m_withLog.clear();
+ m_withoutLog.clear();
+ m_lastGci = m_lastGciNodeId = 0;
+ m_startPartialTimeout = ~0;
+ m_startPartitionedTimeout = ~0;
+ m_startFailureTimeout = ~0;
- jam();
+ m_logNodesCount = 0;
+}
+
+void
+Ndbcntr::execCNTR_START_CONF(Signal * signal){
+ jamEntry();
+ const CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr();
+
+ cnoStartNodes = conf->noStartNodes;
+ ctypeOfStart = (NodeState::StartType)conf->startType;
+ c_start.m_lastGci = conf->startGci;
+ cmasterNodeId = conf->masterNodeId;
+ NdbNodeBitmask tmp;
+ tmp.assign(NdbNodeBitmask::Size, conf->startedNodes);
+ c_startedNodes.bitOR(tmp);
+ c_start.m_starting.assign(NdbNodeBitmask::Size, conf->startingNodes);
+ ph2GLab(signal);
+
+ UpgradeStartup::sendCmAppChg(* this, signal, 2); //START
+}
+
+/**
+ * Tried with parallell nr, but it crashed in DIH
+ * so I turned it off, as I don't want to debug DIH now...
+ * Jonas 19/11-03
+ *
+ * After trying for 2 hours, I gave up.
+ * DIH is not designed to support it, and
+ * it requires quite of lot of changes to
+ * make it work
+ * Jonas 5/12-03
+ */
+#define PARALLELL_NR 0
- cfgBlockPtr.i = 0;
- ptrAss(cfgBlockPtr, cfgBlockRec);
+#if PARALLELL_NR
+const bool parallellNR = true;
+#else
+const bool parallellNR = false;
+#endif
+
+void
+Ndbcntr::execCNTR_START_REP(Signal* signal){
+ jamEntry();
+ Uint32 nodeId = signal->theData[0];
+ c_startedNodes.set(nodeId);
+ c_start.m_starting.clear(nodeId);
- cdelayStart = cfgBlockPtr.p->cfgData[0];
+ if(!c_start.m_starting.isclear()){
+ jam();
+ return;
+ }
- signal->theData[0] = cownBlockref;
- signal->theData[1] = strlen(ZNAME_OF_APPL) | (ZNAME_OF_APPL[0] << 8);
- signal->theData[2] = ZNAME_OF_APPL[1] | (ZNAME_OF_APPL[2] << 8);
- signal->theData[9] = ZAPPL_SUBTYPE;
- signal->theData[10] = 0; //NDB_VERSION;
- sendSignal(cqmgrBlockref, GSN_APPL_REGREQ, signal, 11, JBB);
- return; /* WAIT FOR APPL_REGCONF */
-}//Ndbcntr::execCMVMI_CFGCONF()
+ if(cmasterNodeId != getOwnNodeId()){
+ c_start.reset();
+ return;
+ }
-/*******************************/
-/* APPL_REGCONF */
-/*******************************/
-void Ndbcntr::execAPPL_REGCONF(Signal* signal)
-{
- jamEntry();
- cqmgrConnectionP = signal->theData[0];
- cnoNdbNodes = signal->theData[1];
- if(ctypeOfStart == NodeState::ST_INITIAL_START){
- cmasterCandidateId = signal->theData[2];
- } else {
- cmasterCandidateId = ZNIL;
+ if(c_start.m_waiting.isclear()){
+ c_start.reset();
+ return;
}
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
+ startWaitingNodes(signal);
+}
+
+void
+Ndbcntr::execCNTR_START_REQ(Signal * signal){
+ jamEntry();
+ const CntrStartReq * req = (CntrStartReq*)signal->getDataPtr();
- /*----------------------------------------------------------------------*/
- /* CALCULATE HOW MANY NODES THAT WE NEED TO PERFORM A START. MAKE A */
- /* DECISION ABOUT WAITING FOR MORE NODES OR TO CONTINUE AT ONCE */
- /*----------------------------------------------------------------------*/
- nodePtr.p->state = ZADD;
- nodePtr.p->ndbVersion = 0; //NDB_VERSION;
- nodePtr.p->subType = ZAPPL_SUBTYPE;
- nodePtr.p->dynamicId = signal->theData[3];
- // Save dynamic nodeid in global variable
- cdynamicNodeId = nodePtr.p->dynamicId;
- cnoRegNodes = cnoRegNodes + 1;
- switch((NodeState::StartType)ctypeOfStart){
- case NodeState::ST_INITIAL_START:
+ const Uint32 nodeId = req->nodeId;
+ const Uint32 lastGci = req->lastGci;
+ const NodeState::StartType st = (NodeState::StartType)req->startType;
+
+ if(cmasterNodeId == 0){
jam();
- cnoNeedNodes = cnoNdbNodes;
- break;
- case NodeState::ST_SYSTEM_RESTART:
- if (cnoNdbNodes == 2) {
- jam();
- /*--------------------------------------*/
- /* NEED > 50% OF ALL NODES. */
- /* WE WILL SEND CONTINUEB WHEN THE WE */
- /* RECEIVE THE FIRST APPL_CHANGEREP. */
- /*--------------------------------------*/
- cnoNeedNodes = 1; /* IF ONLY 2 NODES IN CLUSTER, 1 WILL DO*/
- } else {
- jam();
- cnoNeedNodes = (cnoNdbNodes >> 1) + 1;
- }//if
- break;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- break;
- default:
- ndbrequire(false);
- }//if
+ // Has not completed READNODES yet
+ sendSignalWithDelay(reference(), GSN_CNTR_START_REQ, signal, 100,
+ signal->getLength());
+ return;
+ }
- /*--------------------------------------------------------------*/
- /* WE CAN COME HERE ALSO IN A NODE RESTART IF THE */
- /* REGISTRATION OF A RUNNING NODE HAPPENS TO ARRIVE BEFORE*/
- /* THE APPL_REGCONF SIGNAL. */
- /* IN THAT CASE CNO_NEED_NODES = ZNIL IF NOT NODE_STATE */
- /* SIGNAL HAS RETURNED THE PROPER VALUE. IN BOTH CASES WE */
- /* DO NOT NEED TO ASSIGN IT HERE. */
- /*--------------------------------------------------------------*/
- ph2CLab(signal);
- return;
-}//Ndbcntr::execAPPL_REGCONF()
-
-/*--------------------------------------------------------------*/
-/* CHECK THAT WE GOT ALL NODES REGISTRATED AS WE NEED FOR THIS */
-/* KIND OF START. WE ALWAYS END UP HERE AFTER HANDLING OF */
-/* APPL_CHANGEREP AND NODE_STATESCONF */
-/*--------------------------------------------------------------*/
-void Ndbcntr::ph2CLab(Signal* signal)
-{
- NodeRecPtr ownNodePtr;
- ownNodePtr.i = getOwnNodeId();
- ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec);
- if (ownNodePtr.p->state != ZADD) {
+ if(cmasterNodeId != getOwnNodeId()){
jam();
+ sendCntrStartRef(signal, nodeId, CntrStartRef::NotMaster);
return;
- }//if
- switch (ctypeOfStart) {
- case NodeState::ST_INITIAL_START:
+ }
+
+ const NodeState & nodeState = getNodeState();
+ switch(nodeState.startLevel){
+ case NodeState::SL_NOTHING:
+ case NodeState::SL_CMVMI:
jam();
- if (cnoRegNodes == cnoNeedNodes) {
- jam();
- ph2ELab(signal);
-/*******************************/
-/* ALL NODES ADDED */
-/*******************************/
- return;
- }//if
+ ndbrequire(false);
+ case NodeState::SL_STARTING:
+ case NodeState::SL_STARTED:
+ break;
+
+ case NodeState::SL_STOPPING_1:
+ case NodeState::SL_STOPPING_2:
+ case NodeState::SL_STOPPING_3:
+ case NodeState::SL_STOPPING_4:
+ jam();
+ sendCntrStartRef(signal, nodeId, CntrStartRef::StopInProgress);
+ return;
+ }
+
+ /**
+ * Am I starting (or started)
+ */
+ const bool starting = (nodeState.startLevel != NodeState::SL_STARTED);
+
+ c_start.m_waiting.set(nodeId);
+ switch(st){
+ case NodeState::ST_INITIAL_START:
+ c_start.m_withoutLog.set(nodeId);
break;
case NodeState::ST_SYSTEM_RESTART:
- ndbrequire(cnoRunNodes == 0);
- if (cnoRegNodes == cnoNdbNodes) {
+ c_start.m_withLog.set(nodeId);
+ if(starting && lastGci > c_start.m_lastGci){
jam();
- /*******************************/
- /* ALL NODES ADDED */
- /*******************************/
- ph2ELab(signal);
+ CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend();
+ ref->errorCode = CntrStartRef::NotMaster;
+ ref->masterNodeId = nodeId;
+ NodeReceiverGroup rg (NDBCNTR, c_start.m_waiting);
+ sendSignal(rg, GSN_CNTR_START_REF, signal,
+ CntrStartRef::SignalLength, JBB);
return;
- }//if
- if (cwaitContinuebFlag == ZFALSE) {
- if (cnoRegNodes == cnoNeedNodes) {
- jam();
- /****************************************/
- /* ENOUGH NODES ADDED, WAIT CDELAY_START*/
- /****************************************/
- cwaitContinuebFlag = ZTRUE;
- /*******************************/
- /* A DELAY SIGNAL TO MYSELF */
- /*******************************/
- signal->theData[0] = ZCONTINUEB_1;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB,
- signal, cdelayStart * 1000, 1);
- return;
- }//if
- }//if
+ }
+ if(starting){
+ Uint32 i = c_start.m_logNodesCount++;
+ c_start.m_logNodes[i].m_nodeId = nodeId;
+ c_start.m_logNodes[i].m_lastGci = req->lastGci;
+ }
break;
case NodeState::ST_NODE_RESTART:
case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- if (cnoNeedNodes <= cnoRunNodes) {
- /*----------------------------------------------*/
- /* GOT ALL RUNNING NODES */
- /* " =< " :NODES MAY HAVE FINISHED A NODERESTART*/
- /* WHILE WE WERE WAITING FOR NODE_STATESCONF */
- /*----------------------------------------------*/
- if (cnoRegNodes != (cnoRunNodes + 1)) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- getStartNodes(signal);
- cwaitContinuebFlag = ZFALSE;
- cstartProgressFlag = ZTRUE;
- /*--------------------------------------------------------------*/
- /* IF SOMEONE ELSE IS PERFORMING NODERESTART THEN WE GOT A REF */
- /* AND WE HAVE TO MAKE A NEW NODE_STATESREQ */
- /*--------------------------------------------------------------*/
- sendCntrMasterreq(signal);
- }//if
- break;
- default:
- jam();
- systemErrorLab(signal);
- return;
- break;
- }//switch
- /*--------------------------------------------------------------*/
- /* WAIT FOR THE CONTINUEB SIGNAL */
- /* AND / OR MORE NODES TO REGISTER */
- /*--------------------------------------------------------------*/
- return;
-}//Ndbcntr::ph2CLab()
+ case NodeState::ST_ILLEGAL_TYPE:
+ ndbrequire(false);
+ }
-/*******************************/
-/* CONTINUEB */
-/*******************************/
-/*--------------------------------------------------------------*/
-/* WE COME HERE ONLY IN SYSTEM RESTARTS AND INITIAL START. FOR */
-/* INITIAL START WE HAVE ALREADY CALCULATED THE MASTER. FOR */
-/* SYSTEM RESTART WE NEED TO PERFORM A VOTING SCHEME TO AGREE */
-/* ON A COMMON MASTER. WE GET OUR VOTE FROM DIH AND THE RESTART */
-/* INFORMATION IN DIH. */
-/*--------------------------------------------------------------*/
-void Ndbcntr::ph2ELab(Signal* signal)
-{
- cwaitContinuebFlag = ZFALSE;
-/*--------------------------------------*/
-/* JMP TO THIS WHEN ENOUGH NO OF */
-/* NODES ADDED */
-/*--------------------------------------*/
-/*--------------------------------------*/
-/* IGNORE CONTINUEB SIGNAL */
-/* CONTINUEB SIGNALS WILL EXIT AT */
-/* SIGNAL RECEPTION */
-/*--------------------------------------*/
- if (cnoRegNodes >= cnoNeedNodes) {
+ const bool startInProgress = !c_start.m_starting.isclear();
+
+ if((starting && startInProgress) || (startInProgress && !parallellNR)){
jam();
- getStartNodes(signal);
- if (ctypeOfStart == NodeState::ST_INITIAL_START) {
- if (cmasterCandidateId != getOwnNodeId()) {
- jam();
-/*--------------------------------------*/
-/* THIS NODE IS NOT THE MASTER */
-/* DON'T SEND ANY MORE CNTR_MASTERREQ */
-/* VOTE FOR MASTER */
-/*--------------------------------------*/
- cstartProgressFlag = ZTRUE;
- sendCntrMasterreq(signal);
- resetStartVariables(signal);
- } else {
- jam();
- masterreq020Lab(signal);
- }//if
- } else if (ctypeOfStart == NodeState::ST_SYSTEM_RESTART) {
- jam();
-/*--------------------------------------------------------------*/
-/* WE START THE SELECTION OF MASTER PROCESS. IF WE HAVE NOT */
-/* COMPLETED THIS BEFORE THE TIME OUT WE WILL TRY A NEW RESTART.*/
-/*--------------------------------------------------------------*/
- cwaitContinuebFlag = ZTRUE;
- cstartProgressFlag = ZVOTING;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->state == ZADD) {
- jam();
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = cmasterDihId;
- signal->theData[2] = clastGci;
- sendSignal(nodePtr.p->cntrBlockref, GSN_VOTE_MASTERORD,
- signal, 3, JBB);
- }//if
- }//for
- } else {
- jam();
- systemErrorLab(signal);
- }//if
+ // We're already starting together with a bunch of nodes
+ // Let this node wait...
+ return;
+ }
+
+ if(starting){
+ trySystemRestart(signal);
} else {
- jam();
-/*--------------------------------------------------------------*/
-/* TOO FEW NODES TO START */
-/* WE HAVE WAITED FOR THE GIVEN TIME OUT AND NOT ENOUGH NODES */
-/* HAS REGISTERED. WE WILL CRASH AND RENEW THE ATTEMPT TO START */
-/* THE SYSTEM. */
-/*--------------------------------------------------------------*/
- systemErrorLab(signal);
- }//if
+ startWaitingNodes(signal);
+ }
+
return;
-}//Ndbcntr::ph2ELab()
+}
-/*******************************/
-/* MASTER NODE CONFIRMS REQ */
-/* CNTR_MASTERCONF */
-/*******************************/
-void Ndbcntr::execCNTR_MASTERCONF(Signal* signal)
-{
+void
+Ndbcntr::startWaitingNodes(Signal * signal){
+
+#if ! PARALLELL_NR
+ const Uint32 nodeId = c_start.m_waiting.find(0);
+ const Uint32 Tref = calcNdbCntrBlockRef(nodeId);
+ ndbrequire(nodeId != c_start.m_waiting.NotFound);
+
+ NodeState::StartType nrType = NodeState::ST_NODE_RESTART;
+ if(c_start.m_withoutLog.get(nodeId)){
+ nrType = NodeState::ST_INITIAL_NODE_RESTART;
+ }
+
+ /**
+ * Let node perform restart
+ */
+ CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend();
+ conf->noStartNodes = 1;
+ conf->startType = nrType;
+ conf->startGci = ~0; // Not used
+ conf->masterNodeId = getOwnNodeId();
+ BitmaskImpl::clear(NdbNodeBitmask::Size, conf->startingNodes);
+ BitmaskImpl::set(NdbNodeBitmask::Size, conf->startingNodes, nodeId);
+ c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
+ sendSignal(Tref, GSN_CNTR_START_CONF, signal,
+ CntrStartConf::SignalLength, JBB);
+
+ c_start.m_waiting.clear(nodeId);
+ c_start.m_withLog.clear(nodeId);
+ c_start.m_withoutLog.clear(nodeId);
+ c_start.m_starting.set(nodeId);
+#else
+ // Parallell nr
+
+ c_start.m_starting = c_start.m_waiting;
+ c_start.m_waiting.clear();
+
+ CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend();
+ conf->noStartNodes = 1;
+ conf->startGci = ~0; // Not used
+ conf->masterNodeId = getOwnNodeId();
+ c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes);
+ c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
+
+ char buf[100];
+ if(!c_start.m_withLog.isclear()){
+ ndbout_c("Starting nodes w/ log: %s", c_start.m_withLog.getText(buf));
+
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_withLog);
+ conf->startType = NodeState::ST_NODE_RESTART;
+
+ sendSignal(rg, GSN_CNTR_START_CONF, signal,
+ CntrStartConf::SignalLength, JBB);
+ }
+
+ if(!c_start.m_withoutLog.isclear()){
+ ndbout_c("Starting nodes wo/ log: %s", c_start.m_withoutLog.getText(buf));
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_withoutLog);
+ conf->startType = NodeState::ST_INITIAL_NODE_RESTART;
+
+ sendSignal(rg, GSN_CNTR_START_CONF, signal,
+ CntrStartConf::SignalLength, JBB);
+ }
+
+ c_start.m_waiting.clear();
+ c_start.m_withLog.clear();
+ c_start.m_withoutLog.clear();
+#endif
+}
+
+void
+Ndbcntr::sendCntrStartRef(Signal * signal,
+ Uint32 nodeId, CntrStartRef::ErrorCode code){
+ CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend();
+ ref->errorCode = code;
+ ref->masterNodeId = cmasterNodeId;
+ sendSignal(calcNdbCntrBlockRef(nodeId), GSN_CNTR_START_REF, signal,
+ CntrStartRef::SignalLength, JBB);
+}
+
+CheckNodeGroups::Output
+Ndbcntr::checkNodeGroups(Signal* signal, const NdbNodeBitmask & mask){
+ CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
+ sd->blockRef = reference();
+ sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
+ sd->mask = mask;
+ EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
+ CheckNodeGroups::SignalLength);
jamEntry();
+ return (CheckNodeGroups::Output)sd->output;
+}
- CntrMasterConf * const cntrMasterConf =
- (CntrMasterConf *)&signal->theData[0];
+bool
+Ndbcntr::trySystemRestart(Signal* signal){
+ /**
+ * System restart something
+ */
+ const bool allNodes = c_start.m_waiting.equal(c_allDefinedNodes);
+ const bool allClusterNodes = c_start.m_waiting.equal(c_clusterNodes);
+ const Uint64 now = NdbTick_CurrentMillisecond();
- cnoStartNodes = cntrMasterConf->noStartNodes;
- int index = 0;
- unsigned i;
- for (i = 1; i < MAX_NDB_NODES; i++) {
+ if(!allClusterNodes){
jam();
- if (NodeBitmask::get(cntrMasterConf->theNodes, i)) {
- jam();
- cstartNodes[index] = i;
- index++;
- }//if
- }//for
- if (cnoStartNodes != index) {
+ return false;
+ }
+
+ if(!allNodes && c_start.m_startPartialTimeout > now){
jam();
- systemErrorLab(signal);
- }//if
- ph2FLab(signal);
- return;
-}//Ndbcntr::execCNTR_MASTERCONF()
+ return false;
+ }
-void Ndbcntr::ph2FLab(Signal* signal)
-{
-/*--------------------------------------------------------------*/
-//The nodes have been selected and we now know which nodes are
-// included in the system restart. We can reset wait for CONTINUEB
-// flag to ensure system is not restarted when CONTINUEB after the
-// delay.
-/*--------------------------------------------------------------*/
- cmasterNodeId = cmasterCandidateId;
- cwaitContinuebFlag = ZFALSE;
- ph2GLab(signal);
- return;
-}//Ndbcntr::ph2FLab()
+ NodeState::StartType srType = NodeState::ST_SYSTEM_RESTART;
+ if(c_start.m_waiting.equal(c_start.m_withoutLog)){
+ if(!allNodes){
+ jam();
+ return false;
+ }
+ srType = NodeState::ST_INITIAL_START;
+ c_start.m_starting = c_start.m_withoutLog; // Used for starting...
+ c_start.m_withoutLog.clear();
+ } else {
+
+ CheckNodeGroups::Output wLog = checkNodeGroups(signal, c_start.m_withLog);
+
+ switch (wLog) {
+ case CheckNodeGroups::Win:
+ jam();
+ break;
+ case CheckNodeGroups::Lose:
+ jam();
+ // If we lose with all nodes, then we're in trouble
+ ndbrequire(!allNodes);
+ return false;
+ break;
+ case CheckNodeGroups::Partitioning:
+ jam();
+ bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0);
+
+ if(allNodes){
+ jam();
+ if(allowPartition){
+ jam();
+ break;
+ }
+ ndbrequire(false); // All nodes -> partitioning, which is not allowed
+ }
+
+ if(c_start.m_startPartitionedTimeout > now){
+ jam();
+ return false;
+ }
+ break;
+ }
+
+ // For now only with the "logged"-ones.
+ // Let the others do node restart afterwards...
+ c_start.m_starting = c_start.m_withLog;
+ c_start.m_withLog.clear();
+ }
+
+ /**
+ * Okidoki, we try to start
+ */
+ CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr();
+ conf->noStartNodes = c_start.m_starting.count();
+ conf->startType = srType;
+ conf->startGci = c_start.m_lastGci;
+ conf->masterNodeId = c_start.m_lastGciNodeId;
+ c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes);
+ c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
+
+ ndbrequire(c_start.m_lastGciNodeId == getOwnNodeId());
+
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
+ sendSignal(rg, GSN_CNTR_START_CONF, signal, CntrStartConf::SignalLength,JBB);
+
+ c_start.m_waiting.bitANDC(c_start.m_starting);
+
+ return true;
+}
-/*--------------------------------------*/
-/* RECEIVED CNTR_MASTERCONF */
-/*--------------------------------------*/
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-/*---------------------------------------------------------------------------*/
-// NOW WE CAN START NDB START PHASE 1. IN THIS PHASE ALL BLOCKS
-// (EXCEPT DIH THAT INITIALISED WHEN
-// RECEIVING DIH_RESTARTREQ) WILL INITIALISE THEIR DATA, COMMON VARIABLES,
-// LINKED LISTS AND RECORD VARIABLES.
-/*---------------------------------------------------------------------------*/
void Ndbcntr::ph2GLab(Signal* signal)
{
if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
@@ -879,11 +874,6 @@ void Ndbcntr::ph2GLab(Signal* signal)
/*******************************/
void Ndbcntr::startPhase3Lab(Signal* signal)
{
- cinternalStartphase = cstartPhase - 1;
-/*--------------------------------------*/
-/* CASE: CSTART_PHASE = ZSTART_PHASE_3 */
-/*--------------------------------------*/
- cndbBlocksCount = 0;
ph3ALab(signal);
return;
}//Ndbcntr::startPhase3Lab()
@@ -893,29 +883,12 @@ void Ndbcntr::startPhase3Lab(Signal* signal)
/*******************************/
void Ndbcntr::ph3ALab(Signal* signal)
{
- Uint16 tnoStartNodes;
-
if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
jam();
sendNdbSttor(signal);
return;
}//if
-/*******************************/
-/*< APPL_STARTREG <*/
-/*******************************/
- if (ctypeOfStart == NodeState::ST_NODE_RESTART) {
- jam();
- tnoStartNodes = 1;
- } else if (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART) {
- jam();
- tnoStartNodes = 1;
- } else {
- jam();
- tnoStartNodes = cnoStartNodes;
- }//if
- signal->theData[0] = cqmgrConnectionP;
- signal->theData[1] = tnoStartNodes;
- sendSignal(cqmgrBlockref, GSN_APPL_STARTREG, signal, 2, JBB);
+
sendSttorry(signal);
return;
}//Ndbcntr::ph3ALab()
@@ -933,49 +906,12 @@ void Ndbcntr::ph3ALab(Signal* signal)
/*******************************/
void Ndbcntr::startPhase4Lab(Signal* signal)
{
- cinternalStartphase = cstartPhase - 1;
-/*--------------------------------------*/
-/* CASE: CSTART_PHASE = ZSTART_PHASE_4 */
-/*--------------------------------------*/
- cndbBlocksCount = 0;
- cnoWaitrep = 0;
- if (capplStartconfFlag != ZTRUE) {
- jam();
-/*------------------------------------------------------*/
-/* HAVE WE ALREADY RECEIVED APPL_STARTCONF */
-/*------------------------------------------------------*/
- return;
- }//if
ph4ALab(signal);
- return;
}//Ndbcntr::startPhase4Lab()
-/*******************************/
-/* APPL_STARTCONF */
-/*******************************/
-void Ndbcntr::execAPPL_STARTCONF(Signal* signal)
-{
- jamEntry();
- if (cstartPhase == ZSTART_PHASE_4) {
- jam();
- ph4ALab(signal);
- return;
- } else {
- jam();
- capplStartconfFlag = ZTRUE;
-//------------------------------------------------
-/* FLAG WILL BE CHECKED WHEN WE RECEIVED STTOR */
-/* SIGNAL MAY BE RECEIVED IN STARTPHASE 3 */
-//------------------------------------------------
- return;
- }//if
-}//Ndbcntr::execAPPL_STARTCONF()
void Ndbcntr::ph4ALab(Signal* signal)
{
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- nodePtr.p->state = ZSTART;
ph4BLab(signal);
return;
}//Ndbcntr::ph4ALab()
@@ -1014,6 +950,7 @@ void Ndbcntr::waitpoint41Lab(Signal* signal)
cnoWaitrep++;
if (cnoWaitrep == cnoStartNodes) {
jam();
+ cnoWaitrep = 0;
/*---------------------------------------------------------------------------*/
// NDB_STARTREQ STARTS UP ALL SET UP OF DISTRIBUTION INFORMATION IN DIH AND
// DICT. AFTER SETTING UP THIS
@@ -1025,9 +962,9 @@ void Ndbcntr::waitpoint41Lab(Signal* signal)
// 3) EXECUTING THE FRAGMENT REDO LOG FROM ONE OR SEVERAL NODES TO
// RESTORE THE RESTART CONFIGURATION OF DATA IN NDB CLUSTER.
/*---------------------------------------------------------------------------*/
- signal->theData[0] = cownBlockref;
+ signal->theData[0] = reference();
signal->theData[1] = ctypeOfStart;
- sendSignal(cdihBlockref, GSN_NDB_STARTREQ, signal, 2, JBB);
+ sendSignal(DBDIH_REF, GSN_NDB_STARTREQ, signal, 2, JBB);
}//if
} else {
jam();
@@ -1037,11 +974,10 @@ void Ndbcntr::waitpoint41Lab(Signal* signal)
/* SLAVES WONT DO ANYTHING UNTIL THEY */
/* RECEIVE A WAIT REPORT FROM THE MASTER*/
/*--------------------------------------*/
- nodePtr.i = cmasterNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
signal->theData[0] = getOwnNodeId();
signal->theData[1] = ZWAITPOINT_4_1;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
+ sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
+ GSN_CNTR_WAITREP, signal, 2, JBB);
}//if
return;
}//Ndbcntr::waitpoint41Lab()
@@ -1052,23 +988,11 @@ void Ndbcntr::waitpoint41Lab(Signal* signal)
void Ndbcntr::execNDB_STARTCONF(Signal* signal)
{
jamEntry();
- UintR guard0;
- UintR Ttemp1;
- guard0 = cnoStartNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) {
- jam();
- if (cstartNodes[Ttemp1] != getOwnNodeId()) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_4_2;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
- }//if
- }//for
- sendSttorry(signal);
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
+ signal->theData[0] = getOwnNodeId();
+ signal->theData[1] = ZWAITPOINT_4_2;
+ sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
return;
}//Ndbcntr::execNDB_STARTCONF()
@@ -1084,9 +1008,6 @@ void Ndbcntr::execNDB_STARTCONF(Signal* signal)
/*******************************/
void Ndbcntr::startPhase5Lab(Signal* signal)
{
- cinternalStartphase = cstartPhase - 1;
- cndbBlocksCount = 0;
- cnoWaitrep = 0;
ph5ALab(signal);
return;
}//Ndbcntr::startPhase5Lab()
@@ -1147,16 +1068,17 @@ void Ndbcntr::ph5ALab(Signal* signal)
// SEND NDB START PHASE 5 IN NODE RESTARTS TO COPY DATA TO THE NEWLY
// STARTED NODE.
/*----------------------------------------------------------------------*/
- req->senderRef = cownBlockref;
+ req->senderRef = reference();
req->nodeId = getOwnNodeId();
req->internalStartPhase = cinternalStartphase;
req->typeOfStart = ctypeOfStart;
req->masterNodeId = cmasterNodeId;
+ //#define TRACE_STTOR
#ifdef TRACE_STTOR
ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase);
#endif
- sendSignal(cdihBlockref, GSN_NDB_STTOR, signal,
+ sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal,
NdbSttor::SignalLength, JBB);
return;
case NodeState::ST_INITIAL_START:
@@ -1170,11 +1092,10 @@ void Ndbcntr::ph5ALab(Signal* signal)
/* RECEIVE A WAIT REPORT FROM THE MASTER*/
/* WHEN THE MASTER HAS FINISHED HIS WORK*/
/*--------------------------------------*/
- nodePtr.i = cmasterNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
signal->theData[0] = getOwnNodeId();
signal->theData[1] = ZWAITPOINT_5_2;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
+ sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
+ GSN_CNTR_WAITREP, signal, 2, JBB);
return;
default:
ndbrequire(false);
@@ -1198,8 +1119,10 @@ void Ndbcntr::waitpoint52Lab(Signal* signal)
/*--------------------------------------*/
if (cnoWaitrep == cnoStartNodes) {
jam();
+ cnoWaitrep = 0;
+
NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
- req->senderRef = cownBlockref;
+ req->senderRef = reference();
req->nodeId = getOwnNodeId();
req->internalStartPhase = cinternalStartphase;
req->typeOfStart = ctypeOfStart;
@@ -1207,7 +1130,7 @@ void Ndbcntr::waitpoint52Lab(Signal* signal)
#ifdef TRACE_STTOR
ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase);
#endif
- sendSignal(cdihBlockref, GSN_NDB_STTOR, signal,
+ sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal,
NdbSttor::SignalLength, JBB);
}//if
return;
@@ -1218,28 +1141,19 @@ void Ndbcntr::waitpoint52Lab(Signal* signal)
/*******************************/
void Ndbcntr::ph6ALab(Signal* signal)
{
- UintR guard0;
- UintR Ttemp1;
-
if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
(ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
jam();
waitpoint51Lab(signal);
return;
}//if
- guard0 = cnoStartNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) {
- jam();
- if (cstartNodes[Ttemp1] != getOwnNodeId()) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_5_1;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
- }//if
- }//for
+
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
+ rg.m_nodes.clear(getOwnNodeId());
+ signal->theData[0] = getOwnNodeId();
+ signal->theData[1] = ZWAITPOINT_5_1;
+ sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
+
waitpoint51Lab(signal);
return;
}//Ndbcntr::ph6ALab()
@@ -1283,28 +1197,18 @@ void Ndbcntr::waitpoint61Lab(Signal* signal)
cnoWaitrep6++;
if (cnoWaitrep6 == cnoStartNodes) {
jam();
- Uint32 guard0 = cnoStartNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) {
- jam();
- if (cstartNodes[Ttemp1] != getOwnNodeId()) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_6_2;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
- }
- }
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
+ rg.m_nodes.clear(getOwnNodeId());
+ signal->theData[0] = getOwnNodeId();
+ signal->theData[1] = ZWAITPOINT_6_2;
+ sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
sendSttorry(signal);
}
} else {
jam();
- nodePtr.i = cmasterNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
signal->theData[0] = getOwnNodeId();
signal->theData[1] = ZWAITPOINT_6_1;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
+ sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
}
}
@@ -1339,28 +1243,18 @@ void Ndbcntr::waitpoint71Lab(Signal* signal)
cnoWaitrep7++;
if (cnoWaitrep7 == cnoStartNodes) {
jam();
- Uint32 guard0 = cnoStartNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) {
- jam();
- if (cstartNodes[Ttemp1] != getOwnNodeId()) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_7_2;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
- }
- }
+ NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
+ rg.m_nodes.clear(getOwnNodeId());
+ signal->theData[0] = getOwnNodeId();
+ signal->theData[1] = ZWAITPOINT_7_2;
+ sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
sendSttorry(signal);
}
} else {
jam();
- nodePtr.i = cmasterNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
signal->theData[0] = getOwnNodeId();
signal->theData[1] = ZWAITPOINT_7_1;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB);
+ sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
}
}
@@ -1378,315 +1272,11 @@ void Ndbcntr::ph8ALab(Signal* signal)
// NODES WHICH PERFORM A NODE RESTART NEEDS TO GET THE DYNAMIC ID'S
// OF THE OTHER NODES HERE.
/*---------------------------------------------------------------------------*/
- signal->theData[0] = cqmgrConnectionP;
- sendSignal(cqmgrBlockref, GSN_APPL_RUN, signal, 1, JBB);
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- nodePtr.p->state = ZRUN;
- cnoRunNodes = cnoRunNodes + 1;
sendSttorry(signal);
- cstartProgressFlag = ZFALSE;
- ctypeOfStart = (NodeState::StartType)ZSYSTEM_RUN;
resetStartVariables(signal);
return;
}//Ndbcntr::ph8BLab()
-/*
-4.7 HANDLE GLOBAL EVENTS, NOT BOUNDED TO INITIALSTART OR SYSTEM RESTART */
-/*#######################################################################*/
-/*******************************/
-/* APPL_CHANGEREP */
-/*******************************/
-void Ndbcntr::execAPPL_CHANGEREP(Signal* signal)
-{
- jamEntry();
- Uint16 TapplEvent = signal->theData[0];
- Uint16 TapplVersion = signal->theData[1];
- Uint16 TapplNodeId = signal->theData[2];
- Uint16 TapplSubType = signal->theData[3];
-
- nodePtr.i = TapplNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- nodePtr.p->subType = TapplSubType;
- nodePtr.p->ndbVersion = TapplVersion;
- nodePtr.p->dynamicId = signal->theData[4];
-
- switch (TapplEvent) {
- case ZADD:
-/*----------------------------*/
-/* ADD A NEW NDB NODE TO FILE */
-/*----------------------------*/
- if (nodePtr.p->state == ZREMOVE) {
- jam();
- if (cnoRegNodes == cnoNdbNodes) {
- jam();
-/*----------------------------------------------*/
-/* DON'T ACCEPT MORE NODES THAN SYSFILE.CFG SPEC*/
-/*----------------------------------------------*/
- systemErrorLab(signal);
- return;
- }//if
- nodePtr.p->state = ZADD;
- cnoRegNodes = cnoRegNodes + 1;
- } else {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- if (cstartProgressFlag == ZFALSE) {
-/*----------------------------------------------*/
-/* FLAG = TRUE WHEN CNTR_MASTERREQ IS SENT */
-/*----------------------------------------------*/
- switch (ctypeOfStart) {
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- ph2CLab(signal);
-/*----------------------------------------------*/
-/* CHECK IF READY TO MAKE A CNTR_MASTERREQ */
-/*----------------------------------------------*/
- break;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
-/*------------------------------------------------------------------------*/
-/* THIS SHOULD NEVER OCCUR SINCE WE HAVE ALREADY BEEN ALLOWED TO */
-/* START OUR NODE. THE NEXT NODE CANNOT START UNTIL WE ARE FINISHED */
-/*------------------------------------------------------------------------*/
- systemErrorLab(signal);
- break;
- case ZSYSTEM_RUN:
- jam();
- /*empty*/;
- break;
- default:
- jam();
-/*------------------------------------------------------------------------*/
-/* NO PARTICULAR ACTION IS NEEDED. THE NODE WILL PERFORM A NODE */
-/* RESTART BUT NO ACTION IS NEEDED AT THIS STAGE IN THE RESTART. */
-/*------------------------------------------------------------------------*/
- systemErrorLab(signal);
- break;
- }//switch
- } else {
- jam();
-/*--------------------------------------------------------------------------*/
-// WHEN A RESTART IS IN PROGRESS THERE IS A POSSIBILITY THAT A NODE
-// REGISTER AND
-// THINKS THAT HE WOULD BE THE MASTER (LOWER NODE ID) BUT THE OTHER NODE IS
-// ALREADY RUNNING THE RESTART. THIS WILL BE DETECTED WHEN HE ATTEMPTS A
-// CNTR_MASTERREQ AND RECEIVES A REFUSE SIGNAL IN RETURN. THIS WILL CAUSE HIM
-// TO CRASH. IF HE ATTEMPTS TO JOIN AS A NON-MASTER HE WILL WAIT FOR THE MASTER.
-// IN THIS CASE IT IS BETTER TO SHOT HIM DOWN. FOR SAFETY REASONS WE WILL ALWAYS
-// SHOT HIM DOWN.
-/*--------------------------------------------------------------------------*/
- const BlockReference tblockref = calcNdbCntrBlockRef(nodePtr.i);
-
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::StartInProgressError;
- sysErr->errorRef = reference();
- sendSignal(tblockref, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA);
- }//if
- break;
- case ZSTART:
- jam();
- if (nodePtr.p->state != ZADD) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- nodePtr.p->state = ZSTART;
- break;
- case ZRUN:
- if (nodePtr.p->state == ZREMOVE) {
- jam();
- cnoRegNodes = cnoRegNodes + 1;
- } else {
- jam();
- if (nodePtr.p->state != ZSTART) {
- jam();
-/*----------------------------------------------*/
-/* STATE ZADD OR ZRUN -> ZRUN NOT ALLOWED */
-/*----------------------------------------------*/
- systemErrorLab(signal);
- return;
- }//if
- }//if
- cnoRunNodes = cnoRunNodes + 1;
- nodePtr.p->state = ZRUN;
- switch (ctypeOfStart) {
- case NodeState::ST_INITIAL_START:
- jam();
- detectNoderestart(signal);
- if (ctypeOfStart == NodeState::ST_NODE_RESTART) {
- jam();
-/*--------------------------------------------------------------------------*/
-/* WE DISCOVERED THAT WE ARE TRYING TO PERFORM A INITIAL START WHEN THERE */
-/* ARE ALREADY RUNNING NODES. THIS MEANS THAT THE NODE HAS CLEANED THE */
-/* FILE SYSTEM AND CONTAINS NO DATA. THIS IS AN INITIAL NODE RESTART WHICH */
-/* IS NECESSARY TO START A NODE THAT HAS BEEN TAKEN OVER. */
-/*--------------------------------------------------------------------------*/
- ctypeOfStart = NodeState::ST_INITIAL_NODE_RESTART;
- }//if
- break;
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- detectNoderestart(signal);
-/*----------------------------------------------*/
-/* SHOULD THIS NODE PERFORM A NODE RESTART? */
-/* THEN CHANGE CTYPE_OF_START TO NodeState::ST_NODE_RESTART */
-/* AND SEND NODE_STATESREQ. */
-/* WAIT FOR NODE_STATESCONF. */
-/*----------------------------------------------*/
- break;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
-/*----------------------------------------------*/
-/* IF WE ARE WAITING FOR NODE_STATESCONF, THIS */
-/* JUMP WILL EXIT BECAUSE CNO_NEED_NODES = ZNIL */
-/* UNTIL WE RECEIVE NODE_STATESCONF */
-/*----------------------------------------------*/
- ph2CLab(signal);
- break;
- case ZSYSTEM_RUN:
- jam();
- break;
- default:
- jam();
- systemErrorLab(signal);
- break;
- }//switch
- break;
- default:
- jam();
- systemErrorLab(signal);
- break;
- }//switch
- return;
-}//Ndbcntr::execAPPL_CHANGEREP()
-
-/*--------------------------------------------------------------------------*/
-// A NODE HAS ADDED HAS VOTE ON WHICH MASTER IS TO BE CHOOSEN IN A SYSTEM
-// RESTART. WHEN ALL VOTES HAVE
-// BEEN ADDED THEN WE ARE PREPARED TO CHOOSE MASTER AND CONTINUE WITH THE
-// RESTART PROCESSING.
-/*--------------------------------------------------------------------------*/
-
-/*******************************/
-/* VOT_MASTERORD */
-/*******************************/
-void Ndbcntr::execVOTE_MASTERORD(Signal* signal)
-{
- jamEntry();
- nodePtr.i = signal->theData[0];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- UintR TmasterCandidateId = signal->theData[1];
- UintR TlastGci = signal->theData[2];
- if (ctypeOfStart != NodeState::ST_SYSTEM_RESTART) {
- jam();
- progError(__LINE__,
- ERR_SR_RESTARTCONFLICT,
- "One ore more nodes probably requested an initial SR");
- return;
- }//if
- cmasterVoters = cmasterVoters + 1;
- if (cmasterVoters == 1) {
- jam();
- cmasterCurrentId = TmasterCandidateId;
- cmasterLastGci = TlastGci;
- } else {
- if (cmasterLastGci < TlastGci) {
- jam();
- cmasterCurrentId = TmasterCandidateId;
- cmasterLastGci = TlastGci;
- } else if (cmasterLastGci == TlastGci) {
- jam();
- if (cmasterCurrentId != TmasterCandidateId) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- }//if
- }//if
- if (cstartProgressFlag == ZVOTING) {
-/*--------------------------------------------------------------------------*/
-// UNLESS START PROGRESS FLAG IS SET TO VOTING WE HAVE NOT YET REACHED A
-// STATE WHERE WE ARE READY TO
-// PROCEED WITH THE SYSTEM RESTART. OUR OWN NOTE HAVE AT LEAST NOT BEEN
-// CAST INTO THE BALLOT YET.
-/*--------------------------------------------------------------------------*/
- if (cmasterVoters == cnoRegNodes) {
- cmasterCandidateId = cmasterCurrentId;
- if (cmasterCandidateId == getOwnNodeId()) {
- jam();
- masterreq020Lab(signal);
- return;
- } else {
- jam();
- cstartProgressFlag = ZTRUE;
- sendCntrMasterreq(signal);
- resetStartVariables(signal);
- }//if
- }//if
- }//if
- return;
-}//Ndbcntr::execVOTE_MASTERORD()
-
-/*******************************/
-/* CNTR_MASTERREQ */
-/*******************************/
-void Ndbcntr::execCNTR_MASTERREQ(Signal* signal)
-{
- Uint16 ttypeOfStart;
-
- jamEntry();
-
- CntrMasterReq * const cntrMasterReq =
- (CntrMasterReq *)&signal->theData[0];
-
-//-----------------------------------------------
-// cntrMasterReq->userBlockRef NOT USED
-//-----------------------------------------------
- Uint16 TuserNodeId = cntrMasterReq->userNodeId;
- ttypeOfStart = cntrMasterReq->typeOfStart;
- Uint16 TnoRestartNodes = cntrMasterReq->noRestartNodes;
- int index = 0;
- unsigned i;
- for (i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if (NodeBitmask::get(cntrMasterReq->theNodes, i)) {
- jam();
- cstartNodes[index] = i;
- index++;
- }//if
- }//for
- if (TnoRestartNodes != index) {
- jam();
- systemErrorLab(signal);
- }//if
- switch (ttypeOfStart) {
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
-//--------------------------------
-/* ELECTION OF MASTER AT */
-/* INITIAL OR SYSTEM RESTART */
-//--------------------------------
- masterreq010Lab(signal, TnoRestartNodes, TuserNodeId);
- break;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- masterreq030Lab(signal, TnoRestartNodes, TuserNodeId);
- break;
- default:
- jam();
- systemErrorLab(signal);
- break;
- }//switch
-}//Ndbcntr::execCNTR_MASTERREQ()
-
/*******************************/
/* CNTR_WAITREP */
/*******************************/
@@ -1736,243 +1326,102 @@ void Ndbcntr::execCNTR_WAITREP(Signal* signal)
}//switch
}//Ndbcntr::execCNTR_WAITREP()
-/*
-4.7.4 MASTERREQ_010 ( CASE: INITIALSTART OR SYSTEMRESTART ) */
-/*--------------------------------------------------------------------------*/
-// ELECTION OF MASTER AND ELECTION OF PARTICIPANTS IN START. SENDER OF
-// CNTR_MASTERREQ THINKS THAT THIS NODE
-// SHOULD BE THE MASTER. WE CAN'T MAKE A DECISION ABOUT WHO THE MASTER
-// SHOULD BE UNTIL TIMELIMIT HAS EXPIRED AND
-// THAT AT LEAST CNO_NEED_NODES ARE ZADD IN NODE_PTR_REC. IF THIS NODE IS
-// MASTER THEN MAKE SURE THAT ALL NODES IN
-// THE CLUSTER COMES TO AN AGREEMENT ABOUT A SUBSET OF NODES THAT SATISFIES
-// THE NUMBER CNO_NEED_NODES. THERE IS
-// A POSSIBILITY THAT THE RECEIVER OF CNTR_MASTERREQ DOESN'T HAS CHOOSEN
-// A MASTER, THEN THE RECEIVER CAN'T
-// EITHER CONFIRM OR REFUSE JUST STORE THE VOTES OF THE CLUSTERMEMBERS.
-// IF THIS NODE BECOME AWARE OF THAT ANOTHER NODE IS MASTER THEN CHECK IF
-// ANYONE HAS VOTED (SENT CNTR_MASTERREQ) */
-// AND THEN SEND THEM CNTR_MASTERREF BACK.
-/*--------------------------------------------------------------------------*/
-void Ndbcntr::masterreq010Lab(Signal* signal,
- Uint16 TnoRestartNodes,
- Uint16 TuserNodeId)
-{
- UintR guard0;
- UintR Ttemp1;
-
- nodePtr.i = TuserNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- if (cstartProgressFlag == ZTRUE) {
- jam();
-/*--------------------------------------*/
-/* RESTART ALREADY IN PROGRESS */
-/*--------------------------------------*/
- if (ctypeOfStart == NodeState::ST_INITIAL_START) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- signal->theData[0] = cownBlockref;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = ZSTART_IN_PROGRESS_ERROR;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB);
- return;
- }//if
- cnoVoters = cnoVoters + 1;
- nodePtr.p->voter = ZTRUE;
- guard0 = TnoRestartNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- nodePtr.p->votes = nodePtr.p->votes + 1;
- }//for
- masterreq020Lab(signal);
- return;
-}//Ndbcntr::masterreq010Lab()
-
-/*----------------------------------------------------------------------*/
-/* WHEN WE JUST WANT TO CHECK OUR VOTES IT IS POSSIBLE TO JUMP TO THIS */
-/* LABEL. IF WE HAVEN'T RECEIVED ANY VOTES SINCE OUR LASTCHECK WE WILL */
-/* JUST PERFORM AN EXIT */
-/*----------------------------------------------------------------------*/
-void Ndbcntr::masterreq020Lab(Signal* signal)
-{
- if (cmasterCandidateId == ZNIL) {
- jam();
-/*--------------------------------------*/
-/* MASTER UNKNOWN */
-/*--------------------------------------*/
- return;
- } else if (cmasterCandidateId == getOwnNodeId()) {
- jam();
-/*--------------------------------------*/
-/* SATISFIED WHEN WE HAVE AS MANY VOTERS*/
-/* AS RESTARTNODES - 1, DIFFERENT NODES?*/
-/* <- CNO_START_NODES, ALL NODES AGREED */
-/* ON THESE CNO_START_NODES */
-/*--------------------------------------*/
- if ((cnoStartNodes - 1) == cnoVoters) {
- chooseRestartNodes(signal);
- if (cnoStartNodes >= cnoNeedNodes) {
- jam();
- cstartProgressFlag = ZTRUE;
-/*--------------------------------------*/
-/* DON'T SEND ANY MORE CNTR_MASTERREQ */
-/*--------------------------------------*/
- replyMasterconfToAll(signal);
-/*--------------------------------------*/
-/* SEND CONF TO ALL PASSED REQ */
-/* DON'T SEND ANYTHING TO REJECTED NODES*/
-/* BLOCK THEM UNTIL SYSTEM IS RUNNING */
-/* CONTINUE RESTART */
-/*--------------------------------------*/
- ph2FLab(signal);
- } else {
- jam();
- systemErrorLab(signal);
- }//if
- }//if
- } else {
- jam();
-/*----------------------------------------------------------------------*/
-/* WE RECEIVED A REQUEST TO A MASTER WHILE NOT BEING MASTER. THIS */
-/* MUST BE AN ERROR INDICATION. WE CRASH. */
-/*----------------------------------------------------------------------*/
- systemErrorLab(signal);
- }//if
- return; /* WAIT FOR MORE CNTR_MASTERREQ */
-}//Ndbcntr::masterreq020Lab()
-
-void Ndbcntr::masterreq030Lab(Signal* signal,
- Uint16 TnoRestartNodes,
- Uint16 TuserNodeId)
-{
- UintR TretCode;
- if (cmasterNodeId == getOwnNodeId()) {
- jam();
- TretCode = checkNodelist(signal, TnoRestartNodes);
- nodePtr.i = TuserNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- if (TretCode == 1) {
- jam();
-/*******************************************************<*/
-/* CSTART_NODES IS OVERWRITTEN IN RECEIVING BLOCK, */
-/* SO WE MUST SEND CNTR_MASTERCONF TO THE SAME */
-/* CSTART_NODES AS WE RECEIVED IN CNTR_MASTERREQ */
-/*******************************************************<*/
-
- CntrMasterConf * const cntrMasterConf =
- (CntrMasterConf *)&signal->theData[0];
- NodeBitmask::clear(cntrMasterConf->theNodes);
- for (int i = 0; i < TnoRestartNodes; i++){
- jam();
- UintR Tnode = cstartNodes[i];
- arrGuard(Tnode, MAX_NDB_NODES);
- NodeBitmask::set(cntrMasterConf->theNodes, Tnode);
- }//for
- cntrMasterConf->noStartNodes = TnoRestartNodes;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERCONF,
- signal, CntrMasterConf::SignalLength, JBB);
- } else {
- jam();
- signal->theData[0] = cownBlockref;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = ZTOO_FEW_NODES;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB);
- }//if
- } else {
- jam();
- nodePtr.i = TuserNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = cownBlockref;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = ZNOT_MASTER;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB);
- }//if
- return;
-}//Ndbcntr::masterreq030Lab()
-
/*******************************/
/* NODE_FAILREP */
/*******************************/
void Ndbcntr::execNODE_FAILREP(Signal* signal)
{
- UintR TfailureNr;
- UintR TnoOfNodes;
- UintR TreadNodes[MAX_NDB_NODES];
-
jamEntry();
+ const NodeFailRep * nodeFail = (NodeFailRep *)&signal->theData[0];
+ NdbNodeBitmask allFailed;
+ allFailed.assign(NdbNodeBitmask::Size, nodeFail->theNodes);
+
+ NdbNodeBitmask failedStarted = c_startedNodes;
+ NdbNodeBitmask failedStarting = c_start.m_starting;
+ NdbNodeBitmask failedWaiting = c_start.m_waiting;
+
+ failedStarted.bitAND(allFailed);
+ failedStarting.bitAND(allFailed);
+ failedWaiting.bitAND(allFailed);
+
+ const bool tMasterFailed = allFailed.get(cmasterNodeId);
+ const bool tStarted = !failedStarted.isclear();
+ const bool tStarting = !failedStarting.isclear();
+ const bool tWaiting = !failedWaiting.isclear();
+
+ if(tMasterFailed){
+ jam();
+ /**
+ * If master has failed choose qmgr president as master
+ */
+ cmasterNodeId = nodeFail->masterNodeId;
+ }
+
+ /**
+ * Clear node bitmasks from failed nodes
+ */
+ c_start.m_starting.bitANDC(allFailed);
+ c_start.m_waiting.bitANDC(allFailed);
+ c_start.m_withLog.bitANDC(allFailed);
+ c_start.m_withoutLog.bitANDC(allFailed);
+ c_clusterNodes.bitANDC(allFailed);
+ c_startedNodes.bitANDC(allFailed);
+
const NodeState & st = getNodeState();
if(st.startLevel == st.SL_STARTING){
- if(!st.getNodeRestartInProgress()){
+ jam();
+
+ const Uint32 phase = st.starting.startPhase;
+
+ const bool tStartConf = (phase > 2) || (phase == 2 && cndbBlocksCount > 0);
+
+ if(tMasterFailed){
progError(__LINE__,
ERR_SR_OTHERNODEFAILED,
- "Unhandled node failure during system restart");
+ "Unhandled node failure during restart");
+ }
+
+ if(tStartConf && tStarting){
+ // One of other starting nodes has crashed...
+ progError(__LINE__,
+ ERR_SR_OTHERNODEFAILED,
+ "Unhandled node failure of starting node during restart");
}
- }
-
- {
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
- TfailureNr = nodeFail->failNo;
- TnoOfNodes = nodeFail->noOfNodes;
- unsigned index = 0;
- unsigned i;
- for (i = 0; i < MAX_NDB_NODES; i++) {
- jam();
- if (NodeBitmask::get(nodeFail->theNodes, i)) {
- jam();
- TreadNodes[index] = i;
- index++;
- ndbrequire(getOwnNodeId() != i);
- }//if
+ if(tStartConf && tStarted){
+ // One of other started nodes has crashed...
+ progError(__LINE__,
+ ERR_SR_OTHERNODEFAILED,
+ "Unhandled node failure of started node during restart");
+ }
+
+ Uint32 nodeId = 0;
+ while(!allFailed.isclear()){
+ nodeId = allFailed.find(nodeId + 1);
+ allFailed.clear(nodeId);
+ signal->theData[0] = nodeId;
+ sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
}//for
- ndbrequire(TnoOfNodes == index);
+
+ return;
}
- for (Uint32 i = 0; i < TnoOfNodes; i++) {
- jam();
- nodePtr.i = TreadNodes[i];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = EventReport::NODE_FAILREP;
- signal->theData[1] = nodePtr.i;
- signal->theData[2] = nodePtr.p->state;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- if (nodePtr.p->state != ZREMOVE) {
- jam();
- deleteNode(signal);
- }//if
- }//for
+ ndbrequire(!allFailed.get(getOwnNodeId()));
-/*******************************/
-/*< NODE_FAILREP <*/
-/*******************************/
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- nodeFail->failNo = TfailureNr;
- nodeFail->masterNodeId = cmasterNodeId;
+ NodeFailRep * rep = (NodeFailRep *)&signal->theData[0];
+ rep->masterNodeId = cmasterNodeId;
- nodeFail->noOfNodes = TnoOfNodes;
- NodeBitmask::clear(nodeFail->theNodes);
- for (unsigned i = 0; i < TnoOfNodes; i++) {
- jam();
- NodeBitmask::set(nodeFail->theNodes, TreadNodes[i]);
- }//for
-
- sendSignal(ctcBlockref, GSN_NODE_FAILREP, signal,
+ sendSignal(DBTC_REF, GSN_NODE_FAILREP, signal,
NodeFailRep::SignalLength, JBB);
- sendSignal(clqhBlockref, GSN_NODE_FAILREP, signal,
+ sendSignal(DBLQH_REF, GSN_NODE_FAILREP, signal,
NodeFailRep::SignalLength, JBB);
- sendSignal(cdihBlockref, GSN_NODE_FAILREP, signal,
+ sendSignal(DBDIH_REF, GSN_NODE_FAILREP, signal,
NodeFailRep::SignalLength, JBB);
- sendSignal(cdictBlockref, GSN_NODE_FAILREP, signal,
+ sendSignal(DBDICT_REF, GSN_NODE_FAILREP, signal,
NodeFailRep::SignalLength, JBB);
sendSignal(BACKUP_REF, GSN_NODE_FAILREP, signal,
@@ -1983,80 +1432,25 @@ void Ndbcntr::execNODE_FAILREP(Signal* signal)
sendSignal(GREP_REF, GSN_NODE_FAILREP, signal,
NodeFailRep::SignalLength, JBB);
- return;
-}//Ndbcntr::execNODE_FAILREP()
-/*******************************/
-/* NODE_STATESCONF */
-/*******************************/
-void Ndbcntr::execNODE_STATESCONF(Signal* signal)
-{
- jamEntry();
- cmasterCandidateId = signal->theData[0];
- cnoNeedNodes = signal->theData[1];
-/*----------------------------------------------------------------------*/
-// Now that we have knowledge of how many nodes are needed we will call
-// ph2CLab to ensure that node restart continues if we already received
-// all APPL_CHANGEREP signals.
-/*----------------------------------------------------------------------*/
- ph2CLab(signal);
- return;
-}//Ndbcntr::execNODE_STATESCONF()
-
-/*******************************/
-/* NODE_STATESREF */
-/*******************************/
-void Ndbcntr::execNODE_STATESREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal);
- return;
-}//Ndbcntr::execNODE_STATESREF()
+ Uint32 nodeId = 0;
+ while(!allFailed.isclear()){
+ nodeId = allFailed.find(nodeId + 1);
+ allFailed.clear(nodeId);
+ signal->theData[0] = EventReport::NODE_FAILREP;
+ signal->theData[1] = nodeId;
+ signal->theData[2] = 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
+ }//for
-/*******************************/
-/* NODE_STATESREQ */
-/*******************************/
-void Ndbcntr::execNODE_STATESREQ(Signal* signal)
-{
- UintR TnoNeedNodes = 0;
- NodeRecPtr TNodePtr;
- jamEntry();
- BlockReference TuserBlockref = signal->theData[0];
-/*----------------------------------------------------------------------*/
-// IF WE ARE RUNNING, WE WILL ANSWER THIS SIGNAL WITH THE AMOUNT OF NODES
-// THAT ARE IN THE RUN STATE OR START STATE.
-/*----------------------------------------------------------------------*/
- TNodePtr.i = getOwnNodeId();
- ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec);
- if (TNodePtr.p->state == ZRUN) {
- jam();
- for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) {
- jam();
- ptrAss(TNodePtr, nodeRec);
- if ((TNodePtr.p->state == ZRUN) ||
- (TNodePtr.p->state == ZSTART)) {
- jam();
- TnoNeedNodes++;
- }//if
- }//for
- signal->theData[0] = cmasterNodeId;
- signal->theData[1] = TnoNeedNodes;
- sendSignal(TuserBlockref, GSN_NODE_STATESCONF, signal, 2, JBB);
- } else {
- jam();
- signal->theData[0] = ZERROR_NOT_RUNNING;
- sendSignal(TuserBlockref, GSN_NODE_STATESREF, signal, 1, JBB);
- }//if
return;
-}//Ndbcntr::execNODE_STATESREQ()
+}//Ndbcntr::execNODE_FAILREP()
/*******************************/
/* READ_NODESREQ */
/*******************************/
void Ndbcntr::execREAD_NODESREQ(Signal* signal)
{
- UintR TnoNodes = 0;
- NodeRecPtr TNodePtr;
jamEntry();
/*----------------------------------------------------------------------*/
@@ -2067,59 +1461,36 @@ void Ndbcntr::execREAD_NODESREQ(Signal* signal)
BlockReference TuserBlockref = signal->theData[0];
ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
- if (cstartPhase > ZSTART_PHASE_2) {
- ndbrequire(cstartProgressFlag == ZTRUE);
-
- NodeBitmask::clear(readNodes->allNodes);
- NodeBitmask::clear(readNodes->inactiveNodes);
-
- /**
- * Add started nodes
- */
- for (int i = 0; i < cnoStartNodes; i++){
- jam();
- TNodePtr.i = cstartNodes[i];
- ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec);
-
- NodeBitmask::set(readNodes->allNodes, TNodePtr.i);
- readNodes->setVersionId(TNodePtr.i, TNodePtr.p->ndbVersion,
- readNodes->theVersionIds);
- TnoNodes++;
- }//for
-
- /**
- * Sometimes add myself
- */
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
-
- NodeBitmask::set(readNodes->allNodes, getOwnNodeId());
- readNodes->setVersionId(getOwnNodeId(), NDB_VERSION,
- readNodes->theVersionIds);
- TnoNodes++;
- }//if
- /**
- * Check all nodes which are defined but not already added
- */
- for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) {
- jam();
- ptrAss(TNodePtr, nodeRec);
- if ((TNodePtr.p->nodeDefined == ZTRUE) &&
- (NodeBitmask::get(readNodes->allNodes, TNodePtr.i) == false)){
- jam();
+ /**
+ * Prepare inactiveNodes bitmask.
+ * The concept as such is by the way pretty useless.
+ * It makes parallell starts more or less impossible...
+ */
+ NdbNodeBitmask tmp1;
+ tmp1.bitOR(c_startedNodes);
+ if(!getNodeState().getNodeRestartInProgress()){
+ tmp1.bitOR(c_start.m_starting);
+ } else {
+ tmp1.set(getOwnNodeId());
+ }
- NodeBitmask::set(readNodes->allNodes, TNodePtr.i);
- NodeBitmask::set(readNodes->inactiveNodes, TNodePtr.i);
- readNodes->setVersionId(TNodePtr.i, NDB_VERSION,
- readNodes->theVersionIds);
-
- TnoNodes++;
- }//if
- }//for
-
- readNodes->noOfNodes = TnoNodes;
- readNodes->masterNodeId = cmasterNodeId;
+ NdbNodeBitmask tmp2;
+ tmp2.bitOR(c_allDefinedNodes);
+ tmp2.bitANDC(tmp1);
+ /**
+ * Fill in return signal
+ */
+ tmp2.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes);
+ c_allDefinedNodes.copyto(NdbNodeBitmask::Size, readNodes->allNodes);
+ c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes);
+ c_startedNodes.copyto(NdbNodeBitmask::Size, readNodes->startedNodes);
+ c_start.m_starting.copyto(NdbNodeBitmask::Size, readNodes->startingNodes);
+
+ readNodes->noOfNodes = c_allDefinedNodes.count();
+ readNodes->masterNodeId = cmasterNodeId;
+ readNodes->ndynamicId = cdynamicNodeId;
+ if (cstartPhase > ZSTART_PHASE_2) {
+ jam();
sendSignal(TuserBlockref, GSN_READ_NODESCONF, signal,
ReadNodesConf::SignalLength, JBB);
@@ -2237,8 +1608,8 @@ void Ndbcntr::startInsertTransactions(Signal* signal)
ckey = 1;
ctransidPhase = ZTRUE;
- signal->theData[1] = cownBlockref;
- sendSignal(ctcBlockref, GSN_TCSEIZEREQ, signal, 2, JBB);
+ signal->theData[1] = reference();
+ sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB);
return;
}//Ndbcntr::startInsertTransactions()
@@ -2312,7 +1683,7 @@ void Ndbcntr::crSystab7Lab(Signal* signal)
AttributeHeader::init(&tAIDataPtr[2], 1, 2);
tAIDataPtr[3] = (tkey << 16);
tAIDataPtr[4] = 1;
- sendSignal(ctcBlockref, GSN_TCKEYREQ, signal,
+ sendSignal(DBTC_REF, GSN_TCKEYREQ, signal,
TcKeyReq::StaticLength + 6, JBB);
}//for
ckey = ckey + RowsPerCommit;
@@ -2335,7 +1706,7 @@ void Ndbcntr::execTCKEYCONF(Signal* signal)
Uint32 transId2 = keyConf->transId2;
signal->theData[0] = transId1;
signal->theData[1] = transId2;
- sendSignal(ctcBlockref, GSN_TC_COMMIT_ACK, signal, 2, JBB);
+ sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB);
}//if
cresponses = cresponses + TcKeyConf::getNoOfOperations(confInfo);
@@ -2363,8 +1734,8 @@ void Ndbcntr::crSystab8Lab(Signal* signal)
return;
}//if
signal->theData[0] = ctcConnectionP;
- signal->theData[1] = cownBlockref;
- sendSignal(ctcBlockref, GSN_TCRELEASEREQ, signal, 2, JBB);
+ signal->theData[1] = reference();
+ sendSignal(DBTC_REF, GSN_TCRELEASEREQ, signal, 2, JBB);
return;
}//Ndbcntr::crSystab8Lab()
@@ -2380,8 +1751,8 @@ void Ndbcntr::execTCRELEASECONF(Signal* signal)
void Ndbcntr::crSystab9Lab(Signal* signal)
{
- signal->theData[1] = cownBlockref;
- sendSignalWithDelay(cdihBlockref, GSN_GETGCIREQ, signal, 100, 2);
+ signal->theData[1] = reference();
+ sendSignalWithDelay(DBDIH_REF, GSN_GETGCIREQ, signal, 100, 2);
return;
}//Ndbcntr::crSystab9Lab()
@@ -2435,309 +1806,28 @@ void Ndbcntr::execTCSEIZEREF(Signal* signal)
return;
}//Ndbcntr::execTCSEIZEREF()
-/*
-4.10 SUBROUTINES */
-/*##########################################################################*/
-/*
-4.10.1 CHECK_NODELIST */
-/*---------------------------------------------------------------------------*/
-/*CHECK THAT ALL THE NEW NODE HAS DETECTED ALL RUNNING NODES */
-/*INPUT: CSTART_NODES */
-/* TNO_RESTART_NODES */
-/* TUSER_NODE_ID */
-/*RET: CNODE_RESTART */
-/*---------------------------------------------------------------------------*/
-UintR Ndbcntr::checkNodelist(Signal* signal, Uint16 TnoRestartNodes)
-{
- UintR guard1;
- UintR Ttemp1;
-
- if (cnoRunNodes == TnoRestartNodes) {
- jam();
- guard1 = TnoRestartNodes - 1;
- arrGuard(guard1, MAX_NDB_NODES);
- for (Ttemp1 = 0; Ttemp1 <= guard1; Ttemp1++) {
- jam();
- nodePtr.i = cstartNodes[Ttemp1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- if (nodePtr.p->state != ZRUN) {
- jam();
- return 0;
- }//if
- }//for
- return 1;
- }//if
- return 0;
-}//Ndbcntr::checkNodelist()
-
-/*---------------------------------------------------------------------------*/
-// SELECT NODES THAT ARE IN THE STATE TO PERFORM A INITIALSTART OR
-// SYSTEMRESTART.
-// THIS SUBROUTINE CAN ONLY BE INVOKED BY THE MASTER NODE.
-// TO BE CHOOSEN A NODE NEED AS MANY VOTES AS THERE ARE VOTERS, AND OF
-// COURSE THE NODE HAS TO BE KNOWN BY THE
-// MASTER
-// INPUT: NODE_REC
-// CNO_NEED_NODES
-// RETURN:CNO_START_NODES
-// CSTART_NODES
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::chooseRestartNodes(Signal* signal)
-{
- cnoStartNodes = 0;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->votes == cnoVoters) {
- jam();
- if (nodePtr.p->state == ZADD) {
- jam();
- arrGuard(cnoStartNodes, MAX_NDB_NODES);
- cstartNodes[cnoStartNodes] = nodePtr.i;
- cnoStartNodes++;
- }//if
- } else {
- jam();
- if (nodePtr.p->votes > 0) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- }//if
- }//for
-}//Ndbcntr::chooseRestartNodes()
-
-/*
-4.10.6 DELETE_NODE */
-/*---------------------------------------------------------------------------*/
-// INPUT: NODE_PTR
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::deleteNode(Signal* signal)
-{
- UintR tminDynamicId;
-
- if (nodePtr.p->state == ZRUN) {
- jam();
- cnoRunNodes = cnoRunNodes - 1;
- }//if
- nodePtr.p->state = ZREMOVE;
- nodePtr.p->votes = 0;
- nodePtr.p->voter = ZFALSE;
- cnoRegNodes--;
- if (nodePtr.i == cmasterNodeId) {
- jam();
- cmasterNodeId = ZNIL;
-/*---------------------------------------------------------------------------*/
-// IF MASTER HAVE CRASHED WE NEED TO SELECT A NEW MASTER.
-/*---------------------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->state == ZRUN) {
- if (cmasterNodeId == ZNIL) {
- jam();
- cmasterNodeId = nodePtr.i;
- tminDynamicId = nodePtr.p->dynamicId;
- } else {
- jam();
- if (nodePtr.p->dynamicId < tminDynamicId) {
- jam();
- cmasterNodeId = nodePtr.i;
- tminDynamicId = nodePtr.p->dynamicId;
- }//if
- }//if
- }//if
- }//for
- }//if
-}//Ndbcntr::deleteNode()
-
-/*---------------------------------------------------------------------------*/
-// A NEW NODE TRIES TO DETECT A NODE RESTART. NodeState::ST_NODE_RESTART IS A POSSIBLE
-// STATE ONLY WHEN THE SYSTEM IS RUNNING.
-// IF THE SYSTEM IS RUNNING THEN
-// CTYPE_OF_START = NodeState::ST_SYSTEM_RESTART UNTIL THE FIRST NODE HAS REGISTERED.
-// IF SYSTEM IS */
-// RUNNING THE FIRST NODE TO REGISTER WILL BE ZRUN AND CTYPE_OF_START
-// WILL BE CHANGED */
-// TO NodeState::ST_NODE_RESTART AT PH_2C. WHEN A NodeState::ST_NODE_RESTART IS DETECTED THE NEW NODE
-// HAS TO SEND */
-// A CNTR_MASTERREQ TO THE MASTER
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::detectNoderestart(Signal* signal)
-{
- NodeRecPtr ownNodePtr;
- ownNodePtr.i = getOwnNodeId();
- ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec);
- if (ownNodePtr.p->state != ZADD) {
- if (ownNodePtr.p->state != ZREMOVE) {
- jam();
- return;
- }//if
- }//if
- ctypeOfStart = NodeState::ST_NODE_RESTART;
-/*----------------------------------------------*/
-/* THIS NODE WILL PERFORM A NODE RESTART */
-/* REQUEST OF ALL NODES STATES IN SYSTEM */
-// The purpose of this signal is to ensure that
-// the starting node knows when it has received
-// all APPL_CHANGEREP signals and thus can continue
-// to the next step of the node restart. Thus we
-// need to know the amount of nodes that are in the
-// RUN state and in the START state (more than one
-// node can be copying data simultaneously in the
-// cluster.
-/*----------------------------------------------*/
- signal->theData[0] = cownBlockref;
- sendSignal(nodePtr.p->cntrBlockref, GSN_NODE_STATESREQ, signal, 1, JBB);
- cnoNeedNodes = ZNIL;
-/*---------------------------------*/
-/* PREVENT TO SEND NODE_STATESREQ */
-/*---------------------------------------------------------------------------*/
-/* WE NEED TO WATCH THE NODE RESTART WITH A TIME OUT TO NOT WAIT FOR EVER. */
-/*---------------------------------------------------------------------------*/
- cwaitContinuebFlag = ZTRUE;
- signal->theData[0] = ZCONTINUEB_1;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 3 * 1000, 1);
-}//Ndbcntr::detectNoderestart()
-
-/*---------------------------------------------------------------------------*/
-// SCAN NODE_REC FOR APPROPRIATE NODES FOR A START.
-// SYSTEMRESTART AND INITALSTART DEMANDS NODES OF STATE ZADD.
-// NODERESTART DEMANDS NODE OF THE STATE ZRUN.
-// INPUT: CTYPE_OF_START, NODE_REC
-// RETURN: CSTART_NODES(), CNO_START_NODES, CMASTER_CANDIDATE_ID
-// (SYSTEMRESTART AND INITALSTART)
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::getStartNodes(Signal* signal)
-{
- UintR Ttemp1;
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- Ttemp1 = ZRUN;
- } else {
- jam();
-/*---------------------------------*/
-/* SYSTEM RESTART AND INITIAL START*/
-/*---------------------------------*/
- Ttemp1 = ZADD;
- }//if
- cnoStartNodes = 0;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->state == Ttemp1) {
- jam();
- cstartNodes[cnoStartNodes] = nodePtr.i;/*OVERWRITTEN AT CNTR_MASTERCONF*/
- cnoStartNodes++;
- }//if
- }//for
-}//Ndbcntr::getStartNodes()
/*---------------------------------------------------------------------------*/
/*INITIALIZE VARIABLES AND RECORDS */
/*---------------------------------------------------------------------------*/
void Ndbcntr::initData(Signal* signal)
{
- cmasterNodeId = ZNIL;
- cmasterCandidateId = ZNIL;
- cmasterVoters = 0;
- cstartProgressFlag = ZFALSE;
- capplStartconfFlag = ZFALSE;
- cnoVoters = 0;
+ c_start.reset();
+ cmasterNodeId = 0;
cnoStartNodes = 0;
- for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->cntrBlockref = calcNdbCntrBlockRef(nodePtr.i);
- nodePtr.p->state = ZREMOVE;
- nodePtr.p->dynamicId = 0;
- nodePtr.p->votes = 0; /* USED BY MASTER */
- nodePtr.p->voter = ZFALSE; /* USED BY MASTER */
- nodePtr.p->masterReq = ZFALSE; /* USED BY MASTER */
- }//for
+ cnoWaitrep = 0;
}//Ndbcntr::initData()
-/*---------------------------------------------------------------------------*/
-// THE MASTER NODE HAS CHOOSEN THE NODES WHO WERE QUALIFIED TO
-// PARTICIPATE IN A INITIALSTART OR SYSTEMRESTART.
-// THIS SUBROTINE SENDS A CNTR_MASTERCONF TO THESE NODES
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::replyMasterconfToAll(Signal* signal)
-{
- if (cnoStartNodes > 1) {
- /**
- * Construct a MasterConf signal
- */
-
- CntrMasterConf * const cntrMasterConf =
- (CntrMasterConf *)&signal->theData[0];
- NodeBitmask::clear(cntrMasterConf->theNodes);
-
- cntrMasterConf->noStartNodes = cnoStartNodes;
-
- for(int i = 0; i<cnoStartNodes; i++)
- NodeBitmask::set(cntrMasterConf->theNodes, cstartNodes[i]);
-
- /**
- * Then distribute it to everyone but myself
- */
- for(int i = 0; i<cnoStartNodes; i++){
- const NodeId nodeId = cstartNodes[i];
- if(nodeId != getOwnNodeId()){
- sendSignal(numberToRef(number(), nodeId),
- GSN_CNTR_MASTERCONF,
- signal, CntrMasterConf::SignalLength, JBB);
- }
- }
- }
-}//Ndbcntr::replyMasterconfToAll()
/*---------------------------------------------------------------------------*/
/*RESET VARIABLES USED DURING THE START */
/*---------------------------------------------------------------------------*/
void Ndbcntr::resetStartVariables(Signal* signal)
{
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->votes = 0;
- nodePtr.p->voter = ZFALSE;
- nodePtr.p->masterReq = ZFALSE;
- }//for
- cnoVoters = 0;
cnoStartNodes = 0;
cnoWaitrep6 = cnoWaitrep7 = 0;
}//Ndbcntr::resetStartVariables()
-/*---------------------------------------------------------------------------*/
-// SENDER OF THIS SIGNAL HAS CHOOSEN A MASTER NODE AND SENDS A REQUEST
-// TO THE MASTER_CANDIDATE AS AN VOTE FOR
-// THE MASTER. THE SIGNAL ALSO INCLUDES VOTES FOR NODES WHICH SENDER
-// THINKS SHOULD PARTICIPATE IN THE START.
-// INPUT: CNO_START_NODES
-// CSTART_NODES
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::sendCntrMasterreq(Signal* signal)
-{
- nodePtr.i = cmasterCandidateId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
-/*--------------------------------------------------------------*/
-/* O:INITIALSTART, 1:SYSTEMRESTART (ELECTION OF MASTER) */
-/* 2:NODE RESTART (SENDER NODE NOT INCLUDED IN CSTART_NODES) */
-/*--------------------------------------------------------------*/
- CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0];
- NodeBitmask::clear(cntrMasterReq->theNodes);
- for (int i = 0; i < cnoStartNodes; i++){
- jam();
- UintR Tnode = cstartNodes[i];
- arrGuard(Tnode, MAX_NDB_NODES);
- NodeBitmask::set(cntrMasterReq->theNodes, Tnode);
- }//for
- cntrMasterReq->userBlockRef = cownBlockref;
- cntrMasterReq->userNodeId = getOwnNodeId();
- cntrMasterReq->typeOfStart = ctypeOfStart;
- cntrMasterReq->noRestartNodes = cnoStartNodes;
- sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREQ,
- signal, CntrMasterReq::SignalLength, JBB);
-}//Ndbcntr::sendCntrMasterreq()
/*---------------------------------------------------------------------------*/
// SEND THE SIGNAL
@@ -2745,25 +1835,24 @@ void Ndbcntr::sendCntrMasterreq(Signal* signal)
/*---------------------------------------------------------------------------*/
void Ndbcntr::sendNdbSttor(Signal* signal)
{
- CfgBlockRecPtr cfgBlockPtr;
NdbBlocksRecPtr ndbBlocksPtr;
ndbBlocksPtr.i = cndbBlocksCount;
ptrCheckGuard(ndbBlocksPtr, ZSIZE_NDB_BLOCKS_REC, ndbBlocksRec);
- cfgBlockPtr.i = cinternalStartphase;
- ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec);
+
NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
- req->senderRef = cownBlockref;
+ req->senderRef = reference();
req->nodeId = getOwnNodeId();
req->internalStartPhase = cinternalStartphase;
req->typeOfStart = ctypeOfStart;
req->masterNodeId = cmasterNodeId;
for (int i = 0; i < 16; i++) {
- req->config[i] = cfgBlockPtr.p->cfgData[i];
+ // Garbage
+ req->config[i] = 0x88776655;
+ //cfgBlockPtr.p->cfgData[i];
}
- //#define TRACE_STTOR
//#define MAX_STARTPHASE 2
#ifdef TRACE_STTOR
ndbout_c("sending NDB_STTOR(%d) to %s",
@@ -2779,9 +1868,6 @@ void Ndbcntr::sendNdbSttor(Signal* signal)
/*---------------------------------------------------------------------------*/
void Ndbcntr::sendSttorry(Signal* signal)
{
- signal->theData[0] = csignalKey;
- signal->theData[1] = 3;
- signal->theData[2] = 2;
signal->theData[3] = ZSTART_PHASE_1;
signal->theData[4] = ZSTART_PHASE_2;
signal->theData[5] = ZSTART_PHASE_3;
@@ -2801,9 +1887,8 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal)
DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
if(signal->theData[0] == 13){
infoEvent("Cntr: cstartPhase = %d, cinternalStartphase = %d, block = %d",
- cstartPhase, cinternalStartphase, cndbBlocksCount);
- infoEvent("Cntr: cmasterNodeId = %d, cmasterCandidateId = %d",
- cmasterNodeId, cmasterCandidateId);
+ cstartPhase, cinternalStartphase, cndbBlocksCount);
+ infoEvent("Cntr: cmasterNodeId = %d", cmasterNodeId);
}
if (dumpState->args[0] == DumpStateOrd::NdbcntrTestStopOnError){
@@ -2823,6 +1908,7 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal)
}//Ndbcntr::execDUMP_STATE_ORD()
void Ndbcntr::execSET_VAR_REQ(Signal* signal) {
+#if 0
SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0];
ConfigParamId var = setVarReq->variable();
@@ -2835,6 +1921,7 @@ void Ndbcntr::execSET_VAR_REQ(Signal* signal) {
default:
sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB);
}// switch
+#endif
}//Ndbcntr::execSET_VAR_REQ()
void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{
@@ -2947,7 +2034,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
}
updateNodeState(signal, newState);
signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1);
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
}
void
@@ -2991,14 +2078,9 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
/**
* Check if I can survive me stopping
*/
- NodeBitmask ndbMask; ndbMask.clear();
- NodeRecPtr aPtr;
- for(aPtr.i = 1; aPtr.i < MAX_NDB_NODES; aPtr.i++){
- ptrAss(aPtr, cntr.nodeRec);
- if(aPtr.i != cntr.getOwnNodeId() && aPtr.p->state == ZRUN){
- ndbMask.set(aPtr.i);
- }
- }
+ NodeBitmask ndbMask;
+ ndbMask.assign(cntr.c_startedNodes);
+ ndbMask.clear(cntr.getOwnNodeId());
CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
sd->blockRef = cntr.reference();
@@ -3194,7 +2276,7 @@ void Ndbcntr::execSTOP_ME_CONF(Signal* signal){
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1);
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
}
void
@@ -3255,6 +2337,11 @@ void Ndbcntr::execSTTORRY(Signal* signal){
c_missra.execSTTORRY(signal);
}
+void Ndbcntr::execREAD_CONFIG_CONF(Signal* signal){
+ jamEntry();
+ c_missra.execREAD_CONFIG_CONF(signal);
+}
+
void Ndbcntr::execSTART_ORD(Signal* signal){
jamEntry();
ndbrequire(NO_OF_BLOCKS == ALL_BLOCKS_SZ);
@@ -3299,7 +2386,38 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){
signal->theData[0] = EventReport::NDBStartStarted;
signal->theData[1] = NDB_VERSION;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+
+ currentBlockIndex = 0;
+ sendNextREAD_CONFIG_REQ(signal);
+}
+
+void Ndbcntr::Missra::sendNextREAD_CONFIG_REQ(Signal* signal){
+
+ if(currentBlockIndex < ALL_BLOCKS_SZ){
+ jam();
+
+ ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtrSend();
+ req->senderData = 0;
+ req->senderRef = cntr.reference();
+ req->noOfParameters = 0;
+
+ const BlockReference ref = ALL_BLOCKS[currentBlockIndex].Ref;
+
+#if 0
+ ndbout_c("sending READ_CONFIG_REQ to %s(ref=%x index=%d)",
+ getBlockName( refToBlock(ref)),
+ ref,
+ currentBlockIndex);
+#endif
+
+ cntr.sendSignal(ref, GSN_READ_CONFIG_REQ, signal,
+ ReadConfigReq::SignalLength, JBB);
+ return;
+ }
+ /**
+ * Finished...
+ */
currentStartPhase = 0;
for(Uint32 i = 0; i<NO_OF_BLOCKS; i++){
if(ALL_BLOCKS[i].NextSP < currentStartPhase)
@@ -3307,10 +2425,19 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){
}
currentBlockIndex = 0;
-
sendNextSTTOR(signal);
}
+void Ndbcntr::Missra::execREAD_CONFIG_CONF(Signal* signal){
+ const ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtr();
+
+ const Uint32 ref = conf->senderRef;
+ ndbrequire(refToBlock(ALL_BLOCKS[currentBlockIndex].Ref) == refToBlock(ref));
+
+ currentBlockIndex++;
+ sendNextREAD_CONFIG_REQ(signal);
+}
+
void Ndbcntr::Missra::execSTTORRY(Signal* signal){
const BlockReference ref = signal->senderBlockRef();
ndbrequire(refToBlock(ref) == refToBlock(ALL_BLOCKS[currentBlockIndex].Ref));
@@ -3365,8 +2492,8 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
currentBlockIndex);
#endif
- cntr.sendSignal(ref, GSN_STTOR,
- signal, 8, JBB);
+ cntr.sendSignal(ref, GSN_STTOR, signal, 8, JBB);
+
return;
}
}
@@ -3391,4 +2518,136 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
NodeState newState(NodeState::SL_STARTED);
cntr.updateNodeState(signal, newState);
+
+ /**
+ * Backward
+ */
+ UpgradeStartup::sendCmAppChg(cntr, signal, 3); //RUN
+
+ NdbNodeBitmask nodes = cntr.c_clusterNodes;
+ Uint32 node = 0;
+ while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){
+ if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){
+ nodes.clear(node);
+ }
+ }
+
+ NodeReceiverGroup rg(NDBCNTR, nodes);
+ signal->theData[0] = cntr.getOwnNodeId();
+ cntr.sendSignal(rg, GSN_CNTR_START_REP, signal, 1, JBB);
+}
+
+/**
+ * Backward compatible code
+ */
+void
+UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
+
+ signal->theData[0] = startLevel;
+ signal->theData[1] = cntr.getOwnNodeId();
+ signal->theData[2] = 3 | ('N' << 8);
+ signal->theData[3] = 'D' | ('B' << 8);
+ signal->theData[4] = 0;
+ signal->theData[5] = 0;
+ signal->theData[6] = 0;
+ signal->theData[7] = 0;
+ signal->theData[8] = 0;
+ signal->theData[9] = 0;
+ signal->theData[10] = 0;
+ signal->theData[11] = 0;
+
+ NdbNodeBitmask nodes = cntr.c_clusterNodes;
+ nodes.clear(cntr.getOwnNodeId());
+ Uint32 node = 0;
+ while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){
+ if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){
+ cntr.sendSignal(cntr.calcQmgrBlockRef(node),
+ GSN_CM_APPCHG, signal, 12, JBB);
+ } else {
+ cntr.c_startedNodes.set(node); // Fake started
+ }
+ }
+}
+
+void
+UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){
+ Uint32 state = signal->theData[0];
+ Uint32 nodeId = signal->theData[1];
+ if(block.number() == QMGR){
+ Ndbcntr& cntr = * (Ndbcntr*)globalData.getBlock(CNTR);
+ switch(state){
+ case 0: // ZADD
+ break;
+ case 2: // ZSTART
+ break;
+ case 3: // ZRUN{
+ cntr.c_startedNodes.set(nodeId);
+
+ Uint32 recv = cntr.c_startedNodes.count();
+ Uint32 cnt = cntr.c_clusterNodes.count();
+ if(recv + 1 == cnt){ //+1 == own node
+ /**
+ * Check master
+ */
+ sendCntrMasterReq(cntr, signal, 0);
+ }
+ return;
+ }
+ }
+ block.progError(0,0);
+}
+
+void
+UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){
+ Uint32 node = cntr.c_startedNodes.find(n);
+ if(node != NdbNodeBitmask::NotFound &&
+ (node == cntr.getOwnNodeId() ||
+ cntr.getNodeInfo(node).m_version >= MAKE_VERSION(3,5,0))){
+ node = cntr.c_startedNodes.find(node+1);
+ }
+
+ if(node == NdbNodeBitmask::NotFound){
+ cntr.progError(0,0);
+ }
+
+ CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0];
+ cntr.c_clusterNodes.copyto(NdbNodeBitmask::Size, cntrMasterReq->theNodes);
+ NdbNodeBitmask::clear(cntrMasterReq->theNodes, cntr.getOwnNodeId());
+ cntrMasterReq->userBlockRef = 0;
+ cntrMasterReq->userNodeId = cntr.getOwnNodeId();
+ cntrMasterReq->typeOfStart = NodeState::ST_INITIAL_NODE_RESTART;
+ cntrMasterReq->noRestartNodes = cntr.c_clusterNodes.count() - 1;
+ cntr.sendSignal(cntr.calcNdbCntrBlockRef(node), GSN_CNTR_MASTERREQ,
+ signal, CntrMasterReq::SignalLength, JBB);
+}
+
+void
+UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){
+ Uint32 gsn = signal->header.theVerId_signalNumber;
+ Uint32 node = refToNode(signal->getSendersBlockRef());
+ if(block.number() == CNTR){
+ Ndbcntr& cntr = (Ndbcntr&)block;
+ switch(gsn){
+ case GSN_CNTR_MASTERREF:
+ sendCntrMasterReq(cntr, signal, node + 1);
+ return;
+ break;
+ case GSN_CNTR_MASTERCONF:{
+ CntrStartConf* conf = (CntrStartConf*)signal->getDataPtrSend();
+ conf->startGci = 0;
+ conf->masterNodeId = node;
+ conf->noStartNodes = 1;
+ conf->startType = NodeState::ST_INITIAL_NODE_RESTART;
+ NodeBitmask mask;
+ mask.clear();
+ mask.copyto(NdbNodeBitmask::Size, conf->startedNodes);
+ mask.clear();
+ mask.set(cntr.getOwnNodeId());
+ mask.copyto(NdbNodeBitmask::Size, conf->startingNodes);
+ cntr.execCNTR_START_CONF(signal);
+ return;
+ }
+ }
+ }
+ block.progError(0,0);
}