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; }
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()
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); }
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(®AttrPtr.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()
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); } }
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); }
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; }
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()
/* ---------------------------------------------------------------- */ 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 = © 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 }