Esempio n. 1
0
void
ClusterMgr::execNODE_FAILREP(const NdbApiSignal* sig,
                             const LinearSectionPtr ptr[])
{
    const NodeFailRep * rep = CAST_CONSTPTR(NodeFailRep, sig->getDataPtr());
    NodeBitmask mask;
    if (sig->getLength() == NodeFailRep::SignalLengthLong)
    {
        mask.assign(NodeBitmask::Size, rep->theAllNodes);
    }
    else
    {
        mask.assign(NdbNodeBitmask::Size, rep->theNodes);
    }

    NdbApiSignal signal(sig->theSendersBlockRef);
    signal.theVerId_signalNumber = GSN_NODE_FAILREP;
    signal.theReceiversBlockNumber = API_CLUSTERMGR;
    signal.theTrace  = 0;
    signal.theLength = NodeFailRep::SignalLengthLong;

    NodeFailRep * copy = CAST_PTR(NodeFailRep, signal.getDataPtrSend());
    copy->failNo = 0;
    copy->masterNodeId = 0;
    copy->noOfNodes = 0;
    NodeBitmask::clear(copy->theAllNodes);

    for (Uint32 i = mask.find_first(); i != NodeBitmask::NotFound;
            i = mask.find_next(i + 1))
    {
        Node & cm_node = theNodes[i];
        trp_node & theNode = cm_node;

        bool node_failrep = theNode.m_node_fail_rep;
        bool connected = theNode.is_connected();
        set_node_dead(theNode);

        if (node_failrep == false)
        {
            theNode.m_node_fail_rep = true;
            NodeBitmask::set(copy->theAllNodes, i);
            copy->noOfNodes++;
        }

        if (connected)
        {
            theFacade.doDisconnect(i);
        }
    }

    recalcMinDbVersion();
    if (copy->noOfNodes)
    {
        theFacade.for_each(this, &signal, 0); // report GSN_NODE_FAILREP
    }

    if (noOfAliveNodes == 0)
    {
        NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId()));
        signal.theVerId_signalNumber = GSN_NF_COMPLETEREP;
        signal.theReceiversBlockNumber = 0;
        signal.theTrace  = 0;
        signal.theLength = NFCompleteRep::SignalLength;

        NFCompleteRep * rep = CAST_PTR(NFCompleteRep, signal.getDataPtrSend());
        rep->blockNo =0;
        rep->nodeId = getOwnNodeId();
        rep->unused = 0;
        rep->from = __LINE__;

        for (Uint32 i = 1; i < MAX_NODES; i++)
        {
            trp_node& theNode = theNodes[i];
            if (theNode.defined && theNode.nfCompleteRep == false)
            {
                rep->failedNodeId = i;
                execNF_COMPLETEREP(&signal, 0);
            }
        }
    }
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}