void ClusterMgr::startup() { assert(theStop == -1); Uint32 nodeId = getOwnNodeId(); Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; assert(theNode.defined); lock(); theFacade.doConnect(nodeId); flush_send_buffers(); unlock(); for (Uint32 i = 0; i<3000; i++) { lock(); theFacade.theTransporterRegistry->update_connections(); flush_send_buffers(); unlock(); if (theNode.is_connected()) break; NdbSleep_MilliSleep(20); } assert(theNode.is_connected()); Guard g(clusterMgrThreadMutex); theStop = 0; NdbCondition_Broadcast(waitForHBCond); }
void ClusterMgr::startup() { assert(theStop == -1); Uint32 nodeId = getOwnNodeId(); Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; assert(theNode.defined); lock(); theFacade.doConnect(nodeId); flush_send_buffers(); unlock(); for (Uint32 i = 0; i<3000; i++) { theFacade.request_connection_check(); start_poll(); do_poll(0); complete_poll(); if (theNode.is_connected()) break; NdbSleep_MilliSleep(20); } assert(theNode.is_connected()); Guard g(clusterMgrThreadMutex); /* Signalling to creating thread that we are done with thread startup */ theStop = 0; NdbCondition_Broadcast(waitForHBCond); }
void *write_to_clients(void *c) { struct consumer_config *cc = (struct consumer_config *)c; fprintf(stderr, "in write_to_clients()\n"); while (*cc->keep_going) flush_send_buffers(&cc->sb, &cc->clients); return NULL; }
void ClusterMgr::threadMain() { startup(); NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); signal.theVerId_signalNumber = GSN_API_REGREQ; signal.theTrace = 0; signal.theLength = ApiRegReq::SignalLength; ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend()); req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId()); req->version = NDB_VERSION; req->mysql_version = NDB_MYSQL_VERSION_D; NdbApiSignal nodeFail_signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); nodeFail_signal.theVerId_signalNumber = GSN_NODE_FAILREP; nodeFail_signal.theReceiversBlockNumber = API_CLUSTERMGR; nodeFail_signal.theTrace = 0; nodeFail_signal.theLength = NodeFailRep::SignalLengthLong; NDB_TICKS now = NdbTick_getCurrentTicks(); while(!theStop) { /* Sleep 1/5 of minHeartBeatInterval between each check */ const NDB_TICKS before = now; for (Uint32 i = 0; i<5; i++) { NdbSleep_MilliSleep(minHeartBeatInterval/5); { /** * start_poll does lock the trp_client and complete_poll * releases this lock. This means that this protects * against concurrent calls to send signals in ArbitMgr. * We do however need to protect also against concurrent * close in doStop, so to avoid this problem we need to * also lock clusterMgrThreadMutex before we start the * poll. */ Guard g(clusterMgrThreadMutex); start_poll(); do_poll(0); complete_poll(); } } now = NdbTick_getCurrentTicks(); const Uint32 timeSlept = (Uint32)NdbTick_Elapsed(before, now).milliSec(); lock(); if (m_cluster_state == CS_waiting_for_clean_cache && theFacade.m_globalDictCache) { if (!global_flag_skip_waiting_for_clean_cache) { theFacade.m_globalDictCache->lock(); unsigned sz= theFacade.m_globalDictCache->get_size(); theFacade.m_globalDictCache->unlock(); if (sz) { unlock(); continue; } } m_cluster_state = CS_waiting_for_first_connect; } NodeFailRep * nodeFailRep = CAST_PTR(NodeFailRep, nodeFail_signal.getDataPtrSend()); nodeFailRep->noOfNodes = 0; NodeBitmask::clear(nodeFailRep->theAllNodes); for (int i = 1; i < MAX_NODES; i++) { /** * Send register request (heartbeat) to all available nodes * at specified timing intervals */ const NodeId nodeId = i; // Check array bounds + don't allow node 0 to be touched assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; if (!theNode.defined) continue; if (theNode.is_connected() == false) { theFacade.doConnect(nodeId); continue; } if (!theNode.compatible) { continue; } if (nodeId == getOwnNodeId()) { /** * Don't send HB to self more than once * (once needed to avoid weird special cases in e.g ConfigManager) */ if (m_sent_API_REGREQ_to_myself) { continue; } } cm_node.hbCounter += timeSlept; if (cm_node.hbCounter >= m_max_api_reg_req_interval || cm_node.hbCounter >= cm_node.hbFrequency) { /** * It is now time to send a new Heartbeat */ if (cm_node.hbCounter >= cm_node.hbFrequency) { cm_node.hbMissed++; cm_node.hbCounter = 0; } if (theNode.m_info.m_type != NodeInfo::DB) signal.theReceiversBlockNumber = API_CLUSTERMGR; else signal.theReceiversBlockNumber = QMGR; #ifdef DEBUG_REG ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); #endif if (nodeId == getOwnNodeId()) { /* Set flag to ensure we only send once to ourself */ m_sent_API_REGREQ_to_myself = true; } raw_sendSignal(&signal, nodeId); }//if if (cm_node.hbMissed == 4 && cm_node.hbFrequency > 0) { nodeFailRep->noOfNodes++; NodeBitmask::set(nodeFailRep->theAllNodes, nodeId); } } flush_send_buffers(); unlock(); if (nodeFailRep->noOfNodes) { lock(); raw_sendSignal(&nodeFail_signal, getOwnNodeId()); flush_send_buffers(); unlock(); } } }
void ClusterMgr::threadMain() { startup(); NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); signal.theVerId_signalNumber = GSN_API_REGREQ; signal.theTrace = 0; signal.theLength = ApiRegReq::SignalLength; ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend()); req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId()); req->version = NDB_VERSION; req->mysql_version = NDB_MYSQL_VERSION_D; NdbApiSignal nodeFail_signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); nodeFail_signal.theVerId_signalNumber = GSN_NODE_FAILREP; nodeFail_signal.theReceiversBlockNumber = API_CLUSTERMGR; nodeFail_signal.theTrace = 0; nodeFail_signal.theLength = NodeFailRep::SignalLengthLong; NDB_TICKS timeSlept = 100; NDB_TICKS now = NdbTick_CurrentMillisecond(); while(!theStop) { /* Sleep at 100ms between each heartbeat check */ NDB_TICKS before = now; for (Uint32 i = 0; i<5; i++) { NdbSleep_MilliSleep(20); { Guard g(clusterMgrThreadMutex); /** * Protect from ArbitMgr sending signals while we poll */ start_poll(); do_poll(0); complete_poll(); } } now = NdbTick_CurrentMillisecond(); timeSlept = (now - before); if (m_cluster_state == CS_waiting_for_clean_cache && theFacade.m_globalDictCache) { if (!global_flag_skip_waiting_for_clean_cache) { theFacade.m_globalDictCache->lock(); unsigned sz= theFacade.m_globalDictCache->get_size(); theFacade.m_globalDictCache->unlock(); if (sz) continue; } m_cluster_state = CS_waiting_for_first_connect; } NodeFailRep * nodeFailRep = CAST_PTR(NodeFailRep, nodeFail_signal.getDataPtrSend()); nodeFailRep->noOfNodes = 0; NodeBitmask::clear(nodeFailRep->theAllNodes); lock(); for (int i = 1; i < MAX_NODES; i++){ /** * Send register request (heartbeat) to all available nodes * at specified timing intervals */ const NodeId nodeId = i; // Check array bounds + don't allow node 0 to be touched assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; if (!theNode.defined) continue; if (theNode.is_connected() == false){ theFacade.doConnect(nodeId); continue; } if (!theNode.compatible){ continue; } if (nodeId == getOwnNodeId() && theNode.is_confirmed()) { /** * Don't send HB to self more than once * (once needed to avoid weird special cases in e.g ConfigManager) */ continue; } cm_node.hbCounter += (Uint32)timeSlept; if (cm_node.hbCounter >= m_max_api_reg_req_interval || cm_node.hbCounter >= cm_node.hbFrequency) { /** * It is now time to send a new Heartbeat */ if (cm_node.hbCounter >= cm_node.hbFrequency) { cm_node.hbMissed++; cm_node.hbCounter = 0; } if (theNode.m_info.m_type != NodeInfo::DB) signal.theReceiversBlockNumber = API_CLUSTERMGR; else signal.theReceiversBlockNumber = QMGR; #ifdef DEBUG_REG ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); #endif raw_sendSignal(&signal, nodeId); }//if if (cm_node.hbMissed == 4 && cm_node.hbFrequency > 0) { nodeFailRep->noOfNodes++; NodeBitmask::set(nodeFailRep->theAllNodes, nodeId); } } flush_send_buffers(); unlock(); if (nodeFailRep->noOfNodes) { lock(); raw_sendSignal(&nodeFail_signal, getOwnNodeId()); flush_send_buffers(); unlock(); } } }
void ClusterMgr::forceHB() { theFacade.lock_poll_mutex(); if(waitingForHB) { NdbCondition_WaitTimeout(waitForHBCond, theFacade.thePollMutex, 1000); theFacade.unlock_poll_mutex(); return; } waitingForHB= true; NodeBitmask ndb_nodes; ndb_nodes.clear(); waitForHBFromNodes.clear(); for(Uint32 i = 1; i < MAX_NDB_NODES; i++) { const trp_node &node= getNodeInfo(i); if(!node.defined) continue; if(node.m_info.getType() == NodeInfo::DB) { ndb_nodes.set(i); waitForHBFromNodes.bitOR(node.m_state.m_connected_nodes); } } waitForHBFromNodes.bitAND(ndb_nodes); theFacade.unlock_poll_mutex(); #ifdef DEBUG_REG char buf[128]; ndbout << "Waiting for HB from " << waitForHBFromNodes.getText(buf) << endl; #endif NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); signal.theVerId_signalNumber = GSN_API_REGREQ; signal.theReceiversBlockNumber = QMGR; signal.theTrace = 0; signal.theLength = ApiRegReq::SignalLength; ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend()); req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId()); req->version = NDB_VERSION; req->mysql_version = NDB_MYSQL_VERSION_D; { lock(); int nodeId= 0; for(int i=0; (int) NodeBitmask::NotFound != (nodeId= waitForHBFromNodes.find(i)); i= nodeId+1) { #ifdef DEBUG_REG ndbout << "FORCE HB to " << nodeId << endl; #endif raw_sendSignal(&signal, nodeId); } flush_send_buffers(); unlock(); } /* Wait for nodes to reply - if any heartbeats was sent */ theFacade.lock_poll_mutex(); if (!waitForHBFromNodes.isclear()) NdbCondition_WaitTimeout(waitForHBCond, theFacade.thePollMutex, 1000); waitingForHB= false; #ifdef DEBUG_REG ndbout << "Still waiting for HB from " << waitForHBFromNodes.getText(buf) << endl; #endif theFacade.unlock_poll_mutex(); }