int
Dbtup::addTuxEntries(Signal* signal,
                     Operationrec* regOperPtr,
                     Tablerec* regTabPtr)
{
  if (ERROR_INSERTED(4022)) {
    jam();
    CLEAR_ERROR_INSERT_VALUE;
    terrorCode = 9999;
    return -1;
  }
  TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
  const DLList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
  TriggerPtr triggerPtr;
  Uint32 failPtrI;
  triggerList.first(triggerPtr);
  while (triggerPtr.i != RNIL) {
    jam();
    req->indexId = triggerPtr.p->indexId;
    req->errorCode = RNIL;
    if (ERROR_INSERTED(4023) &&
        ! triggerList.hasNext(triggerPtr)) {
      jam();
      CLEAR_ERROR_INSERT_VALUE;
      terrorCode = 9999;
      failPtrI = triggerPtr.i;
      goto fail;
    }
    EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
        signal, TuxMaintReq::SignalLength);
    jamEntry();
    if (req->errorCode != 0) {
      jam();
      terrorCode = req->errorCode;
      failPtrI = triggerPtr.i;
      goto fail;
    }
    triggerList.next(triggerPtr);
  }
  return 0;
fail:
  req->opInfo = TuxMaintReq::OpRemove;
  triggerList.first(triggerPtr);
  while (triggerPtr.i != failPtrI) {
    jam();
    req->indexId = triggerPtr.p->indexId;
    req->errorCode = RNIL;
    EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
        signal, TuxMaintReq::SignalLength);
    jamEntry();
    ndbrequire(req->errorCode == 0);
    triggerList.next(triggerPtr);
  }
#ifdef VM_TRACE
  ndbout << "aborted partial tux update: op " << hex << regOperPtr << endl;
#endif
  return -1;
}
/*
 * Allocate index node in TUP.
 */
int
Dbtux::allocNode(TuxCtx& ctx, NodeHandle& node)
{
  if (ERROR_INSERTED(12007)) {
    jam();
    CLEAR_ERROR_INSERT_VALUE;
    return TuxMaintReq::NoMemError;
  }
  Frag& frag = node.m_frag;
  Uint32 pageId = NullTupLoc.getPageId();
  Uint32 pageOffset = NullTupLoc.getPageOffset();
  Uint32* node32 = 0;
  int errorCode = c_tup->tuxAllocNode(ctx.jamBuffer,
                                      frag.m_tupIndexFragPtrI,
                                      pageId, pageOffset, node32);
  thrjamEntry(ctx.jamBuffer);
  if (errorCode == 0) {
    thrjam(ctx.jamBuffer);
    node.m_loc = TupLoc(pageId, pageOffset);
    node.m_node = reinterpret_cast<TreeNode*>(node32);
    ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
  } else {
    switch (errorCode) {
    case 827:
      errorCode = TuxMaintReq::NoMemError;
      break;
    }
  }
  return errorCode;
}
Example #3
0
void Cmvmi::execNDB_TAMPER(Signal* signal) 
{
  jamEntry();
  SET_ERROR_INSERT_VALUE(signal->theData[0]);
  if(ERROR_INSERTED(9999)){
    CRASH_INSERTION(9999);
  }

  if(ERROR_INSERTED(9998)){
    while(true) NdbSleep_SecSleep(1);
  }

  if(ERROR_INSERTED(9997)){
    ndbrequire(false);
  }

#ifndef NDB_WIN32
  if(ERROR_INSERTED(9996)){
    simulate_error_during_shutdown= SIGSEGV;
    ndbrequire(false);
  }

  if(ERROR_INSERTED(9995)){
    simulate_error_during_shutdown= SIGSEGV;
    kill(getpid(), SIGABRT);
  }
#endif

#ifdef ERROR_INSERT
  if (signal->theData[0] == 9003)
  {
    if (MAX_RECEIVED_SIGNALS < 1024)
    {
      MAX_RECEIVED_SIGNALS = 1024;
    }
    else
    {
      MAX_RECEIVED_SIGNALS = 1 + (rand() % 128);
    }
    ndbout_c("MAX_RECEIVED_SIGNALS: %d", MAX_RECEIVED_SIGNALS);
    CLEAR_ERROR_INSERT_VALUE;
  }
#endif
}//execNDB_TAMPER()
/* ---------------------------------------------------------------- */
Uint32
Dbtup::dropTrigger(Tablerec* table, const DropTrigReq* req, BlockNumber sender)
{
  if (ERROR_INSERTED(4004)) {
    CLEAR_ERROR_INSERT_VALUE;
    return 9999;
  }
  Uint32 triggerId = req->getTriggerId();

  TriggerType::Value ttype = req->getTriggerType();
  TriggerActionTime::Value ttime = req->getTriggerActionTime();
  TriggerEvent::Value tevent = req->getTriggerEvent();

  //  ndbout_c("Drop TupTrigger %u = %u %u %u %u by %u", triggerId, table, ttype, ttime, tevent, sender);

  DLList<TupTriggerData>* tlist = findTriggerList(table, ttype, ttime, tevent);
  ndbrequire(tlist != NULL);

  Ptr<TupTriggerData> ptr;
  for (tlist->first(ptr); !ptr.isNull(); tlist->next(ptr)) {
    jam();
    if (ptr.p->triggerId == triggerId) {
      if(ttype==TriggerType::SUBSCRIPTION && sender != ptr.p->m_receiverBlock)
      {
	/**
	 * You can only drop your own triggers for subscription triggers.
	 * Trigger IDs are private for each block.
	 *
	 * SUMA encodes information in the triggerId
	 *
	 * Backup doesn't really care about the Ids though.
	 */
	jam();
	continue;
      }
      jam();
      tlist->release(ptr.i);
      return 0;
    }
  }
  return DropTrigRef::TriggerNotFound;
}//Dbtup::dropTrigger()
Example #5
0
void
Trpman::execCONNECT_REP(Signal *signal)
{
  const Uint32 hostId = signal->theData[0];
  jamEntry();

  const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
  ndbrequire(type != NodeInfo::INVALID);

  /**
   * Inform QMGR that client has connected
   */
  signal->theData[0] = hostId;
  if (ERROR_INSERTED(9005))
  {
    sendSignalWithDelay(QMGR_REF, GSN_CONNECT_REP, signal, 50, 1);
  }
  else
  {
    sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
  }

  /* Automatically subscribe events for MGM nodes.
   */
  if (type == NodeInfo::MGM)
  {
    jam();
    globalTransporterRegistry.setIOState(hostId, NoHalt);
  }

  //------------------------------------------
  // Also report this event to the Event handler
  //------------------------------------------
  signal->theData[0] = NDB_LE_Connected;
  signal->theData[1] = hostId;
  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
Example #6
0
void
MgmApiSession::getConfig(Parser_t::Context &,
                         const class Properties &args)
{
  Uint32 version, node = 0;

  args.get("version", &version);
  args.get("node", &node);

  const Config *conf = m_mgmsrv.getConfig();
  if(conf == NULL) {
    m_output->println("get config reply");
    m_output->println("result: Could not fetch configuration");
    m_output->println("");
    return;
  }

  if(node != 0){
    bool compatible;
    switch (m_mgmsrv.getNodeType(node)) {
    case NDB_MGM_NODE_TYPE_NDB:
      compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
      break;
    case NDB_MGM_NODE_TYPE_API:
    case NDB_MGM_NODE_TYPE_MGM:
      compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
      break;
    default:
      m_output->println("get config");
      m_output->println("result: unrecognignized node type");
      m_output->println("");
      return;
    }
    
    if (!compatible){
      m_output->println("get config");
      m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
			NDB_VERSION, version);
      m_output->println("");
      return;
    }
  }  
  
  NdbMutex_Lock(m_mgmsrv.m_configMutex);
  const ConfigValues * cfg = &conf->m_configValues->m_config;
  
  UtilBuffer src;
  cfg->pack(src);
  NdbMutex_Unlock(m_mgmsrv.m_configMutex);
  
  char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
  (void) base64_encode(src.get_data(), src.length(), tmp_str);

  SLEEP_ERROR_INSERTED(1);

  m_output->println("get config reply");
  m_output->println("result: Ok");
  m_output->println("Content-Length: %d", strlen(tmp_str));
  m_output->println("Content-Type: ndbconfig/octet-stream");
  SLEEP_ERROR_INSERTED(2);
  m_output->println("Content-Transfer-Encoding: base64");
  m_output->println("");
  if(ERROR_INSERTED(3))
  {
    int l= strlen(tmp_str);
    tmp_str[l/2]='\0';
    m_output->println(tmp_str);
    NdbSleep_SecSleep(10);
  }
  m_output->println(tmp_str);

  free(tmp_str);
  return;
}
bool Dbtup::storedProcedureAttrInfo(Signal* signal,
                                    Operationrec* regOperPtr,
				    const Uint32 *data,
                                    Uint32 length,
                                    bool copyProcedure) 
{
  AttrbufrecPtr regAttrPtr;
  Uint32 RnoFree = cnoFreeAttrbufrec;
  if (ERROR_INSERTED(4004) && !copyProcedure) {
    CLEAR_ERROR_INSERT_VALUE;
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
    return false;
  }//if
  regOperPtr->currentAttrinbufLen += length;
  ndbrequire(regOperPtr->currentAttrinbufLen <= regOperPtr->attrinbufLen);
  if ((RnoFree > MIN_ATTRBUF) ||
      (copyProcedure)) {
    jam();
    regAttrPtr.i = cfirstfreeAttrbufrec;
    ptrCheckGuard(regAttrPtr, cnoOfAttrbufrec, attrbufrec);
    regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = 0;
    cfirstfreeAttrbufrec = regAttrPtr.p->attrbuf[ZBUF_NEXT];
    cnoFreeAttrbufrec = RnoFree - 1;
    regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
  } else {
    jam();
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
    return false;
  }//if
  if (regOperPtr->firstAttrinbufrec == RNIL) {
    jam();
    regOperPtr->firstAttrinbufrec = regAttrPtr.i;
  }//if
  regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
  if (regOperPtr->lastAttrinbufrec != RNIL) {
    AttrbufrecPtr tempAttrinbufptr;
    jam();
    tempAttrinbufptr.i = regOperPtr->lastAttrinbufrec;  
    ptrCheckGuard(tempAttrinbufptr, cnoOfAttrbufrec, attrbufrec);
    tempAttrinbufptr.p->attrbuf[ZBUF_NEXT] = regAttrPtr.i;
  }//if
  regOperPtr->lastAttrinbufrec = regAttrPtr.i;

  regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = length;
  MEMCOPY_NO_WORDS(&regAttrPtr.p->attrbuf[0],
                   data,
                   length);

  if (regOperPtr->currentAttrinbufLen < regOperPtr->attrinbufLen) {
    jam();
    return true;
  }//if
  if (ERROR_INSERTED(4005) && !copyProcedure) {
    CLEAR_ERROR_INSERT_VALUE;
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
    return false;
  }//if

  StoredProcPtr storedPtr;
  c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcPtr);
  ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);

  regOperPtr->currentAttrinbufLen = 0;
  storedPtr.p->storedLinkFirst = regOperPtr->firstAttrinbufrec;
  storedPtr.p->storedLinkLast = regOperPtr->lastAttrinbufrec;
  regOperPtr->firstAttrinbufrec = RNIL;
  regOperPtr->lastAttrinbufrec = RNIL;
  regOperPtr->m_any_value = 0;
  set_trans_state(regOperPtr, TRANS_IDLE);
  signal->theData[0] = regOperPtr->userpointer;
  signal->theData[1] = storedPtr.i;
  sendSignal(DBLQH_REF, GSN_STORED_PROCCONF, signal, 2, JBB);
  return true;
}//Dbtup::storedProcedureAttrInfo()
Example #8
0
void Cmvmi::execOPEN_COMREQ(Signal* signal)
{
  // Connect to the specifed NDB node, only QMGR allowed communication 
  // so far with the node

  const BlockReference userRef = signal->theData[0];
  Uint32 tStartingNode = signal->theData[1];
  Uint32 tData2 = signal->theData[2];
  jamEntry();

  const Uint32 len = signal->getLength();
  if(len == 2)
  {
#ifdef ERROR_INSERT
    if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002)) 
	   && c_error_9000_nodes_mask.get(tStartingNode)))
#endif
    {
      if (globalData.theStartLevel != NodeState::SL_STARTED &&
          (getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
           getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
      {
        jam();
        goto done;
      }

      globalTransporterRegistry.do_connect(tStartingNode);
      globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
      
      //-----------------------------------------------------
      // Report that the connection to the node is opened
      //-----------------------------------------------------
      signal->theData[0] = NDB_LE_CommunicationOpened;
      signal->theData[1] = tStartingNode;
      sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      //-----------------------------------------------------
    }
  } else {
    for(unsigned int i = 1; i < MAX_NODES; i++ ) 
    {
      jam();
      if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2)
      {
	jam();

#ifdef ERROR_INSERT
	if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
	    && c_error_9000_nodes_mask.get(i))
	  continue;
#endif
	
	globalTransporterRegistry.do_connect(i);
	globalTransporterRegistry.setIOState(i, HaltIO);
	
	signal->theData[0] = NDB_LE_CommunicationOpened;
	signal->theData[1] = i;
	sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      }
    }
  }
  
done:  
  if (userRef != 0) {
    jam(); 
    signal->theData[0] = tStartingNode;
    signal->theData[1] = tData2;
    sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA);
  }
}
Example #9
0
void
Dbtup::execBUILD_INDX_IMPL_REQ(Signal* signal)
{
  jamEntry();
#ifdef TIME_MEASUREMENT
  time_events= 0;
  tot_time_passed= 0;
  number_events= 1;
#endif
  const BuildIndxImplReq* const req =
    (const BuildIndxImplReq*)signal->getDataPtr();
  // get new operation
  BuildIndexPtr buildPtr;
  if (ERROR_INSERTED(4031) || ! c_buildIndexList.seizeFirst(buildPtr)) {
    jam();
    BuildIndexRec buildRec;
    buildRec.m_request = *req;
    buildRec.m_errorCode = BuildIndxImplRef::Busy;
    if (ERROR_INSERTED(4031))
    {
      CLEAR_ERROR_INSERT_VALUE;
    }
    buildIndexReply(signal, &buildRec);
    return;
  }
  buildPtr.p->m_request = *req;
  const BuildIndxImplReq* buildReq = &buildPtr.p->m_request;
  // check
  buildPtr.p->m_errorCode= BuildIndxImplRef::NoError;
  buildPtr.p->m_outstanding = 0;
  do {
    if (buildReq->tableId >= cnoOfTablerec) {
      jam();
      buildPtr.p->m_errorCode= BuildIndxImplRef::InvalidPrimaryTable;
      break;
    }
    TablerecPtr tablePtr;
    tablePtr.i= buildReq->tableId;
    ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
    if (tablePtr.p->tableStatus != DEFINED) {
      jam();
      buildPtr.p->m_errorCode= BuildIndxImplRef::InvalidPrimaryTable;
      break;
    }
    // memory page format
    buildPtr.p->m_build_vs =
      (tablePtr.p->m_attributes[MM].m_no_of_varsize +
       tablePtr.p->m_attributes[MM].m_no_of_dynamic) > 0;
    if (DictTabInfo::isOrderedIndex(buildReq->indexType)) {
      jam();
      const DLList<TupTriggerData>& triggerList = 
	tablePtr.p->tuxCustomTriggers;

      TriggerPtr triggerPtr;
      triggerList.first(triggerPtr);
      while (triggerPtr.i != RNIL) {
	if (triggerPtr.p->indexId == buildReq->indexId) {
	  jam();
	  break;
	}
	triggerList.next(triggerPtr);
      }
      if (triggerPtr.i == RNIL) {
	jam();
	// trigger was not created
        ndbassert(false);
	buildPtr.p->m_errorCode = BuildIndxImplRef::InternalError;
	break;
      }
      buildPtr.p->m_indexId = buildReq->indexId;
      buildPtr.p->m_buildRef = DBTUX;
      AlterIndxImplReq* req = (AlterIndxImplReq*)signal->getDataPtrSend();
      req->indexId = buildReq->indexId;
      req->senderRef = 0;
      req->requestType = AlterIndxImplReq::AlterIndexBuilding;
      EXECUTE_DIRECT(DBTUX, GSN_ALTER_INDX_IMPL_REQ, signal, 
                     AlterIndxImplReq::SignalLength);
    } else if(buildReq->indexId == RNIL) {
      jam();
      // REBUILD of acc
      buildPtr.p->m_indexId = RNIL;
      buildPtr.p->m_buildRef = DBACC;
    } else {
      jam();
      buildPtr.p->m_errorCode = BuildIndxImplRef::InvalidIndexType;
      break;
    }

    // set to first tuple position
    const Uint32 firstTupleNo = 0;
    buildPtr.p->m_fragNo= 0;
    buildPtr.p->m_pageId= 0;
    buildPtr.p->m_tupleNo= firstTupleNo;
    // start build

    bool offline = !!(buildReq->requestType&BuildIndxImplReq::RF_BUILD_OFFLINE);
    if (offline && m_max_parallel_index_build > 1)
    {
      jam();
      buildIndexOffline(signal, buildPtr.i);
    }
    else
    {
      jam();
      buildIndex(signal, buildPtr.i);
    }
    return;
  } while (0);
  // check failed
  buildIndexReply(signal, buildPtr.p);
  c_buildIndexList.release(buildPtr);
}
Example #10
0
void
Trpman::execOPEN_COMORD(Signal* signal)
{
  // Connect to the specifed NDB node, only QMGR allowed communication
  // so far with the node

  const BlockReference userRef = signal->theData[0];
  Uint32 tStartingNode = signal->theData[1];
  Uint32 tData2 = signal->theData[2];
  jamEntry();

  const Uint32 len = signal->getLength();
  if (len == 2)
  {
#ifdef ERROR_INSERT
    if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
	   && c_error_9000_nodes_mask.get(tStartingNode)))
#endif
    {
      if (!handles_this_node(tStartingNode))
      {
        jam();
        goto done;
      }

      globalTransporterRegistry.do_connect(tStartingNode);
      globalTransporterRegistry.setIOState(tStartingNode, HaltIO);

      //-----------------------------------------------------
      // Report that the connection to the node is opened
      //-----------------------------------------------------
      signal->theData[0] = NDB_LE_CommunicationOpened;
      signal->theData[1] = tStartingNode;
      sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      //-----------------------------------------------------
    }
  }
  else
  {
    for(unsigned int i = 1; i < MAX_NODES; i++ )
    {
      jam();
      if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2 &&
          handles_this_node(i))
      {
	jam();

#ifdef ERROR_INSERT
	if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
	    && c_error_9000_nodes_mask.get(i))
	  continue;
#endif
	globalTransporterRegistry.do_connect(i);
	globalTransporterRegistry.setIOState(i, HaltIO);

	signal->theData[0] = NDB_LE_CommunicationOpened;
	signal->theData[1] = i;
	sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      }
    }
  }

done:
  /**
   * NO REPLY for now
   */
  (void)userRef;
}
Example #11
0
void
Trpman::execDUMP_STATE_ORD(Signal* signal)
{
  DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
  Uint32 arg = dumpState->args[0]; (void)arg;

#ifdef ERROR_INSERT
  if (arg == 9000 || arg == 9002)
  {
    SET_ERROR_INSERT_VALUE(arg);
    for (Uint32 i = 1; i<signal->getLength(); i++)
      c_error_9000_nodes_mask.set(signal->theData[i]);
  }

  if (arg == 9001)
  {
    CLEAR_ERROR_INSERT_VALUE;
    if (signal->getLength() == 1 || signal->theData[1])
    {
      signal->header.theLength = 2;
      for (Uint32 i = 1; i<MAX_NODES; i++)
      {
        if (c_error_9000_nodes_mask.get(i) &&
            handles_this_node(i))
        {
          signal->theData[0] = 0;
          signal->theData[1] = i;
          execOPEN_COMORD(signal);
        }
      }
    }
    c_error_9000_nodes_mask.clear();
  }

  if (arg == 9004 && signal->getLength() == 2)
  {
    SET_ERROR_INSERT_VALUE(9004);
    c_error_9000_nodes_mask.clear();
    c_error_9000_nodes_mask.set(signal->theData[1]);
  }

  if (arg == 9005 && signal->getLength() == 2 && ERROR_INSERTED(9004))
  {
    Uint32 db = signal->theData[1];
    Uint32 i = c_error_9000_nodes_mask.find(1);
    if (handles_this_node(i))
    {
      signal->theData[0] = i;
      sendSignal(calcQmgrBlockRef(db),GSN_API_FAILREQ, signal, 1, JBA);
      ndbout_c("stopping %u using %u", i, db);
    }
    CLEAR_ERROR_INSERT_VALUE;
  }
#endif

#ifdef ERROR_INSERT
  /* <Target NodeId> dump 9992 <NodeId list>
   * On Target NodeId, block receiving signals from NodeId list
   *
   * <Target NodeId> dump 9993 <NodeId list>
   * On Target NodeId, resume receiving signals from NodeId list
   *
   * <Target NodeId> dump 9991
   * On Target NodeId, resume receiving signals from any blocked node
   *
   *
   * See also code in QMGR for blocking receive from nodes based
   * on HB roles.
   *
   */
  if((arg == 9993) ||  /* Unblock recv from nodeid */
     (arg == 9992))    /* Block recv from nodeid */
  {
    bool block = (arg == 9992);
    TransporterReceiveHandle * recvdata = mt_get_trp_receive_handle(instance());
    assert(recvdata != 0);
    for (Uint32 n = 1; n < signal->getLength(); n++)
    {
      Uint32 nodeId = signal->theData[n];
      if (!handles_this_node(nodeId))
        continue;

      if ((nodeId > 0) &&
          (nodeId < MAX_NODES))
      {
        if (block)
        {
          ndbout_c("TRPMAN : Blocking receive from node %u", nodeId);
          globalTransporterRegistry.blockReceive(*recvdata, nodeId);
        }
        else
        {
          ndbout_c("TRPMAN : Unblocking receive from node %u", nodeId);

          globalTransporterRegistry.unblockReceive(*recvdata, nodeId);
        }
      }
      else
      {
        ndbout_c("TRPMAN : Ignoring dump %u for node %u",
                 arg, nodeId);
      }
    }
  }
  if (arg == 9990) /* Block recv from all ndbd matching pattern */
  {
    Uint32 pattern = 0;
    if (signal->getLength() > 1)
    {
      pattern = signal->theData[1];
      ndbout_c("TRPMAN : Blocking receive from all ndbds matching pattern -%s-",
               ((pattern == 1)? "Other side":"Unknown"));
    }

    TransporterReceiveHandle * recvdata = mt_get_trp_receive_handle(instance());
    assert(recvdata != 0);
    for (Uint32 node = 1; node < MAX_NDB_NODES; node++)
    {
      if (!handles_this_node(node))
        continue;
      if (globalTransporterRegistry.is_connected(node))
      {
        if (getNodeInfo(node).m_type == NodeInfo::DB)
        {
          if (!globalTransporterRegistry.isBlocked(node))
          {
            switch (pattern)
            {
            case 1:
            {
              /* Match if given node is on 'other side' of
               * 2-replica cluster
               */
              if ((getOwnNodeId() & 1) != (node & 1))
              {
                /* Node is on the 'other side', match */
                break;
              }
              /* Node is on 'my side', don't match */
              continue;
            }
            default:
              break;
            }
            ndbout_c("TRPMAN : Blocking receive from node %u", node);
            globalTransporterRegistry.blockReceive(*recvdata, node);
          }
        }
      }
    }
  }
  if (arg == 9991) /* Unblock recv from all blocked */
  {
    TransporterReceiveHandle * recvdata = mt_get_trp_receive_handle(instance());
    assert(recvdata != 0);
    for (Uint32 node = 1; node < MAX_NODES; node++)
    {
      if (!handles_this_node(node))
        continue;
      if (globalTransporterRegistry.isBlocked(node))
      {
        ndbout_c("CMVMI : Unblocking receive from node %u", node);
        globalTransporterRegistry.unblockReceive(*recvdata, node);
      }
    }
  }
#endif
}
/* ---------------------------------------------------------------- */
bool
Dbtup::createTrigger(Tablerec* table, const CreateTrigReq* req)
{
  if (ERROR_INSERTED(4003)) {
    CLEAR_ERROR_INSERT_VALUE;
    return false;
  }
  TriggerType::Value ttype = req->getTriggerType();
  TriggerActionTime::Value ttime = req->getTriggerActionTime();
  TriggerEvent::Value tevent = req->getTriggerEvent();

  DLList<TupTriggerData>* tlist = findTriggerList(table, ttype, ttime, tevent);
  ndbrequire(tlist != NULL);

  TriggerPtr tptr;
  if (!tlist->seize(tptr))
    return false;

  // Set trigger id
  tptr.p->triggerId = req->getTriggerId();

  //  ndbout_c("Create TupTrigger %u = %u %u %u %u", tptr.p->triggerId, table, ttype, ttime, tevent);

  // Set index id
  tptr.p->indexId = req->getIndexId();

  // Set trigger type etc
  tptr.p->triggerType = ttype;
  tptr.p->triggerActionTime = ttime;
  tptr.p->triggerEvent = tevent;

  tptr.p->sendBeforeValues = true;
  if ((tptr.p->triggerType == TriggerType::SUBSCRIPTION) &&
      ((tptr.p->triggerEvent == TriggerEvent::TE_UPDATE) ||
       (tptr.p->triggerEvent == TriggerEvent::TE_DELETE))) {
    jam();
    tptr.p->sendBeforeValues = false;
  }
  /*
  tptr.p->sendOnlyChangedAttributes = false;
  if (((tptr.p->triggerType == TriggerType::SUBSCRIPTION) ||
      (tptr.p->triggerType == TriggerType::SUBSCRIPTION_BEFORE)) &&
      (tptr.p->triggerEvent == TriggerEvent::TE_UPDATE)) {
    jam();
    tptr.p->sendOnlyChangedAttributes = true;
  }
  */
  tptr.p->sendOnlyChangedAttributes = !req->getReportAllMonitoredAttributes();
  // Set monitor all
  tptr.p->monitorAllAttributes = req->getMonitorAllAttributes();
  tptr.p->monitorReplicas = req->getMonitorReplicas();
  tptr.p->m_receiverBlock = refToBlock(req->getReceiverRef());

  tptr.p->attributeMask.clear();
  if (tptr.p->monitorAllAttributes) {
    jam();
    for(Uint32 i = 0; i < table->m_no_of_attributes; i++) {
      if (!primaryKey(table, i)) {
        jam();
        tptr.p->attributeMask.set(i);
      }
    }
  } else {
    // Set attribute mask
    jam();
    tptr.p->attributeMask = req->getAttributeMask();
  }
  return true;
}//Dbtup::createTrigger()
Example #13
0
/* ---------------------------------------------------------------- */
void Dbtup::lcpSaveDataPageLab(Signal* signal, Uint32 ciIndex) 
{
  CheckpointInfoPtr ciPtr;
  DiskBufferSegmentInfoPtr dbsiPtr;
  FragrecordPtr regFragPtr;
  LocalLogInfoPtr lliPtr;
  UndoPagePtr undoCopyPagePtr;
  PagePtr pagePtr;

  ciPtr.i = ciIndex;
  ptrCheckGuard(ciPtr, cnoOfLcpRec, checkpointInfo);
  if (ERROR_INSERTED(4000)){
    if (ciPtr.p->lcpTabPtr == c_errorInsert4000TableId) {
    // Delay writing of data pages during LCP
      ndbout << "Delay writing of data pages during LCP" << endl;
      signal->theData[0] = ZCONT_SAVE_DP;
      signal->theData[1] = ciIndex;
      sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 1000, 2);
      return;
    }//if
  }//if
  if (clblPageCounter == 0) {
    ljam();
    signal->theData[0] = ZCONT_SAVE_DP;
    signal->theData[1] = ciPtr.i;
    sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 100, 2);
    return;
  } else {
    ljam();
    clblPageCounter--;
  }//if

  regFragPtr.i = ciPtr.p->lcpFragmentP;
  ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
  dbsiPtr.i = ciPtr.p->lcpDataBufferSegmentP;
  ptrCheckGuard(dbsiPtr, cnoOfConcurrentWriteOp, diskBufferSegmentInfo);

  pagePtr.i = getRealpid(regFragPtr.p, regFragPtr.p->minPageNotWrittenInCheckpoint);
  ptrCheckGuard(pagePtr, cnoOfPage, page);
  ndbrequire(dbsiPtr.p->pdxNumDataPages < 16);
  undoCopyPagePtr.i = dbsiPtr.p->pdxDataPage[dbsiPtr.p->pdxNumDataPages];
  ptrCheckGuard(undoCopyPagePtr, cnoOfUndoPage, undoPage);
  MEMCOPY_NO_WORDS(&undoCopyPagePtr.p->undoPageWord[0],
                   &pagePtr.p->pageWord[0],
                   ZWORDS_ON_PAGE);
  regFragPtr.p->minPageNotWrittenInCheckpoint++;
  dbsiPtr.p->pdxNumDataPages++;
  if (regFragPtr.p->minPageNotWrittenInCheckpoint == regFragPtr.p->maxPageWrittenInCheckpoint) {
    /* ---------------------------------------------------------- */
    /* ALL PAGES ARE COPIED, TIME TO FINISH THE CHECKPOINT        */
    /* SAVE THE END POSITIONS OF THE LOG RECORDS SINCE ALL DATA   */
    /* PAGES ARE NOW SAFE ON DISK AND NO MORE LOGGING WILL APPEAR */
    /* ---------------------------------------------------------- */
    ljam();
    lliPtr.i = ciPtr.p->lcpLocalLogInfoP;
    ptrCheckGuard(lliPtr, cnoOfParallellUndoFiles, localLogInfo);
    regFragPtr.p->checkpointVersion = RNIL;	/* UNDO LOGGING IS SHUT OFF */
    lcpWriteListDataPageSegment(signal, dbsiPtr, ciPtr, false);
    dbsiPtr.p->pdxOperation = CHECKPOINT_DATA_WRITE_LAST;
  } else if (dbsiPtr.p->pdxNumDataPages == ZDB_SEGMENT_SIZE) {
    ljam();
    lcpWriteListDataPageSegment(signal, dbsiPtr, ciPtr, false);
    dbsiPtr.p->pdxOperation = CHECKPOINT_DATA_WRITE;
  } else {
    ljam();
    signal->theData[0] = ZCONT_SAVE_DP;
    signal->theData[1] = ciPtr.i;
    sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  }//if
}//Dbtup::lcpSaveDataPageLab()
void
Dbtux::execCREATE_TAB_REQ(Signal* signal)
{
  jamEntry();
  CreateTabReq copy = *(CreateTabReq*)signal->getDataPtr();
  CreateTabReq* req = &copy;

  IndexPtr indexPtr;
  indexPtr.i = RNIL;
  FragOpPtr fragOpPtr;
  fragOpPtr.i = RNIL;
  Uint32 errorCode = 0;

  do {
    // get the index record
    if (req->tableId >= c_indexPool.getSize()) {
      jam();
      errorCode = TuxFragRef::InvalidRequest;
      break;
    }
    c_indexPool.getPtr(indexPtr, req->tableId);
    if (indexPtr.p->m_state != Index::NotDefined)
    {
      jam();
      errorCode = TuxFragRef::InvalidRequest;
      indexPtr.i = RNIL;        // leave alone
      break;
    }

    // get new operation record
    c_fragOpPool.seize(fragOpPtr);
    ndbrequire(fragOpPtr.i != RNIL);
    new (fragOpPtr.p) FragOp();
    fragOpPtr.p->m_userPtr = req->senderData;
    fragOpPtr.p->m_userRef = req->senderRef;
    fragOpPtr.p->m_indexId = req->tableId;
    fragOpPtr.p->m_fragId = RNIL;
    fragOpPtr.p->m_fragNo = RNIL;
    fragOpPtr.p->m_numAttrsRecvd = 0;
#ifdef VM_TRACE
    if (debugFlags & DebugMeta) {
      debugOut << "Seize frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
    }
#endif
    // check if index has place for more fragments
    ndbrequire(indexPtr.p->m_state == Index::NotDefined &&
               DictTabInfo::isOrderedIndex(req->tableType) &&
               req->noOfAttributes > 0 &&
               req->noOfAttributes <= MaxIndexAttributes &&
               indexPtr.p->m_descPage == RNIL);

    indexPtr.p->m_state = Index::Defining;
    indexPtr.p->m_tableType = (DictTabInfo::TableType)req->tableType;
    indexPtr.p->m_tableId = req->primaryTableId;
    indexPtr.p->m_numAttrs = req->noOfAttributes;
    indexPtr.p->m_storeNullKey = true;  // not yet configurable
    // allocate attribute descriptors
    if (! allocDescEnt(indexPtr)) {
      jam();
      errorCode = TuxFragRef::NoFreeAttributes;
      break;
    }

    // error inserts
    if ((ERROR_INSERTED(12001) && fragOpPtr.p->m_fragNo == 0) ||
        (ERROR_INSERTED(12002) && fragOpPtr.p->m_fragNo == 1)) {
      jam();
      errorCode = (TuxFragRef::ErrorCode)1;
      CLEAR_ERROR_INSERT_VALUE;
      break;
    }
    // success
    CreateTabConf* conf = (CreateTabConf*)signal->getDataPtrSend();
    conf->senderRef = reference();
    conf->senderData = req->senderData;
    conf->tuxConnectPtr = fragOpPtr.i;
    sendSignal(req->senderRef, GSN_CREATE_TAB_CONF,
               signal, CreateTabConf::SignalLength, JBB);
    return;
  } while (0);
  // error

  CreateTabRef* const ref = (CreateTabRef*)signal->getDataPtrSend();
  ref->senderData = req->senderData;
  ref->errorCode = errorCode;
  sendSignal(req->senderRef, GSN_CREATE_TAB_REF,
             signal, CreateTabRef::SignalLength, JBB);

  if (indexPtr.i != RNIL) {
    jam();
    // let DICT drop the unfinished index
  }

  if (fragOpPtr.i != RNIL)
  {
    jam();
    c_fragOpPool.release(fragOpPtr);
  }
}
void
Dbtux::execTUXFRAGREQ(Signal* signal)
{
  jamEntry();

  if (signal->theData[0] == (Uint32)-1) {
    jam();
    abortAddFragOp(signal);
    return;
  }

  const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr();
  const TuxFragReq* const req = &reqCopy;
  IndexPtr indexPtr;
  indexPtr.i = RNIL;
  TuxFragRef::ErrorCode errorCode = TuxFragRef::NoError;
  do {
    // get the index record
    if (req->tableId >= c_indexPool.getSize()) {
      jam();
      errorCode = TuxFragRef::InvalidRequest;
      break;
    }
    c_indexPool.getPtr(indexPtr, req->tableId);
    if (false && indexPtr.p->m_state != Index::Defining) {
      jam();
      errorCode = TuxFragRef::InvalidRequest;
      indexPtr.i = RNIL;        // leave alone
      break;
    }

    // check if index has place for more fragments
    ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments);
    // seize new fragment record
    if (ERROR_INSERTED(12008))
    {
      CLEAR_ERROR_INSERT_VALUE;
      errorCode = TuxFragRef::InvalidRequest;
      break;
    }

    FragPtr fragPtr;
    c_fragPool.seize(fragPtr);
    if (fragPtr.i == RNIL) {
      jam();
      errorCode = TuxFragRef::NoFreeFragment;
      break;
    }
    new (fragPtr.p) Frag(c_scanOpPool);
    fragPtr.p->m_tableId = req->primaryTableId;
    fragPtr.p->m_indexId = req->tableId;
    fragPtr.p->m_fragId = req->fragId;
    fragPtr.p->m_tupIndexFragPtrI = req->tupIndexFragPtrI;
    fragPtr.p->m_tupTableFragPtrI = req->tupTableFragPtrI;
    fragPtr.p->m_accTableFragPtrI = req->accTableFragPtrI;
    // add the fragment to the index
    Uint32 fragNo = indexPtr.p->m_numFrags;
    indexPtr.p->m_fragId[indexPtr.p->m_numFrags] = req->fragId;
    indexPtr.p->m_fragPtrI[indexPtr.p->m_numFrags] = fragPtr.i;
    indexPtr.p->m_numFrags++;
#ifdef VM_TRACE
    if (debugFlags & DebugMeta) {
      debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl;
    }
#endif
    // error inserts
    if ((ERROR_INSERTED(12001) && fragNo == 0) ||
        (ERROR_INSERTED(12002) && fragNo == 1)) {
      jam();
      errorCode = (TuxFragRef::ErrorCode)1;
      CLEAR_ERROR_INSERT_VALUE;
      break;
    }

    // initialize tree header
    TreeHead& tree = fragPtr.p->m_tree;
    new (&tree) TreeHead();
    // make these configurable later
    tree.m_nodeSize = MAX_TTREE_NODE_SIZE;
    tree.m_prefSize = (indexPtr.p->m_prefBytes + 3) / 4;
    const unsigned maxSlack = MAX_TTREE_NODE_SLACK;
    // size of header and min prefix
    const unsigned fixedSize = NodeHeadSize + tree.m_prefSize;
    if (! (fixedSize <= tree.m_nodeSize)) {
      jam();
      errorCode = (TuxFragRef::ErrorCode)TuxAddAttrRef::InvalidNodeSize;
      break;
    }
    const unsigned slots = (tree.m_nodeSize - fixedSize) / TreeEntSize;
    tree.m_maxOccup = slots;
    // min occupancy of interior node must be at least 2
    if (! (2 + maxSlack <= tree.m_maxOccup)) {
      jam();
      errorCode = (TuxFragRef::ErrorCode)TuxAddAttrRef::InvalidNodeSize;
      break;
    }
    tree.m_minOccup = tree.m_maxOccup - maxSlack;
    // root node does not exist (also set by ctor)
    tree.m_root = NullTupLoc;
#ifdef VM_TRACE
    if (debugFlags & DebugMeta) {
      if (fragNo == 0) {
        debugOut << "Index id=" << indexPtr.i;
        debugOut << " nodeSize=" << tree.m_nodeSize;
        debugOut << " headSize=" << NodeHeadSize;
        debugOut << " prefSize=" << tree.m_prefSize;
        debugOut << " entrySize=" << TreeEntSize;
        debugOut << " minOccup=" << tree.m_minOccup;
        debugOut << " maxOccup=" << tree.m_maxOccup;
        debugOut << endl;
      }
    }
#endif

    // success
    TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend();
    conf->userPtr = req->userPtr;
    conf->tuxConnectPtr = RNIL;
    conf->fragPtr = fragPtr.i;
    conf->fragId = fragPtr.p->m_fragId;
    sendSignal(req->userRef, GSN_TUXFRAGCONF,
        signal, TuxFragConf::SignalLength, JBB);
    return;
  } while (0);

  // error
  TuxFragRef* const ref = (TuxFragRef*)signal->getDataPtrSend();
  ref->userPtr = req->userPtr;
  ref->errorCode = errorCode;
  sendSignal(req->userRef, GSN_TUXFRAGREF,
      signal, TuxFragRef::SignalLength, JBB);

  if (indexPtr.i != RNIL) {
    jam();
    // let DICT drop the unfinished index
  }
}
void
Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
{
  jamEntry();
  const TuxAddAttrReq reqCopy = *(const TuxAddAttrReq*)signal->getDataPtr();
  const TuxAddAttrReq* const req = &reqCopy;
  // get the records
  FragOpPtr fragOpPtr;
  IndexPtr indexPtr;
  c_fragOpPool.getPtr(fragOpPtr, req->tuxConnectPtr);
  c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId);
  TuxAddAttrRef::ErrorCode errorCode = TuxAddAttrRef::NoError;
  do {
    // expected attribute id
    const unsigned attrId = fragOpPtr.p->m_numAttrsRecvd++;
    ndbrequire(
        indexPtr.p->m_state == Index::Defining &&
        attrId < indexPtr.p->m_numAttrs &&
        attrId == req->attrId);
    const Uint32 ad = req->attrDescriptor;
    const Uint32 typeId = AttributeDescriptor::getType(ad);
    const Uint32 sizeInBytes = AttributeDescriptor::getSizeInBytes(ad);
    const Uint32 nullable = AttributeDescriptor::getNullable(ad);
    const Uint32 csNumber = req->extTypeInfo >> 16;
    const Uint32 primaryAttrId = req->primaryAttrId;

    DescHead& descHead = getDescHead(*indexPtr.p);
    // add type to spec
    KeySpec& keySpec = indexPtr.p->m_keySpec;
    KeyType keyType(typeId, sizeInBytes, nullable, csNumber);
    if (keySpec.add(keyType) == -1) {
      jam();
      errorCode = TuxAddAttrRef::InvalidAttributeType;
      break;
    }
    // add primary attr to read keys array
    AttributeHeader* keyAttrs = getKeyAttrs(descHead);
    AttributeHeader& keyAttr = keyAttrs[attrId];
    new (&keyAttr) AttributeHeader(primaryAttrId, sizeInBytes);
#ifdef VM_TRACE
    if (debugFlags & DebugMeta) {
      debugOut << "attr " << attrId << " " << keyType << endl;
    }
#endif
    if (csNumber != 0) {
      unsigned err;
      CHARSET_INFO *cs = all_charsets[csNumber];
      ndbrequire(cs != 0);
      if ((err = NdbSqlUtil::check_column_for_ordered_index(typeId, cs))) {
        jam();
        errorCode = (TuxAddAttrRef::ErrorCode) err;
        break;
      }
    }
    const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd);
    if ((ERROR_INSERTED(12003) && attrId == 0) ||
        (ERROR_INSERTED(12004) && lastAttr))
    {
      errorCode = (TuxAddAttrRef::ErrorCode)1;
      CLEAR_ERROR_INSERT_VALUE;
      break;
    }
    if (lastAttr) {
      // compute min prefix
      const KeySpec& keySpec = indexPtr.p->m_keySpec;
      unsigned attrs = 0;
      unsigned bytes = keySpec.get_nullmask_len(false);
      unsigned maxAttrs = indexPtr.p->m_numAttrs;
#ifdef VM_TRACE
#ifdef NDB_USE_GET_ENV
      {
        const char* p = NdbEnv_GetEnv("MAX_TTREE_PREF_ATTRS", (char*)0, 0);
        if (p != 0 && p[0] != 0 && maxAttrs > (unsigned)atoi(p))
          maxAttrs = atoi(p);
      }
#endif
#endif
      while (attrs < maxAttrs) {
        const KeyType& keyType = keySpec.get_type(attrs);
        const unsigned newbytes = bytes + keyType.get_byte_size();
        if (newbytes > (MAX_TTREE_PREF_SIZE << 2))
          break;
        attrs++;
        bytes = newbytes;
      }
      if (attrs == 0)
        bytes = 0;
      indexPtr.p->m_prefAttrs = attrs;
      indexPtr.p->m_prefBytes = bytes;
      // fragment is defined
#ifdef VM_TRACE
      if (debugFlags & DebugMeta) {
        debugOut << "Release frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
      }
#endif
      c_fragOpPool.release(fragOpPtr);
    }
    // success
    TuxAddAttrConf* conf = (TuxAddAttrConf*)signal->getDataPtrSend();
    conf->userPtr = fragOpPtr.p->m_userPtr;
    conf->lastAttr = lastAttr;
    sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRCONF,
        signal, TuxAddAttrConf::SignalLength, JBB);
    return;
  } while (0);
  // error
  TuxAddAttrRef* ref = (TuxAddAttrRef*)signal->getDataPtrSend();
  ref->userPtr = fragOpPtr.p->m_userPtr;
  ref->errorCode = errorCode;
  sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRREF,
      signal, TuxAddAttrRef::SignalLength, JBB);
#ifdef VM_TRACE
    if (debugFlags & DebugMeta) {
      debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
    }
#endif
  // let DICT drop the unfinished index
}