/* * 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 Dbtux::execTUX_MAINT_REQ(Signal* signal) { jamEntry(); TuxMaintReq* const sig = (TuxMaintReq*)signal->getDataPtrSend(); // ignore requests from redo log IndexPtr indexPtr; c_indexPool.getPtr(indexPtr, sig->indexId); if (unlikely(! (indexPtr.p->m_state == Index::Online || indexPtr.p->m_state == Index::Building))) { jam(); #ifdef VM_TRACE if (debugFlags & DebugMaint) { TupLoc tupLoc(sig->pageId, sig->pageIndex); debugOut << "opInfo=" << hex << sig->opInfo; debugOut << " tableId=" << dec << sig->tableId; debugOut << " indexId=" << dec << sig->indexId; debugOut << " fragId=" << dec << sig->fragId; debugOut << " tupLoc=" << tupLoc; debugOut << " tupVersion=" << dec << sig->tupVersion; debugOut << " -- ignored at ISP=" << dec << c_internalStartPhase; debugOut << " TOS=" << dec << c_typeOfStart; debugOut << endl; } #endif sig->errorCode = 0; return; } TuxMaintReq reqCopy = *sig; TuxMaintReq* const req = &reqCopy; const Uint32 opCode = req->opInfo & 0xFF; // get the index ndbrequire(indexPtr.p->m_tableId == req->tableId); // get base fragment id and extra bits const Uint32 fragId = req->fragId; // get the fragment FragPtr fragPtr; findFrag(jamBuffer(), *indexPtr.p, fragId, fragPtr); ndbrequire(fragPtr.i != RNIL); Frag& frag = *fragPtr.p; // set up search entry TreeEnt ent; ent.m_tupLoc = TupLoc(req->pageId, req->pageIndex); ent.m_tupVersion = req->tupVersion; // set up and read search key KeyData searchKey(indexPtr.p->m_keySpec, false, 0); searchKey.set_buf(c_ctx.c_searchKey, MaxAttrDataSize << 2); readKeyAttrs(c_ctx, frag, ent, searchKey, indexPtr.p->m_numAttrs); if (unlikely(! indexPtr.p->m_storeNullKey) && searchKey.get_null_cnt() == indexPtr.p->m_numAttrs) { jam(); return; } #ifdef VM_TRACE if (debugFlags & DebugMaint) { const Uint32 opFlag = req->opInfo >> 8; debugOut << "opCode=" << dec << opCode; debugOut << " opFlag=" << dec << opFlag; debugOut << " tableId=" << dec << req->tableId; debugOut << " indexId=" << dec << req->indexId; debugOut << " fragId=" << dec << req->fragId; debugOut << " entry=" << ent; debugOut << endl; } #endif // do the operation req->errorCode = 0; TreePos treePos; bool ok; switch (opCode) { case TuxMaintReq::OpAdd: jam(); ok = searchToAdd(c_ctx, frag, searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { debugOut << treePos << (! ok ? " - error" : "") << endl; } #endif if (! ok) { jam(); // there is no "Building" state so this will have to do if (indexPtr.p->m_state == Index::Online) { jam(); req->errorCode = TuxMaintReq::SearchError; } break; } /* * At most one new node is inserted in the operation. Pre-allocate * it so that the operation cannot fail. */ if (frag.m_freeLoc == NullTupLoc) { jam(); NodeHandle node(frag); req->errorCode = allocNode(c_ctx, node); if (req->errorCode != 0) { jam(); break; } frag.m_freeLoc = node.m_loc; ndbrequire(frag.m_freeLoc != NullTupLoc); } treeAdd(c_ctx, frag, treePos, ent); frag.m_entryCount++; frag.m_entryBytes += searchKey.get_data_len(); frag.m_entryOps++; break; case TuxMaintReq::OpRemove: jam(); ok = searchToRemove(c_ctx, frag, searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { debugOut << treePos << (! ok ? " - error" : "") << endl; } #endif if (! ok) { jam(); // there is no "Building" state so this will have to do if (indexPtr.p->m_state == Index::Online) { jam(); req->errorCode = TuxMaintReq::SearchError; } break; } treeRemove(frag, treePos); ndbrequire(frag.m_entryCount != 0); frag.m_entryCount--; frag.m_entryBytes -= searchKey.get_data_len(); frag.m_entryOps++; break; default: ndbrequire(false); break; } #ifdef VM_TRACE if (debugFlags & DebugTree) { printTree(signal, frag, debugOut); } #endif // copy back *sig = *req; //ndbrequire(c_keyAttrs[0] == c_keyAttrs[1]); //ndbrequire(c_sqlCmp[0] == c_sqlCmp[1]); //ndbrequire(c_searchKey[0] == c_searchKey[1]); //ndbrequire(c_entryKey[0] == c_entryKey[1]); //ndbrequire(c_dataBuffer[0] == c_dataBuffer[1]); }
void Dbtux::execTUX_MAINT_REQ(Signal* signal) { jamEntry(); TuxMaintReq* const sig = (TuxMaintReq*)signal->getDataPtrSend(); // ignore requests from redo log if (c_internalStartPhase < 6 && c_typeOfStart != NodeState::ST_NODE_RESTART && c_typeOfStart != NodeState::ST_INITIAL_NODE_RESTART) { jam(); #ifdef VM_TRACE if (debugFlags & DebugMaint) { TupLoc tupLoc(sig->pageId, sig->pageOffset); debugOut << "opInfo=" << hex << sig->opInfo; debugOut << " tableId=" << dec << sig->tableId; debugOut << " indexId=" << dec << sig->indexId; debugOut << " fragId=" << dec << sig->fragId; debugOut << " tupLoc=" << tupLoc; debugOut << " tupVersion=" << dec << sig->tupVersion; debugOut << " -- ignored at ISP=" << dec << c_internalStartPhase; debugOut << " TOS=" << dec << c_typeOfStart; debugOut << endl; } #endif sig->errorCode = 0; return; } TuxMaintReq reqCopy = *sig; TuxMaintReq* const req = &reqCopy; const Uint32 opCode = req->opInfo & 0xFF; const Uint32 opFlag = req->opInfo >> 8; // get the index IndexPtr indexPtr; c_indexPool.getPtr(indexPtr, req->indexId); ndbrequire(indexPtr.p->m_tableId == req->tableId); // get base fragment id and extra bits const Uint32 fragId = req->fragId & ~1; const Uint32 fragBit = req->fragId & 1; // get the fragment FragPtr fragPtr; fragPtr.i = RNIL; for (unsigned i = 0; i < indexPtr.p->m_numFrags; i++) { jam(); if (indexPtr.p->m_fragId[i] == fragId) { jam(); c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]); break; } } ndbrequire(fragPtr.i != RNIL); Frag& frag = *fragPtr.p; // set up index keys for this operation setKeyAttrs(frag); // set up search entry TreeEnt ent; ent.m_tupLoc = TupLoc(req->pageId, req->pageOffset); ent.m_tupVersion = req->tupVersion; ent.m_fragBit = fragBit; // read search key readKeyAttrs(frag, ent, 0, c_searchKey); if (! frag.m_storeNullKey) { // check if all keys are null const unsigned numAttrs = frag.m_numAttrs; bool allNull = true; for (unsigned i = 0; i < numAttrs; i++) { if (c_searchKey[i] != 0) { jam(); allNull = false; break; } } if (allNull) { jam(); req->errorCode = 0; *sig = *req; return; } } #ifdef VM_TRACE if (debugFlags & DebugMaint) { debugOut << "opCode=" << dec << opCode; debugOut << " opFlag=" << dec << opFlag; debugOut << " tableId=" << dec << req->tableId; debugOut << " indexId=" << dec << req->indexId; debugOut << " fragId=" << dec << req->fragId; debugOut << " entry=" << ent; debugOut << endl; } #endif // do the operation req->errorCode = 0; TreePos treePos; bool ok; switch (opCode) { case TuxMaintReq::OpAdd: jam(); ok = searchToAdd(frag, c_searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { debugOut << treePos << (! ok ? " - error" : "") << endl; } #endif if (! ok) { jam(); // there is no "Building" state so this will have to do if (indexPtr.p->m_state == Index::Online) { jam(); req->errorCode = TuxMaintReq::SearchError; } break; } /* * At most one new node is inserted in the operation. Pre-allocate * it so that the operation cannot fail. */ if (frag.m_freeLoc == NullTupLoc) { jam(); NodeHandle node(frag); req->errorCode = allocNode(signal, node); if (req->errorCode != 0) { jam(); break; } // link to freelist node.setLink(0, frag.m_freeLoc); frag.m_freeLoc = node.m_loc; ndbrequire(frag.m_freeLoc != NullTupLoc); } treeAdd(frag, treePos, ent); break; case TuxMaintReq::OpRemove: jam(); ok = searchToRemove(frag, c_searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { debugOut << treePos << (! ok ? " - error" : "") << endl; } #endif if (! ok) { jam(); // there is no "Building" state so this will have to do if (indexPtr.p->m_state == Index::Online) { jam(); req->errorCode = TuxMaintReq::SearchError; } break; } treeRemove(frag, treePos); break; default: ndbrequire(false); break; } #ifdef VM_TRACE if (debugFlags & DebugTree) { printTree(signal, frag, debugOut); } #endif // copy back *sig = *req; }