Пример #1
0
/*
 * 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;
}
Пример #2
0
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]);
}
Пример #3
0
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;
}