📄 dbdihmain.cpp
字号:
return; }//if if (errorCode == StartPermRef::InitialStartRequired) { CRASH_INSERTION(7170); char buf[255]; BaseString::snprintf(buf, sizeof(buf), "Cluster requires this node to be started " " with --initial as partial start has been performed" " and this filesystem is unusable"); progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT, buf); ndbrequire(false); } /*------------------------------------------------------------------------*/ // Some node process in another node involving our node was still active. We // will recover from this by crashing here. // This is controlled restart using the // already existing features of node crashes. It is not a bug getting here. /*-------------------------------------------------------------------------*/ ndbrequire(false); return;}//Dbdih::execSTART_PERMREF()/*---------------------------------------------------------------------------*//* THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ *//* HAS BEEN EXECUTED IN THE MASTER NODE. *//*---------------------------------------------------------------------------*/void Dbdih::execSTART_MECONF(Signal* signal) { jamEntry(); StartMeConf * const startMe = (StartMeConf *)&signal->theData[0]; Uint32 nodeId = startMe->startingNodeId; const Uint32 startWord = startMe->startWord; Uint32 i; CRASH_INSERTION(7130); ndbrequire(nodeId == cownNodeId); arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4); for(i = 0; i < StartMeConf::DATA_SIZE; i++) cdata[startWord+i] = startMe->data[i]; if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){ jam(); /** * We are still waiting for data */ return; } jam(); /** * Copy into sysfile * * But dont copy lastCompletedGCI:s */ Uint32 tempGCP[MAX_NDB_NODES]; for(i = 0; i < MAX_NDB_NODES; i++) tempGCP[i] = SYSFILE->lastCompletedGCI[i]; for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++) sysfileData[i] = cdata[i]; for(i = 0; i < MAX_NDB_NODES; i++) SYSFILE->lastCompletedGCI[i] = tempGCP[i]; setNodeActiveStatus(); setNodeGroups(); ndbsttorry10Lab(signal, __LINE__);}//Dbdih::execSTART_MECONF()void Dbdih::execSTART_COPYCONF(Signal* signal) { jamEntry(); Uint32 nodeId = signal->theData[0]; ndbrequire(nodeId == cownNodeId); CRASH_INSERTION(7132); ndbsttorry10Lab(signal, __LINE__); return;}//Dbdih::execSTART_COPYCONF()/*---------------------------------------------------------------------------*//* MASTER LOGIC FOR NODE RESTART *//*---------------------------------------------------------------------------*//* NODE RESTART PERMISSION REQUEST *//*---------------------------------------------------------------------------*/// A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE// IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN// THIS NODE INVOLVING THE STARTING NODE THIS REQUEST WILL BE GRANTED./*---------------------------------------------------------------------------*/void Dbdih::execSTART_PERMREQ(Signal* signal){ StartPermReq * const req = (StartPermReq*)&signal->theData[0]; jamEntry(); const BlockReference retRef = req->blockRef; const Uint32 nodeId = req->nodeId; const Uint32 typeStart = req->startType; CRASH_INSERTION(7122); ndbrequire(isMaster()); ndbrequire(refToNode(retRef) == nodeId); if ((c_nodeStartMaster.activeState) || (c_nodeStartMaster.wait != ZFALSE)) { jam(); signal->theData[0] = nodeId; signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR; sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB); return; }//if if (getNodeStatus(nodeId) != NodeRecord::DEAD){ ndbout << "nodeStatus in START_PERMREQ = " << (Uint32) getNodeStatus(nodeId) << endl; ndbrequire(false); }//if if (SYSFILE->lastCompletedGCI[nodeId] == 0 && typeStart != NodeState::ST_INITIAL_NODE_RESTART) { jam(); signal->theData[0] = nodeId; signal->theData[1] = StartPermRef::InitialStartRequired; sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB); return; } /*---------------------------------------------------------------------- * WE START THE INCLUSION PROCEDURE * ---------------------------------------------------------------------*/ c_nodeStartMaster.failNr = cfailurenr; c_nodeStartMaster.wait = ZFALSE; c_nodeStartMaster.startInfoErrorCode = 0; c_nodeStartMaster.startNode = nodeId; c_nodeStartMaster.activeState = true; c_nodeStartMaster.m_outstandingGsn = GSN_START_INFOREQ; setNodeStatus(nodeId, NodeRecord::STARTING); /** * But if it's a NodeState::ST_INITIAL_NODE_RESTART * * We first have to clear LCP's * For normal node restart we simply ensure that all nodes * are informed of the node restart */ StartInfoReq *const r =(StartInfoReq*)&signal->theData[0]; r->startingNodeId = nodeId; r->typeStart = typeStart; r->systemFailureNo = cfailurenr; sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ);}//Dbdih::execSTART_PERMREQ()void Dbdih::execSTART_INFOREF(Signal* signal){ StartInfoRef * ref = (StartInfoRef*)&signal->theData[0]; if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) { jam(); return; }//if ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId); c_nodeStartMaster.startInfoErrorCode = ref->errorCode; startInfoReply(signal, ref->sendingNodeId);}//Dbdih::execSTART_INFOREF()void Dbdih::execSTART_INFOCONF(Signal* signal){ jamEntry(); StartInfoConf * conf = (StartInfoConf*)&signal->theData[0]; if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) { jam(); return; }//if ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId); startInfoReply(signal, conf->sendingNodeId);}//Dbdih::execSTART_INFOCONF()void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId){ receiveLoopMacro(START_INFOREQ, nodeId); /** * We're finished with the START_INFOREQ's */ if (c_nodeStartMaster.startInfoErrorCode == 0) { jam(); /** * Everything has been a success so far */ StartPermConf * conf = (StartPermConf*)&signal->theData[0]; conf->startingNodeId = c_nodeStartMaster.startNode; conf->systemFailureNo = cfailurenr; sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode), GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB); c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF; } else { jam(); StartPermRef * ref = (StartPermRef*)&signal->theData[0]; ref->startingNodeId = c_nodeStartMaster.startNode; ref->errorCode = c_nodeStartMaster.startInfoErrorCode; sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode), GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB); nodeResetStart(); }//if}//Dbdih::startInfoReply()/*---------------------------------------------------------------------------*//* NODE RESTART CONTINUE REQUEST *//*---------------------------------------------------------------------------*/// THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN// REQUESTED TO START UP A NEW NODE. The master instructs the starting node// how to set up its log for continued execution./*---------------------------------------------------------------------------*/void Dbdih::execSTART_MEREQ(Signal* signal) { StartMeReq * req = (StartMeReq*)&signal->theData[0]; jamEntry(); const BlockReference Tblockref = req->startingRef; const Uint32 Tnodeid = refToNode(Tblockref); ndbrequire(isMaster()); ndbrequire(c_nodeStartMaster.startNode == Tnodeid); ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING); sendSTART_RECREQ(signal, Tnodeid);}//Dbdih::execSTART_MEREQ()void Dbdih::nodeRestartStartRecConfLab(Signal* signal) { c_nodeStartMaster.blockLcp = true; if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) && (c_lcpState.lcpStatus != LCP_TCGET)) { jam(); /*-----------------------------------------------------------------------*/ // WE WILL NOT ALLOW A NODE RESTART TO COME IN WHEN A LOCAL CHECKPOINT IS // ONGOING. IT WOULD COMPLICATE THE LCP PROTOCOL TOO MUCH. WE WILL ADD THIS // LATER. /*-----------------------------------------------------------------------*/ return; }//if lcpBlockedLab(signal);}//Dbdih::nodeRestartStartRecConfLab()void Dbdih::lcpBlockedLab(Signal* signal) { ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING); /*------------------------------------------------------------------------*/ // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL // INFORMATION IN DIH TO THE NEW NODE. /*------------------------------------------------------------------------*/ c_nodeStartMaster.wait = 10; signal->theData[0] = DihContinueB::ZCOPY_NODE; signal->theData[1] = 0; sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB); c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;}//Dbdih::lcpBlockedLab()void Dbdih::nodeDictStartConfLab(Signal* signal) { /*-------------------------------------------------------------------------*/ // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF // THE DICTIONARY AGAIN. /*-------------------------------------------------------------------------*/ c_nodeStartMaster.wait = ZFALSE; c_nodeStartMaster.blockGcp = true; if (cgcpStatus != GCP_READY) { /*-----------------------------------------------------------------------*/ // The global checkpoint is executing. Wait until it is completed before we // continue processing the node recovery. /*-----------------------------------------------------------------------*/ jam(); return; }//if gcpBlockedLab(signal); /*-----------------------------------------------------------------*/ // Report that node restart has completed copy of dictionary. /*-----------------------------------------------------------------*/ signal->theData[0] = NDB_LE_NR_CopyDict; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);}//Dbdih::nodeDictStartConfLab()void Dbdih::dihCopyCompletedLab(Signal* signal){ BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode); DictStartReq * req = (DictStartReq*)&signal->theData[0]; req->restartGci = cnewgcp; req->senderRef = reference(); sendSignal(ref, GSN_DICTSTARTREQ, signal, DictStartReq::SignalLength, JBB); c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ; c_nodeStartMaster.wait = 0;}//Dbdih::dihCopyCompletedLab()void Dbdih::gcpBlockedLab(Signal* signal){ /*-----------------------------------------------------------------*/ // Report that node restart has completed copy of distribution info. /*-----------------------------------------------------------------*/ signal->theData[0] = NDB_LE_NR_CopyDistr; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB); /** * The node DIH will be part of LCP */ NodeRecordPtr nodePtr; nodePtr.i = c_nodeStartMaster.startNode; ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord); nodePtr.p->m_inclDihLcp = true; /*-------------------------------------------------------------------------*/ // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH. /*------------------------------------------------------------------------*/ sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ); /*-------------------------------------------------------------------------*/ // We also need to send to the starting node to ensure he is aware of the // global checkpoint id and the correct state. We do not wait for any reply // since the starting node will not send any. /*-------------------------------------------------------------------------*/ Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version; if ((getMajor(startVersion) == 4 && startVersion >= NDBD_INCL_NODECONF_VERSION_4) || (getMajor(startVersion) == 5 && startVersion >= NDBD_INCL_NODECONF_VERSION_5)) { c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode); } sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode);}//Dbdih::gcpBlockedLab()/*---------------------------------------------------------------------------*/// THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER/*---------------------------------------------------------------------------*/void Dbdih::execINCL_NODECONF(Signal* signal) { Uint32 TsendNodeId; Uint32 TstartNode_or_blockref; jamEntry(); TstartNode_or_blockref = signal->theData[0]; TsendNodeId = signal->theData[1]; if (TstartNode_or_blockref == clocallqhblockref) { jam(); /*-----------------------------------------------------------------------*/ // THIS SIGNAL CAME FROM THE LOCAL LQH BLOCK. // WE WILL NOW SEND INCLUDE TO THE TC BLOCK. /*-----------------------------------------------------------------------*/ signal->theData[0] = reference(); signal->theData[1] = c_nodeStartSlave.nodeId; sendSignal(clocaltcblockref, GSN_INCL_NODEREQ, signal, 2, JBB); return; }//if if (TstartNode_or_blockref == clocaltcblockref) { jam(); /*----------------------------------------------------------------------*/ // THIS SIGNAL CAME FROM THE LOCAL LQH BLOCK. // WE WILL NOW SEND INCLUDE TO THE DICT BLOCK. /*----------------------------------------------------------------------*/ signal->theData[0] = reference(); signal->theData[1] = c_nodeStartSlave.nodeId; sendSignal(cdictblockref, GSN_INCL_NODEREQ, signal, 2, JBB); return; }//if if (TstartNode_or_blockref == cdictblockref) { jam(); /*-----------------------------------------------------------------------*/ // THIS SIGNAL CAME FROM THE LOCAL DICT BLOCK. WE WILL NOW SEND CONF TO THE // BACKUP. /*-----------------------------------------------------------------------*/ signal->theData[0] = reference(); signal->theData[1] = c_nodeStartSlave.nodeId; sendSignal(BACKUP_REF, GSN_INCL_NODEREQ, signal, 2, JBB); // Suma will not send response to this for now, later... sendSignal(SUMA_REF, GSN_INCL_NODEREQ, signal, 2, JBB); return; }//if if (TstartNode_or_blockref == numberToRef(BACKUP, getOwnNodeId())){ jam(); signal->theData[0] = c_nodeStartSlave.nodeId; signal->theData[1] = cownNodeId; sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB); c_nodeStartSlave.nodeId = 0; return; } ndbrequire(cmasterdihref = reference()); receiveLoopMacro(INCL_NODEREQ, TsendNodeId); CRASH_INSERTION(7128); /*-------------------------------------------------------------------------*/ // Now that we have included the starting node in the node lists in the // various blocks we are ready to start the global checkpoint protocol /*------------------------------------------------------------------------*/ c_nodeStartMaster.wait = 11; c_nodeStartMaster.blockGcp = false; signal->theData
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -