📄 qmgrmain.cpp
字号:
ndbrequire(c_readnodes_nodes.get(nodeId)); ReadNodesConf* conf = (ReadNodesConf*)signal->getDataPtr(); if (gsn == GSN_READ_NODESREF) { jam();retry: signal->theData[0] = reference(); sendSignal(calcQmgrBlockRef(nodeId), GSN_READ_NODESREQ, signal, 1, JBA); return; } if (conf->masterNodeId == ZNIL) { jam(); goto retry; } Uint32 president = conf->masterNodeId; if (president == cpresident) { jam(); c_readnodes_nodes.clear(nodeId); return; } char buf[255]; BaseString::snprintf(buf, sizeof(buf), "Partitioned cluster! check StartPartialTimeout, " " node %d thinks %d is president, " " I think president is: %d", nodeId, president, cpresident); ndbout_c(buf); CRASH_INSERTION(933); if (getNodeState().startLevel == NodeState::SL_STARTED) { jam(); NdbNodeBitmask part; part.assign(NdbNodeBitmask::Size, conf->clusterNodes); FailRep* rep = (FailRep*)signal->getDataPtrSend(); rep->failCause = FailRep::ZPARTITIONED_CLUSTER; rep->president = cpresident; c_clusterNodes.copyto(NdbNodeBitmask::Size, rep->partition); Uint32 ref = calcQmgrBlockRef(nodeId); Uint32 i = 0; while((i = part.find(i + 1)) != NdbNodeBitmask::NotFound) { if (i == nodeId) continue; rep->failNodeId = i; sendSignal(ref, GSN_FAIL_REP, signal, FailRep::SignalLength, JBA); } rep->failNodeId = nodeId; sendSignal(ref, GSN_FAIL_REP, signal, FailRep::SignalLength, JBB); return; } CRASH_INSERTION(932); progError(__LINE__, NDBD_EXIT_ARBIT_SHUTDOWN, buf); ndbrequire(false);}voidQmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){ CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); req->nodeId = getOwnNodeId(); req->dynamicId = self->ndynamicId; req->version = getNodeInfo(getOwnNodeId()).m_version; const Uint32 ref = calcQmgrBlockRef(nodeId); sendSignal(ref,GSN_CM_NODEINFOREQ, signal, CmNodeInfoReq::SignalLength, JBB); DEBUG_START(GSN_CM_NODEINFOREQ, nodeId, "");}/*4.4.11 CM_REGREF *//**-------------------------------------------------------------------------- * Only a president or a president candidate can refuse a node to get added to * the cluster. * Refuse reasons: * ZBUSY We know that the sender is the president and we have to * make a new CM_REGREQ. * ZNOT_IN_CFG This node number is not specified in the configfile, * SYSTEM ERROR * ZELECTION Sender is a president candidate, his timelimit * hasn't expired so maybe someone else will show up. * Update the CPRESIDENT_CANDIDATE, then wait for our * timelimit to expire. *---------------------------------------------------------------------------*//*******************************//* CM_REGREF *//*******************************/staticconst char *get_start_type_string(Uint32 st){ static char buf[256]; if (st == 0) { return "<ANY>"; } else { buf[0] = 0; for(Uint32 i = 0; i<NodeState::ST_ILLEGAL_TYPE; i++) { if (st & (1 << i)) { if (buf[0]) strcat(buf, "/"); switch(i){ case NodeState::ST_INITIAL_START: strcat(buf, "inital start"); break; case NodeState::ST_SYSTEM_RESTART: strcat(buf, "system restart"); break; case NodeState::ST_NODE_RESTART: strcat(buf, "node restart"); break; case NodeState::ST_INITIAL_NODE_RESTART: strcat(buf, "initial node restart"); break; } } } return buf; }}void Qmgr::execCM_REGREF(Signal* signal) { jamEntry(); CmRegRef* ref = (CmRegRef*)signal->getDataPtr(); UintR TaddNodeno = ref->nodeId; UintR TrefuseReason = ref->errorCode; Uint32 candidate = ref->presidentCandidate; Uint32 node_gci = 1; Uint32 candidate_gci = 1; Uint32 start_type = ~0; NdbNodeBitmask skip_nodes; DEBUG_START3(signal, TrefuseReason); if (signal->getLength() == CmRegRef::SignalLength) { jam(); node_gci = ref->latest_gci; candidate_gci = ref->candidate_latest_gci; start_type = ref->start_type; skip_nodes.assign(NdbNodeBitmask::Size, ref->skip_nodes); } c_start.m_regReqReqRecv++; // Ignore block reference in data[0] if(candidate != c_start.m_president_candidate) { jam(); c_start.m_regReqReqRecv = ~0; } c_start.m_starting_nodes.set(TaddNodeno); if (node_gci) { jam(); c_start.m_starting_nodes_w_log.set(TaddNodeno); } skip_nodes.bitAND(c_definedNodes); c_start.m_skip_nodes.bitOR(skip_nodes); char buf[100]; switch (TrefuseReason) { case CmRegRef::ZINCOMPATIBLE_VERSION: jam(); systemErrorLab(signal, __LINE__, "incompatible version, " "connection refused by running ndb node"); case CmRegRef::ZINCOMPATIBLE_START_TYPE: jam(); BaseString::snprintf(buf, sizeof(buf), "incompatible start type detected: node %d" " reports %s(%d) my start type: %s(%d)", TaddNodeno, get_start_type_string(start_type), start_type, get_start_type_string(c_start.m_start_type), c_start.m_start_type); progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT, buf); break; case CmRegRef::ZBUSY: case CmRegRef::ZBUSY_TO_PRES: case CmRegRef::ZBUSY_PRESIDENT: jam(); cpresidentAlive = ZTRUE; signal->theData[3] = 0; break; case CmRegRef::ZNOT_IN_CFG: jam(); progError(__LINE__, NDBD_EXIT_NODE_NOT_IN_CONFIG); break; case CmRegRef::ZNOT_DEAD: jam(); progError(__LINE__, NDBD_EXIT_NODE_NOT_DEAD); break; case CmRegRef::ZELECTION: jam(); if (candidate_gci > c_start.m_president_candidate_gci || (candidate_gci == c_start.m_president_candidate_gci && candidate < c_start.m_president_candidate)) { jam(); //---------------------------------------- /* We may already have a candidate */ /* choose the lowest nodeno */ //---------------------------------------- signal->theData[3] = 2; c_start.m_president_candidate = candidate; c_start.m_president_candidate_gci = candidate_gci; } else { signal->theData[3] = 4; }//if break; case CmRegRef::ZNOT_PRESIDENT: jam(); cpresidentAlive = ZTRUE; signal->theData[3] = 3; break; default: jam(); signal->theData[3] = 5; /*empty*/; break; }//switch/*--------------------------------------------------------------*/// Send this as an EVENT REPORT to inform about hearing about// other NDB node proclaiming not to be president./*--------------------------------------------------------------*/ signal->theData[0] = NDB_LE_CM_REGREF; signal->theData[1] = getOwnNodeId(); signal->theData[2] = TaddNodeno;//-----------------------------------------// signal->theData[3] filled in above//----------------------------------------- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB); if(cpresidentAlive == ZTRUE) { jam(); DEBUG("cpresidentAlive"); return; } if(c_start.m_regReqReqSent != c_start.m_regReqReqRecv) { jam(); DEBUG(c_start.m_regReqReqSent << " != " << c_start.m_regReqReqRecv); return; } if(c_start.m_president_candidate != getOwnNodeId()) { jam(); DEBUG("i'm not the candidate"); return; } /** * All connected nodes has agreed */ if(check_startup(signal)) { jam(); electionWon(signal); /** * Start timer handling */ signal->theData[0] = ZTIMER_HANDLING; sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); } return;}//Qmgr::execCM_REGREF()Uint32Qmgr::check_startup(Signal* signal){ Uint64 now = NdbTick_CurrentMillisecond(); Uint64 partial_timeout = c_start_election_time + c_restartPartialTimeout; Uint64 partitioned_timeout = partial_timeout + c_restartPartionedTimeout; /** * First see if we should wait more... */ NdbNodeBitmask tmp; tmp.bitOR(c_start.m_skip_nodes); tmp.bitOR(c_start.m_starting_nodes); NdbNodeBitmask wait; wait.assign(c_definedNodes); wait.bitANDC(tmp); Uint32 retVal = 0; NdbNodeBitmask report_mask; if ((c_start.m_latest_gci == 0) || (c_start.m_start_type == (1 << NodeState::ST_INITIAL_START))) { if (!tmp.equal(c_definedNodes)) { jam(); signal->theData[1] = 1; signal->theData[2] = ~0; report_mask.assign(wait); retVal = 0; goto start_report; } else { jam(); signal->theData[1] = 0x8000; report_mask.assign(c_definedNodes); report_mask.bitANDC(c_start.m_starting_nodes); retVal = 1; goto start_report; } } { const bool all = c_start.m_starting_nodes.equal(c_definedNodes); CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0]; { /** * Check for missing node group directly */ char buf[100]; NdbNodeBitmask check; check.assign(c_definedNodes); check.bitANDC(c_start.m_starting_nodes); // Not connected nodes check.bitOR(c_start.m_starting_nodes_w_log); sd->blockRef = reference(); sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck; sd->mask = check; EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal, CheckNodeGroups::SignalLength); if (sd->output == CheckNodeGroups::Lose) { jam(); goto missing_nodegroup; } } sd->blockRef = reference(); sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck; sd->mask = c_start.m_starting_nodes; EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal, CheckNodeGroups::SignalLength); const Uint32 result = sd->output; sd->blockRef = reference(); sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck; sd->mask = c_start.m_starting_nodes_w_log; EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal, CheckNodeGroups::SignalLength); const Uint32 result_w_log = sd->output; if (tmp.equal(c_definedNodes)) { /** * All nodes (wrt no-wait nodes) has connected... * this means that we will now start or die */ jam(); switch(result_w_log){ case CheckNodeGroups::Lose: { jam(); goto missing_nodegroup; } case CheckNodeGroups::Win: signal->theData[1] = all ? 0x8001 : 0x8002; report_mask.assign(c_definedNodes); report_mask.bitANDC(c_start.m_starting_nodes); retVal = 1; goto start_report; case CheckNodeGroups::Partitioning: ndbrequire(result != CheckNodeGroups::Lose); signal->theData[1] = all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003); report_mask.assign(c_definedNodes); report_mask.bitANDC(c_start.m_starting_nodes); retVal = 1; goto start_report; } } if (now < partial_timeout) { jam(); signal->theData[1] = c_restartPartialTimeout == ~0 ? 2 : 3; signal->theData[2] = Uint32((partial_timeout - now + 500) / 1000); report_mask.assign(wait); retVal = 0; goto start_report; } /** * Start partial has passed...check for partitioning... */ switch(result_w_log){ case CheckNodeGroups::Lose: jam(); goto missing_nodegroup; case CheckNodeGroups::Partitioning: if (now < partitioned_timeout && result != CheckNodeGroups::Win) { signal->theData[1] = c_restartPartionedTimeout == ~0 ? 4 : 5; signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000); report_mask.assign(c_definedNodes); report_mask.bitANDC(c_start.m_starting_nodes); retVal = 0; goto start_report; } // Fall through... case CheckNodeGroups::Win: signal->theData[1] = all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003); report_mask.assign(c_definedNodes); report_mask.bitANDC(c_start.m_starting_nodes); retVal = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -