Beispiel #1
0
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);
      }
    }
  }
}
Beispiel #2
0
/**
 * We're holding the trp_client lock while performing poll from
 * ClusterMgr. So we always execute all the execSIGNAL-methods in
 * ClusterMgr with protection other methods that use the trp_client
 * lock (reportDisconnect, reportConnect, is_cluster_completely_unavailable,
 * ArbitMgr (sendSignalToQmgr)).
 */
void
ClusterMgr::trp_deliver_signal(const NdbApiSignal* sig,
                               const LinearSectionPtr ptr[3])
{
    const Uint32 gsn = sig->theVerId_signalNumber;
    const Uint32 * theData = sig->getDataPtr();

    switch (gsn) {
    case GSN_API_REGREQ:
        execAPI_REGREQ(theData);
        break;

    case GSN_API_REGCONF:
        execAPI_REGCONF(sig, ptr);
        break;

    case GSN_API_REGREF:
        execAPI_REGREF(theData);
        break;

    case GSN_NODE_FAILREP:
        execNODE_FAILREP(sig, ptr);
        break;

    case GSN_NF_COMPLETEREP:
        execNF_COMPLETEREP(sig, ptr);
        break;
    case GSN_ARBIT_STARTREQ:
        if (theArbitMgr != NULL)
            theArbitMgr->doStart(theData);
        break;

    case GSN_ARBIT_CHOOSEREQ:
        if (theArbitMgr != NULL)
            theArbitMgr->doChoose(theData);
        break;

    case GSN_ARBIT_STOPORD:
        if(theArbitMgr != NULL)
            theArbitMgr->doStop(theData);
        break;

    case GSN_ALTER_TABLE_REP:
    {
        if (theFacade.m_globalDictCache == NULL)
            break;
        const AlterTableRep* rep = (const AlterTableRep*)theData;
        theFacade.m_globalDictCache->lock();
        theFacade.m_globalDictCache->
        alter_table_rep((const char*)ptr[0].p,
                        rep->tableId,
                        rep->tableVersion,
                        rep->changeType == AlterTableRep::CT_ALTERED);
        theFacade.m_globalDictCache->unlock();
        break;
    }
    case GSN_SUB_GCP_COMPLETE_REP:
    {
        /**
         * Report
         */
        theFacade.for_each(this, sig, ptr);

        /**
         * Reply
         */
        {
            BlockReference ownRef = numberToRef(API_CLUSTERMGR, theFacade.ownId());
            NdbApiSignal tSignal(* sig);
            Uint32* send= tSignal.getDataPtrSend();
            memcpy(send, theData, tSignal.getLength() << 2);
            CAST_PTR(SubGcpCompleteAck, send)->rep.senderRef = ownRef;
            Uint32 ref= sig->theSendersBlockRef;
            Uint32 aNodeId= refToNode(ref);
            tSignal.theReceiversBlockNumber= refToBlock(ref);
            tSignal.theVerId_signalNumber= GSN_SUB_GCP_COMPLETE_ACK;
            tSignal.theSendersBlockRef = API_CLUSTERMGR;
            safe_noflush_sendSignal(&tSignal, aNodeId);
        }
        break;
    }
    case GSN_TAKE_OVERTCCONF:
    {
        /**
         * Report
         */
        theFacade.for_each(this, sig, ptr);
        return;
    }
    case GSN_CONNECT_REP:
    {
        execCONNECT_REP(sig, ptr);
        return;
    }
    case GSN_DISCONNECT_REP:
    {
        execDISCONNECT_REP(sig, ptr);
        return;
    }
    case GSN_CLOSE_COMREQ:
    {
        theFacade.perform_close_clnt(this);
        return;
    }
    case GSN_EXPAND_CLNT:
    {
        theFacade.expand_clnt();
        return;
    }
    default:
        break;

    }
    return;
}
Beispiel #3
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);
            }
        }
    }
}