📄 dbdihmain.cpp
字号:
cstarttype = typestart; cstartPhase = phase; switch (phase){ case ZNDB_SPH1: jam(); /*----------------------------------------------------------------------*/ /* Set the delay between local checkpoints in ndb startphase 1. */ /*----------------------------------------------------------------------*/ cownNodeId = ownNodeId; /*-----------------------------------------------------------------------*/ // Compute all static block references in this node as part of // ndb start phase 1. /*-----------------------------------------------------------------------*/ cntrlblockref = cntrRef; clocaltcblockref = calcTcBlockRef(ownNodeId); clocallqhblockref = calcLqhBlockRef(ownNodeId); cdictblockref = calcDictBlockRef(ownNodeId); ndbsttorry10Lab(signal, __LINE__); break; case ZNDB_SPH2: jam(); /*-----------------------------------------------------------------------*/ // Set the number of replicas, maximum is 4 replicas. // Read the ndb nodes from the configuration. /*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/ // For node restarts we will also add a request for permission // to continue the system restart. // The permission is given by the master node in the alive set. /*-----------------------------------------------------------------------*/ createMutexes(signal, 0); break; case ZNDB_SPH3: jam(); /*-----------------------------------------------------------------------*/ // Non-master nodes performing an initial start will execute // the start request here since the // initial start do not synchronise so much from the master. // In the master nodes the start // request will be sent directly to dih (in ndb_startreq) when all // nodes have completed phase 3 of the start. /*-----------------------------------------------------------------------*/ cmasterState = MASTER_IDLE; if(cstarttype == NodeState::ST_INITIAL_START || cstarttype == NodeState::ST_SYSTEM_RESTART){ jam(); cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE; } if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) { jam(); ndbStartReqLab(signal, cntrRef); return; }//if ndbsttorry10Lab(signal, __LINE__); break; case ZNDB_SPH4: jam(); c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__); cmasterTakeOverNode = ZNIL; switch(typestart){ case NodeState::ST_INITIAL_START: jam(); ndbsttorry10Lab(signal, __LINE__); return; case NodeState::ST_SYSTEM_RESTART: jam(); if (isMaster()) { jam(); systemRestartTakeOverLab(signal); if (anyActiveTakeOver() && false) { jam(); ndbout_c("1 - anyActiveTakeOver == true"); return; } } ndbsttorry10Lab(signal, __LINE__); return; case NodeState::ST_INITIAL_NODE_RESTART: case NodeState::ST_NODE_RESTART: jam(); /*********************************************************************** * When starting nodes while system is operational we must be controlled * by the master since only one node restart is allowed at a time. * When this signal is confirmed the master has also copied the * dictionary and the distribution information. */ StartMeReq * req = (StartMeReq*)&signal->theData[0]; req->startingRef = reference(); req->startingVersion = 0; // Obsolete sendSignal(cmasterdihref, GSN_START_MEREQ, signal, StartMeReq::SignalLength, JBB); return; } ndbrequire(false); break; case ZNDB_SPH5: jam(); switch(typestart){ case NodeState::ST_INITIAL_START: case NodeState::ST_SYSTEM_RESTART: jam(); jam(); /*---------------------------------------------------------------------*/ // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART. // THE IDEA IS THAT WE NEED TO // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE // CRASHES THAT CAUSES THE LOG // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW. // THIS CAN OTHERWISE GET US INTO // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT // BEFORE ALLOWING ANY TRANSACTIONS TO START. /*---------------------------------------------------------------------*/ if (!isMaster()) { jam(); ndbsttorry10Lab(signal, __LINE__); return; }//if c_lcpState.immediateLcpStart = true; cwaitLcpSr = true; checkLcpStart(signal, __LINE__); return; case NodeState::ST_NODE_RESTART: case NodeState::ST_INITIAL_NODE_RESTART: jam(); signal->theData[0] = cownNodeId; signal->theData[1] = reference(); sendSignal(cmasterdihref, GSN_START_COPYREQ, signal, 2, JBB); return; } ndbrequire(false); case ZNDB_SPH6: jam(); switch(typestart){ case NodeState::ST_INITIAL_START: case NodeState::ST_SYSTEM_RESTART: jam(); if(isMaster()){ jam(); startGcp(signal); } ndbsttorry10Lab(signal, __LINE__); return; case NodeState::ST_NODE_RESTART: case NodeState::ST_INITIAL_NODE_RESTART: ndbsttorry10Lab(signal, __LINE__); return; } ndbrequire(false); break; default: jam(); ndbsttorry10Lab(signal, __LINE__); break; }//switch}//Dbdih::execNDB_STTOR()voidDbdih::createMutexes(Signal * signal, Uint32 count){ Callback c = { safe_cast(&Dbdih::createMutex_done), count }; switch(count){ case 0:{ Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle); mutex.create(c); return; } case 1:{ Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle); mutex.create(c); return; } } signal->theData[0] = reference(); sendSignal(cntrlblockref, GSN_READ_NODESREQ, signal, 1, JBB);}voidDbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){ jamEntry(); ndbrequire(retVal == 0); switch(senderData){ case 0:{ Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle); mutex.release(); } case 1:{ Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle); mutex.release(); } } createMutexes(signal, senderData + 1);}/*****************************************************************************//* ------------------------------------------------------------------------- *//* WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE *//* DATABASE TABLES. *//* THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A *//* SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN *//* INITIAL START. *//* ------------------------------------------------------------------------- *//*****************************************************************************/void Dbdih::execNDB_STARTREQ(Signal* signal) { jamEntry(); BlockReference ref = signal->theData[0]; cstarttype = signal->theData[1]; ndbStartReqLab(signal, ref);}//Dbdih::execNDB_STARTREQ()void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref) { cndbStartReqBlockref = ref; if (cstarttype == NodeState::ST_INITIAL_START) { jam(); initRestartInfo(); initGciFilesLab(signal); return; } NodeRecordPtr nodePtr; Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()]; for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { jam(); ptrAss(nodePtr, nodeRecord); if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci) { jam(); /** * Since we're starting(is master) and there * there are other nodes with higher GCI... * there gci's must be invalidated... * and they _must_ do an initial start * indicate this by setting lastCompletedGCI = 0 */ SYSFILE->lastCompletedGCI[nodePtr.i] = 0; ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE); warningEvent("Making filesystem for node %d unusable", nodePtr.i); } } /** * This set which GCI we will try to restart to */ SYSFILE->newestRestorableGCI = gci; ndbrequire(isMaster()); copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!}//Dbdih::ndbStartReqLab()void Dbdih::execREAD_NODESCONF(Signal* signal) { unsigned i; ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; jamEntry(); Uint32 nodeArray[MAX_NDB_NODES]; csystemnodes = readNodes->noOfNodes; cmasterNodeId = readNodes->masterNodeId; int index = 0; NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes); for (i = 1; i < MAX_NDB_NODES; i++){ jam(); if(tmp.get(i)){ jam(); nodeArray[index] = i; if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){ jam(); con_lineNodes++; }//if index++; }//if }//for if(cstarttype == NodeState::ST_SYSTEM_RESTART || cstarttype == NodeState::ST_NODE_RESTART){ for(i = 1; i<MAX_NDB_NODES; i++){ const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus); if(stat == Sysfile::NS_NotDefined && !tmp.get(i)){ jam(); continue; } if(tmp.get(i) && stat != Sysfile::NS_NotDefined){ jam(); continue; } char buf[255]; BaseString::snprintf(buf, sizeof(buf), "Illegal configuration change." " Initial start needs to be performed " " when changing no of storage nodes (node %d)", i); progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf); } } ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES); if (cstarttype == NodeState::ST_INITIAL_START) { jam(); ndbrequire(cnoReplicas <= csystemnodes); calculateHotSpare(); ndbrequire(cnoReplicas <= (csystemnodes - cnoHotSpare)); }//if cmasterdihref = calcDihBlockRef(cmasterNodeId); /*-------------------------------------------------------------------------*/ /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/ /*-------------------------------------------------------------------------*/ makePrnList(readNodes, nodeArray); if (cstarttype == NodeState::ST_INITIAL_START) { jam(); /**---------------------------------------------------------------------- * WHEN WE INITIALLY START A DATABASE WE WILL CREATE NODE GROUPS. * ALL NODES ARE PUT INTO NODE GROUPS ALTHOUGH HOT SPARE NODES ARE PUT * INTO A SPECIAL NODE GROUP. IN EACH NODE GROUP WE HAVE THE SAME AMOUNT * OF NODES AS THERE ARE NUMBER OF REPLICAS. * ONE POSSIBLE USAGE OF NODE GROUPS ARE TO MAKE A NODE GROUP A COMPLETE * FRAGMENT OF THE DATABASE. THIS MEANS THAT ALL REPLICAS WILL BE STORED * IN THE NODE GROUP. *-----------------------------------------------------------------------*/ makeNodeGroups(nodeArray); }//if ndbrequire(checkNodeAlive(cmasterNodeId)); if (cstarttype == NodeState::ST_INITIAL_START) { jam(); /**----------------------------------------------------------------------- * INITIALISE THE SECOND NODE-LIST AND SET NODE BITS AND SOME NODE STATUS. * VERY CONNECTED WITH MAKE_NODE_GROUPS. CHANGING ONE WILL AFFECT THE * OTHER AS WELL. *-----------------------------------------------------------------------*/ setInitialActiveStatus(); } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) { jam(); /*empty*/; } else if ((cstarttype == NodeState::ST_NODE_RESTART) || (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) { jam(); nodeRestartPh2Lab(signal); return; } else { ndbrequire(false); }//if /**------------------------------------------------------------------------ * ESTABLISH CONNECTIONS WITH THE OTHER DIH BLOCKS AND INITIALISE THIS * NODE-LIST THAT HANDLES CONNECTION WITH OTHER DIH BLOCKS. *-------------------------------------------------------------------------*/ ndbsttorry10Lab(signal, __LINE__);}//Dbdih::execREAD_NODESCONF()/*---------------------------------------------------------------------------*//* START NODE LOGIC FOR NODE RESTART *//*---------------------------------------------------------------------------*/void Dbdih::nodeRestartPh2Lab(Signal* signal) { /*------------------------------------------------------------------------*/ // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY // RUNNING SYSTEM. /*------------------------------------------------------------------------*/ StartPermReq * const req = (StartPermReq *)&signal->theData[0]; req->blockRef = reference(); req->nodeId = cownNodeId; req->startType = cstarttype; sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);}//Dbdih::nodeRestartPh2Lab()void Dbdih::execSTART_PERMCONF(Signal* signal) { jamEntry(); CRASH_INSERTION(7121); Uint32 nodeId = signal->theData[0]; cfailurenr = signal->theData[1]; ndbrequire(nodeId == cownNodeId); ndbsttorry10Lab(signal, __LINE__);}//Dbdih::execSTART_PERMCONF()void Dbdih::execSTART_PERMREF(Signal* signal) { jamEntry(); Uint32 errorCode = signal->theData[1]; if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR) { jam(); /*-----------------------------------------------------------------------*/ // The master was busy adding another node. We will wait for a second and // try again. /*-----------------------------------------------------------------------*/ signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN; sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -