void ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; assert(node.defined == true); assert(node.connected == true); if(node.m_info.m_version != apiRegConf->version){ node.m_info.m_version = apiRegConf->version; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.m_api_reg_conf = true; node.m_state = apiRegConf->nodeState; if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())){ set_node_alive(node, true); } else { set_node_alive(node, false); }//if node.m_info.m_heartbeat_cnt = 0; node.hbCounter = 0; if(waitingForHB) { waitForHBFromNodes.clear(nodeId); if(waitForHBFromNodes.isclear()) { waitingForHB= false; NdbCondition_Broadcast(waitForHBCond); } } node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50; }
void ClusterMgr::execAPI_REGREF(const Uint32 * theData) { ApiRegRef * ref = (ApiRegRef*)theData; const NodeId nodeId = refToNode(ref->ref); assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.is_connected() == true); assert(node.defined == true); /* Only DB nodes will send API_REGREF */ assert(node.m_info.getType() == NodeInfo::DB); node.compatible = false; set_node_alive(node, false); node.m_state = NodeState::SL_NOTHING; node.m_info.m_version = ref->version; switch(ref->errorCode) { case ApiRegRef::WrongType: ndbout_c("Node %d reports that this node should be a NDB node", nodeId); abort(); case ApiRegRef::UnsupportedVersion: default: break; } }
void ClusterMgr::execAPI_REGREF(const Uint32 * theData){ ApiRegRef * ref = (ApiRegRef*)theData; const NodeId nodeId = refToNode(ref->ref); assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; assert(node.connected == true); assert(node.defined == true); node.compatible = false; set_node_alive(node, false); node.m_state = NodeState::SL_NOTHING; node.m_info.m_version = ref->version; switch(ref->errorCode){ case ApiRegRef::WrongType: ndbout_c("Node %d reports that this node should be a NDB node", nodeId); abort(); case ApiRegRef::UnsupportedVersion: default: break; } waitForHBFromNodes.clear(nodeId); if(waitForHBFromNodes.isclear()) NdbCondition_Signal(waitForHBCond); }
void ClusterMgr::set_node_dead(trp_node& theNode) { set_node_alive(theNode, false); theNode.set_confirmed(false); theNode.m_state.m_connected_nodes.clear(); theNode.m_state.startLevel = NodeState::SL_NOTHING; theNode.m_info.m_connectCount ++; theNode.nfCompleteRep = false; }
void ClusterMgr::reportNodeFailed(NodeId nodeId, bool disconnect){ Node & theNode = theNodes[nodeId]; set_node_alive(theNode, false); theNode.m_info.m_connectCount ++; if(theNode.connected) { theFacade.doDisconnect(nodeId); } const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING); theNode.m_state.startLevel = NodeState::SL_NOTHING; if(disconnect || report) { theFacade.ReportNodeDead(nodeId); } theNode.nfCompleteRep = false; if(noOfAliveNodes == 0) { if (!global_flag_skip_invalidate_cache) { theFacade.m_globalDictCache.lock(); theFacade.m_globalDictCache.invalidate_all(); theFacade.m_globalDictCache.unlock(); m_connect_count ++; m_cluster_state = CS_waiting_for_clean_cache; } NFCompleteRep rep; for(Uint32 i = 1; i<MAX_NODES; i++){ if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){ rep.failedNodeId = i; execNF_COMPLETEREP((Uint32*)&rep); } } } }
void ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal, const LinearSectionPtr ptr[]) { const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf, signal->getDataPtr()); const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.defined == true); assert(node.is_connected() == true); if(node.m_info.m_version != apiRegConf->version) { node.m_info.m_version = apiRegConf->version; node.m_info.m_mysql_version = apiRegConf->mysql_version; if (node.m_info.m_version < NDBD_SPLIT_VERSION) node.m_info.m_mysql_version = 0; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.set_confirmed(true); if (node.minDbVersion != apiRegConf->minDbVersion) { node.minDbVersion = apiRegConf->minDbVersion; recalcMinDbVersion(); } if (node.m_info.m_version >= NDBD_255_NODES_VERSION) { node.m_state = apiRegConf->nodeState; } else { /** * from 2 to 8 words = 6 words diff, 6*4 = 24 */ memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24); } if (node.m_info.m_type == NodeInfo::DB) { /** * Only set DB nodes to "alive" */ if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())) { set_node_alive(node, true); } else { set_node_alive(node, false); } } cm_node.hbMissed = 0; cm_node.hbCounter = 0; /* By convention, conf->apiHeartbeatFrequency is in centiseconds rather than milliseconds. See also Qmgr::sendApiRegConf(). */ const Int64 freq = (static_cast<Int64>(apiRegConf->apiHeartbeatFrequency) * 10) - 50; if (freq > UINT_MAX32) { // In case of overflow. assert(false); /* Note this assert fails on some upgrades... */ cm_node.hbFrequency = UINT_MAX32; } else if (freq < minHeartBeatInterval) { /** * We use minHeartBeatInterval as a lower limit. This also prevents * against underflow. */ cm_node.hbFrequency = minHeartBeatInterval; } else { cm_node.hbFrequency = static_cast<Uint32>(freq); } // If responding nodes indicates that it is connected to other // nodes, that makes it probable that those nodes are alive and // available also for this node. for (int db_node_id = 1; db_node_id <= MAX_DATA_NODE_ID; db_node_id ++) { if (node.m_state.m_connected_nodes.get(db_node_id)) { // Tell this nodes start clients thread that db_node_id // is up and probable connectable. theFacade.theTransporterRegistry->indicate_node_up(db_node_id); } } // Distribute signal to all threads/blocks // TODO only if state changed... theFacade.for_each(this, signal, ptr); }
void ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal, const LinearSectionPtr ptr[]) { const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf, signal->getDataPtr()); const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.defined == true); assert(node.is_connected() == true); if(node.m_info.m_version != apiRegConf->version){ node.m_info.m_version = apiRegConf->version; node.m_info.m_mysql_version = apiRegConf->mysql_version; if (node.m_info.m_version < NDBD_SPLIT_VERSION) node.m_info.m_mysql_version = 0; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.set_confirmed(true); if (node.minDbVersion != apiRegConf->minDbVersion) { node.minDbVersion = apiRegConf->minDbVersion; recalcMinDbVersion(); } if (node.m_info.m_version >= NDBD_255_NODES_VERSION) { node.m_state = apiRegConf->nodeState; } else { /** * from 2 to 8 words = 6 words diff, 6*4 = 24 */ memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24); } if (node.m_info.m_type == NodeInfo::DB) { /** * Only set DB nodes to "alive" */ if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())) { set_node_alive(node, true); } else { set_node_alive(node, false); } } cm_node.hbMissed = 0; cm_node.hbCounter = 0; cm_node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50; // Distribute signal to all threads/blocks // TODO only if state changed... theFacade.for_each(this, signal, ptr); check_wait_for_hb(nodeId); }