Пример #1
0
int runScanRefreshNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
  int result = NDBT_OK;
  int loops = ctx->getNumLoops();
  int records = ctx->getNumRecords();
  int stepNo = step->getStepNo();
  int maxSleep = (int)(TIMEOUT * 0.3);
  ndbout << "TransactionInactiveTimeout="<< TIMEOUT
	 << ", maxSleep="<<maxSleep<<endl;

  HugoOperations hugoOps(*ctx->getTab());
  Ndb* pNdb = GETNDB(step);

  for (int l = 1; l < loops && result == NDBT_OK; l++){

    do{
      // Start an insert trans
      CHECK(hugoOps.startTransaction(pNdb) == 0);
      int recordNo = records + (stepNo*loops) + l;
      CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0);
      CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
      
      for (int i = 0; i < 3; i++)
      {
        NdbTransaction* pTrans = hugoOps.getTransaction();

        Vector<NdbScanOperation*> ops;
        for (int j = 0; j <= i; j++)
        {
          // Perform buddy scan reads
          NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
          CHECK(pOp != 0);
          CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
          ops.push_back(pOp);
        }
        CHECK(pTrans->execute(NoCommit) == 0);

        for (unsigned i = 0; i<TIMEOUT; i += 1000)
        {
          pTrans->refresh();
          NdbSleep_MilliSleep(1000);
        }

        int res;
        for (unsigned j = 0; j < ops.size(); j++)
        {
          while((res = ops[j]->nextResult()) == 0);
          CHECK(res != -1);
        }
      }

      // Expect that transaction has NOT timed-out
      CHECK(hugoOps.execute_Commit(pNdb) == 0); 
    
    } while(false);

    hugoOps.closeTransaction(pNdb);
  }

  return result;
}
Пример #2
0
void DatasetTableTailer::handleUpdate(NdbRecAttr* value[]) {
    int datasetPK = value[DS_ID_PK]->int32_value();
    int datasetId = -1;
    int projectId = -1;
    if(value[DS_INODE_ID]->isNULL() == -1){
        const NdbDictionary::Dictionary* database = getDatabase(mNdbConnection);
        const NdbDictionary::Table* table = getTable(database, TABLE.mTableName);
        NdbTransaction* transaction = startNdbTransaction(mNdbConnection);
        NdbOperation* op = getNdbOperation(transaction, table);
        
        op->readTuple(NdbOperation::LM_CommittedRead);
        
        op->equal(_dataset_cols[8].c_str(), datasetPK);
        
        NdbRecAttr* datasetIdCol = getNdbOperationValue(op, _dataset_cols[DS_INODE_ID]);
        NdbRecAttr* projectIdCol = getNdbOperationValue(op, _dataset_cols[DS_PROJ_ID]);
        
        executeTransaction(transaction, NdbTransaction::Commit);        
        datasetId = datasetIdCol->int32_value();
        projectId = projectIdCol->int32_value();
        
        transaction->close();
    }
    
    if(datasetId == -1 || projectId == -1){
        LOG_ERROR("Couldn't resolve projectId[" << projectId << "] or datasetId[" << datasetId << "]");
        return;
    }
    
     
    string data = createJSONUpSert(projectId, value);
    if (mElasticSearch->addDataset(projectId, datasetId, data)) {
        LOG_INFO("Update Dataset[" << datasetId << "]: Succeeded");
    }
}
Пример #3
0
//
//  Execute function which re-executes (tries 10 times) the transaction 
//  if there are temporary errors (e.g. the NDB Cluster is overloaded).
//  @return -1 failure, 1 success
//
int executeInsertTransaction(int transactionId, Ndb* myNdb,
			     const NdbDictionary::Table *myTable) {
  int result = 0;                       // No result yet
  int noOfRetriesLeft = 10;
  NdbTransaction	 *myTransaction;         // For other transactions
  NdbError ndberror;
  
  while (noOfRetriesLeft > 0 && !result) {
    
    /*********************************
     * Start and execute transaction *
     *********************************/
    myTransaction = myNdb->startTransaction();
    if (myTransaction == NULL) {
      APIERROR(myNdb->getNdbError());
      ndberror = myNdb->getNdbError();
      result = -1;  // Failure
    } else if (insert(transactionId, myTransaction, myTable) || 
	       insert(10000+transactionId, myTransaction, myTable) ||
	       myTransaction->execute(NdbTransaction::Commit)) {
      TRANSERROR(myTransaction);
      ndberror = myTransaction->getNdbError();
      result = -1;  // Failure
    } else {
      result = 1;   // Success
    }

    /**********************************
     * If failure, then analyze error *
     **********************************/
    if (result == -1) {                 
      switch (ndberror.status) {
      case NdbError::Success:
	break;
      case NdbError::TemporaryError:
	std::cout << "Retrying transaction..." << std::endl;
	sleep(TIME_TO_SLEEP_BETWEEN_TRANSACTION_RETRIES);
	--noOfRetriesLeft;
	result = 0;   // No completed transaction yet
	break;
	
      case NdbError::UnknownResult:
      case NdbError::PermanentError:
	std::cout << "No retry of transaction..." << std::endl;
	result = -1;  // Permanent failure
	break;
      }
    }

    /*********************
     * Close transaction *
     *********************/
    if (myTransaction != NULL) {
      myNdb->closeTransaction(myTransaction);
    }
  }

  if (result != 1) exit(-1);
  return result;
}
/* Producer thread */
int runV2MultiWait_Producer(NDBT_Context* ctx, NDBT_Step* step,
                           int thd_id, int nthreads)
{
  int records = ctx->getNumRecords();
  HugoOperations hugoOps(*ctx->getTab());

  /* For three threads (2 producers + 1 consumer) we loop 0-7.
     producer 0 is slow if (loop & 1)  
     producer 1 is slow if (loop & 2)
     consumer is slow if (loop & 4)
  */
  for (int loop = 0; loop < V2_NLOOPS; loop++) 
  {
    ctx->getPropertyWait("LOOP", loop+1);
    bool slow = loop & (thd_id+1);
    for (int j=0; j < records; j++)
    {
      if(j % nthreads == thd_id) 
      {
        Ndb* ndb = global_ndb_pool->getNdb();
        NdbTransaction* trans = ndb->startTransaction();
        check(trans != NULL, (*ndb));
        ndb->setCustomData(trans);

        NdbOperation* readOp = trans->getNdbOperation(ctx->getTab());
        check(readOp != NULL, (*trans));
        check(readOp->readTuple() == 0, (*readOp));
        check(hugoOps.equalForRow(readOp, j) == 0, hugoOps);

        /* Read all other cols */
        for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++)
        {
          check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL,
                (*readOp));
        }

        trans->executeAsynchPrepare(NdbTransaction::Commit,
                                    NULL,
                                    NULL,
                                    NdbOperation::AbortOnError);
        ndb->sendPreparedTransactions();
        global_poll_group->push(ndb);
        if(slow) 
        {
          int tm = myRandom48(3) * myRandom48(3);
          if(tm) NdbSleep_MilliSleep(tm);
        }
      }
    }
  } 
  return NDBT_OK;
}
Пример #5
0
void DatasetTableTailer::handleAdd(int datasetId, int projectId, NdbRecAttr* value[]) {
    mPDICache->addDatasetToProject(datasetId, projectId);
    
    string data = createJSONUpSert(projectId, value);
    if (mElasticSearch->addDataset(projectId, datasetId, data)) {
        LOG_INFO("Add Dataset[" << datasetId << "]: Succeeded");
    }

    const NdbDictionary::Dictionary* database = getDatabase(mNdbConnection);
    NdbTransaction* transaction = startNdbTransaction(mNdbConnection);
    Recovery::checkpointDataset(database, transaction, datasetId);
    transaction->close();
}
Пример #6
0
int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
  int result = NDBT_OK;
  int loops = ctx->getNumLoops();
  int records = ctx->getNumRecords();
  int stepNo = step->getStepNo();
  int maxSleep = (int)(TIMEOUT * 0.3);
  ndbout << "TransactionInactiveTimeout="<< TIMEOUT
	 << ", maxSleep="<<maxSleep<<endl;

  HugoOperations hugoOps(*ctx->getTab());
  Ndb* pNdb = GETNDB(step);

  for (int l = 1; l < loops && result == NDBT_OK; l++){

    do{
      // Start an insert trans
      CHECK(hugoOps.startTransaction(pNdb) == 0);
      int recordNo = records + (stepNo*loops) + l;
      CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0);
      CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
      
      int remain = maxSleep;
      for (int i = 0; i < 3; i++)
      {
        NdbTransaction* pTrans = hugoOps.getTransaction();

        // Perform buddy scan reads
        NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
        CHECK(pOp != 0);
        CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
        CHECK(pTrans->execute(NoCommit) == 0);
        while(pOp->nextResult() == 0);
	
        int sleep = myRandom48(remain);
        remain = remain - sleep + 1;
        ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
        NdbSleep_MilliSleep(sleep);
      }

      // Expect that transaction has NOT timed-out
      CHECK(hugoOps.execute_Commit(pNdb) == 0); 
    
    } while(false);

    hugoOps.closeTransaction(pNdb);
  }

  return result;
}
Пример #7
0
int
runInterpretedUKLookup(NDBT_Context* ctx, NDBT_Step* step)
{
  const NdbDictionary::Table * pTab = ctx->getTab();
  Ndb* pNdb = GETNDB(step);
  NdbDictionary::Dictionary * dict = pNdb->getDictionary();

  const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
  CHK_RET_FAILED(pIdx != 0);

  const NdbRecord * pRowRecord = pTab->getDefaultRecord();
  CHK_RET_FAILED(pRowRecord != 0);
  const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
  CHK_RET_FAILED(pIdxRecord != 0);

  const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
  Uint8 * pRow = new Uint8[len];
  bzero(pRow, len);

  HugoCalculator calc(* pTab);
  calc.equalForRow(pRow, pRowRecord, 0);

  NdbTransaction* pTrans = pNdb->startTransaction();
  CHK_RET_FAILED(pTrans != 0);

  NdbInterpretedCode code;
  code.interpret_exit_ok();
  code.finalise();

  NdbOperation::OperationOptions opts;
  bzero(&opts, sizeof(opts));
  opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
  opts.interpretedCode = &code;

  const NdbOperation * pOp = pTrans->readTuple(pIdxRecord, (char*)pRow,
                                               pRowRecord, (char*)pRow,
                                               NdbOperation::LM_Read,
                                               0,
                                               &opts,
                                               sizeof(opts));
  CHK_RET_FAILED(pOp);
  int res = pTrans->execute(Commit, AbortOnError);

  CHK_RET_FAILED(res == 0);

  delete [] pRow;

  return NDBT_OK;
}
Пример #8
0
/***************************************************************************
void abortTransactionsAfterNodeFailure();

Remark:   Abort all transactions in theSentTransactionsArray after connection 
          to one node has failed
****************************************************************************/
void	
Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
{  
  Uint32 tNoSentTransactions = theNoOfSentTransactions;
  for (int i = tNoSentTransactions - 1; i >= 0; i--) {
    NdbTransaction* localCon = theSentTransactionsArray[i];
    if (localCon->getConnectedNodeId() == aNodeId) {
      const NdbTransaction::SendStatusType sendStatus = localCon->theSendStatus;
      if (sendStatus == NdbTransaction::sendTC_OP || 
	  sendStatus == NdbTransaction::sendTC_COMMIT) {
        /*
        A transaction was interrupted in the prepare phase by a node
        failure. Since the transaction was not found in the phase
        after the node failure it cannot have been committed and
        we report a normal node failure abort.
        */
	localCon->setOperationErrorCodeAbort(4010);
        localCon->theCompletionStatus = NdbTransaction::CompletedFailure;
      } else if (sendStatus == NdbTransaction::sendTC_ROLLBACK) {
        /*
        We aimed for abort and abort we got even if it was by a node
        failure. We will thus report it as a success.
        */
        localCon->theCompletionStatus = NdbTransaction::CompletedSuccess;
      } else {
#ifdef VM_TRACE
        printState("abortTransactionsAfterNodeFailure %lx", (long)this);
        abort();
#endif
      }
      /*
      All transactions arriving here have no connection to the kernel
      intact since the node was failing and they were aborted. Thus we
      set commit state to Aborted and set state to release on close.
      */
      localCon->theReturnStatus = NdbTransaction::ReturnFailure;
      localCon->theCommitStatus = NdbTransaction::Aborted;
      localCon->theReleaseOnClose = true;
      completedTransaction(localCon);
    }
    else if(localCon->report_node_failure(aNodeId))
    {
      completedTransaction(localCon);
    }
  }//for
  return;
}//Ndb::abortTransactionsAfterNodeFailure()
Пример #9
0
static void run_master_update(struct Xxx &xxx, struct XxxR &xxxr)
{
  Ndb *ndb = xxx.ndb;
  const NdbDictionary::Table *myTable = xxx.table;
  int retry_sleep= 10; /* 10 milliseconds */
  int retries= 100;
  while (1)
  {
    Uint32 val;
    NdbTransaction *trans = ndb->startTransaction();
    if (trans == NULL)
      goto err;
    {
      NdbOperation *op = trans->getNdbOperation(myTable);
      if (op == NULL)
        APIERROR(trans->getNdbError());
      op->readTupleExclusive();
      op->equal(xxx.pk_col, xxxr.pk_val);
      op->getValue(xxx.col, (char *)&val);
    }
    if (trans->execute(NdbTransaction::NoCommit))
      goto err;
    //fprintf(stderr, "read %u\n", val);
    xxxr.val = val + 1;
    {
      NdbOperation *op = trans->getNdbOperation(myTable);
      if (op == NULL)
        APIERROR(trans->getNdbError());
      op->updateTuple();
      op->equal(xxx.pk_col, xxxr.pk_val);
      op->setValue(xxx.col, xxxr.val);
    }
    if (trans->execute(NdbTransaction::Commit))
      goto err;
    ndb->closeTransaction(trans);
    //fprintf(stderr, "updated to %u\n", xxxr.val);
    break;
err:
    const NdbError this_error= trans ?
      trans->getNdbError() : ndb->getNdbError();
    if (this_error.status == NdbError::TemporaryError)
    {
      if (retries--)
      {
        if (trans)
          ndb->closeTransaction(trans);
        NdbSleep_MilliSleep(retry_sleep);
        continue; // retry
      }
    }
    if (trans)
      ndb->closeTransaction(trans);
    APIERROR(this_error);
  }
  /* update done start timer */
  gettimeofday(&xxxr.start_time, 0);
}
Пример #10
0
static int
checkorphan(const Blob&b, int& res)
{
  int ret = 0;

  NdbTransaction* tx = 0;
  NdbOperation* op = 0;

  do
  {
    tx = g_ndb->startTransaction();
    CHK2(tx != 0, g_ndb->getNdbError());

    op = tx->getNdbOperation(g_tab);
    CHK2(op != 0, tx->getNdbError());

    const NdbOperation::LockMode lm = NdbOperation::LM_Read;
    CHK2(op->readTuple(lm) == 0, op->getNdbError());

    for (int i = 0; i < g_pkcount; i++)
    {
      Val& v = g_vallist[i];
      assert(v.ra != 0);
      assert(v.ra->isNULL() == 0);
      const char* data = v.ra->aRef();
      CHK2(op->equal(v.colname, data) == 0, op->getNdbError());
    }
    CHK1(ret == 0);

    // read something to be safe
    NdbRecAttr* ra0 = op->getValue(g_vallist[0].colname);
    assert(ra0 != 0);

    // not sure about the rules
    assert(tx->getNdbError().code == 0);
    tx->execute(Commit);
    if (tx->getNdbError().code == 626)
    {
      g_info << "parent not found" << endl;
      res = 1; // not found
    }
    else
    {
      CHK2(tx->getNdbError().code == 0, tx->getNdbError());
      res = 0; // found
    }
  }
  while (0);

  if (tx != 0)
    g_ndb->closeTransaction(tx);
  return ret;
}
Пример #11
0
static int
deleteorphan(const Blob& b)
{
  int ret = 0;

  NdbTransaction* tx = 0;

  do
  {
    tx = g_ndb->startTransaction();
    CHK2(tx != 0, g_ndb->getNdbError());

    CHK2(g_scanop->deleteCurrentTuple(tx) == 0, g_scanop->getNdbError());
    CHK2(tx->execute(Commit) == 0, tx->getNdbError());
  }
  while (0);

  if (tx != 0)
    g_ndb->closeTransaction(tx);
  return ret;
}
/* Consumer */
int runV2MultiWait_WaitPop_Thread(NDBT_Context* ctx, NDBT_Step* step)
{
  static int iter = 0;  // keeps incrementing when test case is repeated
  int records = ctx->getNumRecords();
  const char * d[5] = { " fast"," slow"," slow",""," slow" };
  const int timeout[3] = { 100, 1, 0 };
  const int pct_wait[9] = { 0,0,0,50,50,50,100,100,100 };
  for (int loop = 0; loop < V2_NLOOPS; loop++, iter++) 
  {
    ctx->incProperty("LOOP");
    ndbout << "V2 test: " << d[loop&1] << d[loop&2] << d[loop&4];
    ndbout << " " << timeout[iter%3] << "/" << pct_wait[iter%9] << endl;
    bool slow = loop & 4; 
    int nrec = 0;
    while(nrec < records) 
    {
      /* Occasionally check with no timeout */
      global_poll_group->wait(timeout[iter%3], pct_wait[iter%9]);
      Ndb * ndb = global_poll_group->pop();
      while(ndb) 
      {
        check(ndb->pollNdb(0, 1) != 0, (*ndb));
        nrec++;
        NdbTransaction *tx = (NdbTransaction *) ndb->getCustomData();
        tx->close();
        global_ndb_pool->recycleNdb(ndb);
        ndb = global_poll_group->pop();
      }
      if(slow) 
      {
         NdbSleep_MilliSleep(myRandom48(6));
      }  
    }
  }
  ctx->stopTest();
  global_ndb_pool->closeAll();
  return NDBT_OK;
}
Пример #13
0
int runBuddyTransTimeout(NDBT_Context* ctx, NDBT_Step* step){
  int result = NDBT_OK;
  int loops = ctx->getNumLoops();
  int records = ctx->getNumRecords();
  int stepNo = step->getStepNo();
  ndbout << "TransactionInactiveTimeout="<< TIMEOUT <<endl;

  HugoOperations hugoOps(*ctx->getTab());
  Ndb* pNdb = GETNDB(step);

  for (int l = 1; l < loops && result == NDBT_OK; l++){

    NdbTransaction* pTrans = 0;
    do{
      pTrans = pNdb->startTransaction();
      NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
      CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
      CHECK(pTrans->execute(NoCommit) == 0);
      
      int sleep = 2 * TIMEOUT;
      ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
      NdbSleep_MilliSleep(sleep);
    
      int res = 0;
      while((res = pOp->nextResult()) == 0);
      ndbout_c("res: %d", res);
      CHECK(res == -1);
      
    } while(false);
    
    if (pTrans)
    {
      pTrans->close();
    }
  }
  
  return result;
}
Пример #14
0
void
Ndb::checkFailedNode()
{
  DBUG_ENTER("Ndb::checkFailedNode");
  Uint32 *the_release_ind= theImpl->the_release_ind;
  if (the_release_ind[0] == 0)
  {
    DBUG_VOID_RETURN;
  }
  Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes;
  Uint8 *theDBnodes= theImpl->theDBnodes;

  DBUG_PRINT("enter", ("theNoOfDBnodes: %d", tNoOfDbNodes));

  DBUG_ASSERT(tNoOfDbNodes < MAX_NDB_NODES);
  for (Uint32 i = 0; i < tNoOfDbNodes; i++){
    const NodeId node_id = theDBnodes[i];
    DBUG_PRINT("info", ("i: %d, node_id: %d", i, node_id));
    
    DBUG_ASSERT(node_id < MAX_NDB_NODES);    
    if (the_release_ind[node_id] == 1){

      /**
       * Release all connections in idle list (for node)
       */
      NdbTransaction * tNdbCon = theConnectionArray[node_id];
      theConnectionArray[node_id] = NULL;
      while (tNdbCon != NULL) {
        NdbTransaction* tempNdbCon = tNdbCon;
        tNdbCon = tNdbCon->next();
        releaseNdbCon(tempNdbCon);
      }
      the_release_ind[node_id] = 0;
    }
  }
  DBUG_VOID_RETURN;
}
Пример #15
0
void TableTailer::recover(int recoverFromId) {
    const NdbDictionary::Dictionary* database = getDatabase(mNdbConnection);
    const NdbDictionary::Index* index = getIndex(database, mTable.mTableName, mTable.mRecoveryIndex);
    
    NdbTransaction* transaction = startNdbTransaction(mNdbConnection);
    NdbIndexScanOperation* scanOp = getNdbIndexScanOperation(transaction, index);
    
    scanOp->readTuples(NdbOperation::LM_CommittedRead, NdbScanOperation::SF_OrderBy);
    scanOp->setBound(mTable.mRecoveryColumn.c_str(), NdbIndexScanOperation::BoundLT, (char*) & recoverFromId);
    
    NdbRecAttr * row[mTable.mNoColumns];
    
    for (int i = 0; i < mTable.mNoColumns; i++) {
        row[i] = scanOp->getValue(mTable.mColumnNames[i].c_str());
    }

    executeTransaction(transaction, NdbTransaction::Commit);
    
    while (scanOp->nextResult(true) == 0) {
        handleEvent(NdbDictionary::Event::TE_INSERT, NULL, row);
    }
    
    transaction->close();
}
Пример #16
0
int calc_blob_column(const NdbDictionary::Table * t,
		   const NdbDictionary::Index * ix,
		   int col,
		   Ndb* ndb,
		   int & szRam,
		   int & szDisk,
		   bool ftScan)
{

  NdbTransaction * trans = ndb->startTransaction();
  NdbScanOperation * sop = trans->getNdbScanOperation(t);

  sop->readTuples();

  NdbBlob * blob = sop->getBlobHandle(col);  
  bool no_data=false;
  if(trans->execute(NdbTransaction::NoCommit, 
		    NdbOperation::AbortOnError, 1) == -1)
    {
      no_data=true;
      sop->close();
      trans->close();
    }
  
  unsigned long long len=0;


  int rows=0;
  int check=0;
  const NdbDictionary::Column *  c = t->getColumn(col);
  int part_size= c->getPartSize();
  if(!no_data)
    {
      while(((check = sop->nextResult(true)) == 0) && !ignoreData)
	{
	  int isnull;
	  rows++;
	  blob->getNull(isnull);
	  if(isnull)
	    len=0;
	  else	    
	    blob->getLength(len);
	  
	  /*	  
		  printf("blob is %llu\n", len);
		  if(len>256)
		  {
		  szRam+=(((len-256)/part_size) + 1)*part_size+256;
		  printf("len2=%llu, part-size=%d, len=%llu\n", (((len-256)/part_size) + 1)*part_size+256, part_size, len);
		  
		  }
		  else
	  */
	  
	  szRam+=(int)len;
	  if(rows==1000 && !ftScan)
	    break;
	}
      sop->close();
      trans->close();
    }
  if(rows==0)
    {
      if (c->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
      {
          printf("---\tWARNING! No reference data found for BLOB/TEXT. "
             "Defaulting to 256 bytes DataMemory, %d bytes Diskspace! \n",(part_size<=256 ? 0:part_size));
          printf("\tConsider loading database with average data for exact"
             " measurement. \n");
          szRam=256;
          szDisk=(part_size<=256 ? 0:part_size);
          return 0;
      }
      else
      {
         printf("---\tWARNING! No reference data found for BLOB/TEXT. "
	        "Defaulting to %d bytes DataMemory ! \n", (part_size<=256 ? 256:part_size+256));
         printf("\tConsider loading database with average data for exact"
	        " measurement. \n");
         szRam=(part_size<=256 ? 256:part_size+256);
         szDisk=0;
         return 0;
      }
    }
  if (c->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
    {
    int averageSz=szRam/rows;
    if((averageSz)>256)
	  {
      szRam=256;
	  szDisk=((averageSz-256)/part_size) *part_size + (((averageSz-256)%part_size)==0 ? 0:part_size);
	  }
      else
	  {
      szRam=256;
	  szDisk=0;
	  }
    }
  else
    {
      int averageSz=szRam/rows;
      szDisk=0;
      if((averageSz)<256)
        {
        szRam=256;
        }
        else
        {
        szRam=256 + ((averageSz-256)/part_size)*part_size + (((averageSz-256)%part_size)==0 ? 0:part_size);
        }
    }
   
  printf("---\tBLOB/TEXT attribute is %d bytes (RAM) and %d bytes (DISK)"
	 " averaged over %d rows\n", 	 
	 szRam, 
	 szDisk,
	 rows);

  return 0;
}
Пример #17
0
void
HugoOperations::refresh() {
  NdbTransaction * t = getTransaction(); 
  if(t)
    t->refresh();
}
Пример #18
0
int
NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOperation* op, Uint64 table_rows, Uint64* count, int flags)
{
    DBUG_ENTER("NdbIndexStat::records_in_range");
    Uint64 rows;
    Uint32 key1[1000], keylen1;
    Uint32 key2[1000], keylen2;

    if (m_cache == NULL)
        flags |= RR_UseDb | RR_NoUpdate;
    else if (m_area[0].m_entries == 0 || m_area[1].m_entries == 0)
        flags |= RR_UseDb;

    if ((flags & (RR_UseDb | RR_NoUpdate)) != RR_UseDb | RR_NoUpdate) {
        // get start and end key - assume bound is ordered, wellformed
        Uint32 bound[1000];
        Uint32 boundlen = op->getKeyFromSCANTABREQ(bound, 1000);

        keylen1 = keylen2 = 0;
        Uint32 n = 0;
        while (n < boundlen) {
            Uint32 t = bound[n];
            AttributeHeader ah(bound[n + 1]);
            Uint32 sz = 2 + ah.getDataSize();
            t &= 0xFFFF;      // may contain length
            assert(t <= 4);
            bound[n] = t;
            if (t == 0 || t == 1 || t == 4) {
                memcpy(&key1[keylen1], &bound[n], sz << 2);
                keylen1 += sz;
            }
            if (t == 2 || t == 3 || t == 4) {
                memcpy(&key2[keylen2], &bound[n], sz << 2);
                keylen2 += sz;
            }
            n += sz;
        }
    }

    if (flags & RR_UseDb) {
        Uint32 out[4] = { 0, 0, 0, 0 };  // rows, in, before, after
        float tot[4] = { 0, 0, 0, 0 };   // totals of above
        int cnt, ret;
        bool forceSend = true;
        NdbTransaction* trans = op->m_transConnection;
        if (op->interpret_exit_last_row() == -1 ||
                op->getValue(NdbDictionary::Column::RECORDS_IN_RANGE, (char*)out) == 0) {
            m_error = op->getNdbError();
            DBUG_PRINT("error", ("op:%d", op->getNdbError().code));
            DBUG_RETURN(-1);
        }
        if (trans->execute(NdbTransaction::NoCommit,
                           NdbOperation::AbortOnError, forceSend) == -1) {
            m_error = trans->getNdbError();
            DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
                                 op->getNdbError().code));
            DBUG_RETURN(-1);
        }
        cnt = 0;
        while ((ret = op->nextResult(true, forceSend)) == 0) {
            DBUG_PRINT("info", ("frag rows=%u in=%u before=%u after=%u [error=%d]",
                                out[0], out[1], out[2], out[3],
                                (int)(out[1] + out[2] + out[3]) - (int)out[0]));
            unsigned i;
            for (i = 0; i < 4; i++)
                tot[i] += (float)out[i];
            cnt++;
        }
        if (ret == -1) {
            m_error = op->getNdbError();
            DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
                                 op->getNdbError().code));
            DBUG_RETURN(-1);
        }
        op->close(forceSend);
        rows = (Uint64)tot[1];
        if (cnt != 0 && ! (flags & RR_NoUpdate)) {
            float pct[2];
            pct[0] = 100 * tot[2] / tot[0];
            pct[1] = 100 * tot[3] / tot[0];
            DBUG_PRINT("info", ("update stat pct"
                                " before=%.2f after=%.2f",
                                pct[0], pct[1]));
            stat_update(key1, keylen1, key2, keylen2, pct);
        }
    } else {
        float pct[2];
        stat_select(key1, keylen1, key2, keylen2, pct);
        float diff = 100.0 - (pct[0] + pct[1]);
        float trows = (float)table_rows;
        DBUG_PRINT("info", ("select stat pct"
                            " before=%.2f after=%.2f in=%.2f table_rows=%.2f",
                            pct[0], pct[1], diff, trows));
        rows = 0;
        if (diff >= 0)
            rows = (Uint64)(diff * trows / 100);
        if (rows == 0)
            rows = 1;
    }

    *count = rows;
    DBUG_PRINT("value", ("rows=%llu flags=%o", rows, flags));
    DBUG_RETURN(0);
}
Пример #19
0
int calc_var_column(const NdbDictionary::Table * t,
		    const NdbDictionary::Index * ix,
		    int col,
		    Ndb* ndb,
		    bool longvarchar,
		    bool ftScan,
            bool ignoreData)
{
  
  char buff[8052];
  memset(buff, 0, sizeof(buff));
  int sz=0;
  NdbTransaction * trans = ndb->startTransaction();
  if(trans==0)
    abort();

  NdbScanOperation * sop;
  sop=trans->getNdbScanOperation(t);

  sop->readTuples();
  NdbRecAttr * attr=sop->getValue(col, buff);
  int rows=0;
  int charset_size=1;
  bool no_data=false;  

  //Set charset cost (for binary and latin1 cost is 1)
  const NdbDictionary::Column  * c = t->getColumn(col);
  const NdbDictionary::Column::Type type = c->getType();
  if ((type == NdbDictionary::Column::Varchar) || (type == NdbDictionary::Column::Longvarchar))
  {
    CHARSET_INFO * cs2;
    cs2= (CHARSET_INFO*)(c->getCharset());

    if(cs2!=0)
    {       
      if(strncmp(cs2->name, "utf8",4)==0)
      {
        charset_size=3;
        printf(  "---\tWARNING! cs2->name charset used, each character cost : %d bytes\n",charset_size);
      }

      if(strncmp(cs2->name, "ucs2",4)==0)
      {
        charset_size=2;
        printf(  "---\tWARNING! cs2->name charset used, each character cost : %d bytes\n",charset_size);
      }
    }
  }

  //Set var header size
  int headerSize=longvarchar ? 2 : 1;



  if(trans->execute(NdbTransaction::NoCommit, 
		    NdbOperation::AbortOnError, 1) == -1)
  {
	no_data=true;
	trans->close();
  }


  if(!no_data)
  {
    int check=0;
    while( ((check = sop->nextResult(true)) == 0) && !ignoreData)
	{  
	  rows++;
      if (verbose) 
      {
        printf("attribut %d size = %d \n",rows,attr->isNULL()==1 ? 0 : attr->get_size_in_bytes());  
      }


      if(attr->isNULL()==1)  
      {
        sz+=0; //for the time being until we know for sure..
      }
      else
      { //attr->get_size_in_bytes return lengh of attr including header attr cost = (length-header*charset)
        sz+=((attr->get_size_in_bytes() - headerSize)* charset_size);
      }
            
	  if(rows==1024 && !ftScan)
	    break;
	}
    trans->close();
  }

  if(rows==0)
  {
    sz = (int)(((float)(t->getColumn(col)->getSizeInBytes()))* (float)((float)loadfactor/100));
    printf("---\tWARNING! No reference data found for VAR*. Defaulting to max size (loadfactor=100 percent)..%d bytes \n",sz);
    printf("\tConsider loading database with average data for exact measurement\n");
      
    return sz+waste_sz(sz);
  }

  int tmpsz=(sz/rows)+headerSize;
  sz=tmpsz + waste_sz(tmpsz);
  if(ix)
    printf("---\t\tVAR* attribute is %d bytes averaged over %d rows\n", sz, rows);
  else
    printf("---\tVAR* attribute is %d bytes averaged over %d rows\n", sz, rows);
  return sz;
}
Пример #20
0
int scan_update(Ndb* myNdb, 
		int update_column,
		const char * before_color,
		const char * after_color)
		
{
  
  // Scan all records exclusive and update
  // them one by one
  int                  retryAttempt = 0;
  const int            retryMax = 10;
  int updatedRows = 0;
  int check;
  NdbError              err;
  NdbTransaction	*myTrans;
  NdbScanOperation	*myScanOp;

  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("api_scan");

  if (myTable == NULL) 
    APIERROR(myDict->getNdbError());

  /**
   * Loop as long as :
   *  retryMax not reached
   *  failed operations due to TEMPORARY erros
   *
   * Exit loop;
   *  retryMax reached
   *  Permanent error (return -1)
   */
  while (true)
  {

    if (retryAttempt >= retryMax)
    {
      std::cout << "ERROR: has retried this operation " << retryAttempt 
		<< " times, failing!" << std::endl;
      return -1;
    }

    myTrans = myNdb->startTransaction();
    if (myTrans == NULL) 
    {
      const NdbError err = myNdb->getNdbError();

      if (err.status == NdbError::TemporaryError)
      {
	milliSleep(50);
	retryAttempt++;
	continue;
      }
      std::cout <<  err.message << std::endl;
      return -1;
    }

   /**
    * Get a scan operation.
    */
    myScanOp = myTrans->getNdbScanOperation(myTable);	
    if (myScanOp == NULL) 
    {
      std::cout << myTrans->getNdbError().message << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    }

    /**
     * Define a result set for the scan.
     */ 
    if( myScanOp->readTuples(NdbOperation::LM_Exclusive) ) 
    {
      std::cout << myTrans->getNdbError().message << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    } 

    /**
     * Use NdbScanFilter to define a search critera
     */ 
    NdbScanFilter filter(myScanOp) ;   
    if(filter.begin(NdbScanFilter::AND) < 0  || 
       filter.cmp(NdbScanFilter::COND_EQ, update_column, before_color, 20) <0||
       filter.end() <0)
    {
      std::cout <<  myTrans->getNdbError().message << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    }    
    
    /**
     * Start scan    (NoCommit since we are only reading at this stage);
     */     
    if(myTrans->execute(NdbTransaction::NoCommit) != 0)
    {      
      err = myTrans->getNdbError();    
      if(err.status == NdbError::TemporaryError){
	std::cout << myTrans->getNdbError().message << std::endl;
	myNdb->closeTransaction(myTrans);
	milliSleep(50);
	continue;
      }
      std::cout << myTrans->getNdbError().code << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    }

    /**
     * start of loop: nextResult(true) means that "parallelism" number of
     * rows are fetched from NDB and cached in NDBAPI
     */    
    while((check = myScanOp->nextResult(true)) == 0){
      do {
	/**
	 * Get update operation
	 */    
	NdbOperation * myUpdateOp = myScanOp->updateCurrentTuple();
	if (myUpdateOp == 0)
	{
	  std::cout << myTrans->getNdbError().message << std::endl;
	  myNdb->closeTransaction(myTrans);
	  return -1;
	}
	updatedRows++;

	/**
	 * do the update
	 */    
	myUpdateOp->setValue(update_column, after_color);
	/**
	 * nextResult(false) means that the records 
	 * cached in the NDBAPI are modified before
	 * fetching more rows from NDB.
	 */    
      } while((check = myScanOp->nextResult(false)) == 0);
      
      /**
       * NoCommit when all cached tuple have been updated
       */    
      if(check != -1)
      {
	check = myTrans->execute(NdbTransaction::NoCommit);   
      }

      /**
       * Check for errors
       */
      err = myTrans->getNdbError();    
      if(check == -1)
      {
	if(err.status == NdbError::TemporaryError){
	  std::cout << myTrans->getNdbError().message << std::endl;
	  myNdb->closeTransaction(myTrans);
	  milliSleep(50);
	  continue;
	}	
      }
      /**
       * End of loop 
       */
    }

    /**
     * Commit all prepared operations
     */
    if(myTrans->execute(NdbTransaction::Commit) == -1)
    {
      if(err.status == NdbError::TemporaryError){
	std::cout << myTrans->getNdbError().message << std::endl;
	myNdb->closeTransaction(myTrans);
	milliSleep(50);
	continue;
      }	
    }

    std::cout << myTrans->getNdbError().message << std::endl;
    myNdb->closeTransaction(myTrans);
    return 0;    
  }


  if(myTrans!=0) 
  {
    std::cout << myTrans->getNdbError().message << std::endl;
    myNdb->closeTransaction(myTrans);
  }
  return -1;
}
Пример #21
0
int scan_print(Ndb * myNdb)
{
// Scan all records exclusive and update
  // them one by one
  int                  retryAttempt = 0;
  const int            retryMax = 10;
  int fetchedRows = 0;
  int check;
  NdbError              err;
  NdbTransaction	*myTrans;
  NdbScanOperation	*myScanOp;
  /* Result of reading attribute value, three columns:
     REG_NO, BRAND, and COLOR
   */
  NdbRecAttr *    	myRecAttr[3];   

  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("api_scan");

  if (myTable == NULL) 
    APIERROR(myDict->getNdbError());

  /**
   * Loop as long as :
   *  retryMax not reached
   *  failed operations due to TEMPORARY erros
   *
   * Exit loop;
   *  retyrMax reached
   *  Permanent error (return -1)
   */
  while (true)
  {

    if (retryAttempt >= retryMax)
    {
      std::cout << "ERROR: has retried this operation " << retryAttempt 
		<< " times, failing!" << std::endl;
      return -1;
    }

    myTrans = myNdb->startTransaction();
    if (myTrans == NULL) 
    {
      const NdbError err = myNdb->getNdbError();

      if (err.status == NdbError::TemporaryError)
      {
	milliSleep(50);
	retryAttempt++;
	continue;
      }
     std::cout << err.message << std::endl;
      return -1;
    }
    /*
     * Define a scan operation. 
     * NDBAPI.
     */
    myScanOp = myTrans->getNdbScanOperation(myTable);	
    if (myScanOp == NULL) 
    {
      std::cout << myTrans->getNdbError().message << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    }

    /**
     * Read without locks, without being placed in lock queue
     */
    if( myScanOp->readTuples(NdbOperation::LM_CommittedRead) == -1)
    {
      std::cout << myTrans->getNdbError().message << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    } 

    /**
     * Define storage for fetched attributes.
     * E.g., the resulting attributes of executing
     * myOp->getValue("REG_NO") is placed in myRecAttr[0].
     * No data exists in myRecAttr until transaction has commited!
     */
    myRecAttr[0] = myScanOp->getValue("REG_NO");
    myRecAttr[1] = myScanOp->getValue("BRAND");
    myRecAttr[2] = myScanOp->getValue("COLOR");
    if(myRecAttr[0] ==NULL || myRecAttr[1] == NULL || myRecAttr[2]==NULL) 
    {
	std::cout << myTrans->getNdbError().message << std::endl;
	myNdb->closeTransaction(myTrans);
	return -1;
    }
    /**
     * Start scan   (NoCommit since we are only reading at this stage);
     */     
    if(myTrans->execute(NdbTransaction::NoCommit) != 0){      
      err = myTrans->getNdbError();    
      if(err.status == NdbError::TemporaryError){
	std::cout << myTrans->getNdbError().message << std::endl;
	myNdb->closeTransaction(myTrans);
	milliSleep(50);
	continue;
      }
      std::cout << err.code << std::endl;
      std::cout << myTrans->getNdbError().code << std::endl;
      myNdb->closeTransaction(myTrans);
      return -1;
    }
    
    /**
     * start of loop: nextResult(true) means that "parallelism" number of
     * rows are fetched from NDB and cached in NDBAPI
     */    
    while((check = myScanOp->nextResult(true)) == 0){
      do {
	
	fetchedRows++;
	/**
	 * print  REG_NO unsigned int
	 */
	std::cout << myRecAttr[0]->u_32_value() << "\t";

	/**
	 * print  BRAND character string
	 */
	std::cout << myRecAttr[1]->aRef() << "\t";

	/**
	 * print  COLOR character string
	 */
	std::cout << myRecAttr[2]->aRef() << std::endl;

	/**
	 * nextResult(false) means that the records 
	 * cached in the NDBAPI are modified before
	 * fetching more rows from NDB.
	 */    
      } while((check = myScanOp->nextResult(false)) == 0);

    }    
    myNdb->closeTransaction(myTrans);
    return 1;
  }
  return -1;

}
Пример #22
0
const NdbError & DBScanHelper::getNdbError() {
  return tx->getNdbError();
}
Пример #23
0
int populate(Ndb * myNdb)
{
  int i;
  Car cars[15];

  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("api_scan");

  if (myTable == NULL) 
    APIERROR(myDict->getNdbError());

  /**
   * Five blue mercedes
   */
  for (i = 0; i < 5; i++)
  {
    cars[i].reg_no = i;
    sprintf(cars[i].brand, "Mercedes");
    sprintf(cars[i].color, "Blue");
  }

  /**
   * Five black bmw
   */
  for (i = 5; i < 10; i++)
  {
    cars[i].reg_no = i;
    sprintf(cars[i].brand, "BMW");
    sprintf(cars[i].color, "Black");
  }

  /**
   * Five pink toyotas
   */
  for (i = 10; i < 15; i++)
  {
    cars[i].reg_no = i;
    sprintf(cars[i].brand, "Toyota");
    sprintf(cars[i].color, "Pink");
  }
  
  NdbTransaction* myTrans = myNdb->startTransaction();
  if (myTrans == NULL)
    APIERROR(myNdb->getNdbError());

  for (i = 0; i < 15; i++) 
  {
    NdbOperation* myNdbOperation = myTrans->getNdbOperation(myTable);
    if (myNdbOperation == NULL) 
      APIERROR(myTrans->getNdbError());
    myNdbOperation->insertTuple();
    myNdbOperation->equal("REG_NO", cars[i].reg_no);
    myNdbOperation->setValue("BRAND", cars[i].brand);
    myNdbOperation->setValue("COLOR", cars[i].color);
  }

  int check = myTrans->execute(NdbTransaction::Commit);

  myTrans->close();

  return check != -1;
}
Пример #24
0
void
BackupRestore::logEntry(const LogEntry & tup)
{
  if (!m_restore)
    return;

  NdbTransaction * trans = m_ndb->startTransaction();
  if (trans == NULL) 
  {
    // TODO: handle the error
    ndbout << "Cannot start transaction" << endl;
    exit(-1);
  } // if
  
  const TableS * table = tup.m_table;
  NdbOperation * op = trans->getNdbOperation(table->getTableName());
  if (op == NULL) 
  {
    ndbout << "Cannot get operation: ";
    ndbout << trans->getNdbError() << endl;
    exit(-1);
  } // if
  
  int check = 0;
  switch(tup.m_type)
  {
  case LogEntry::LE_INSERT:
    check = op->insertTuple();
    break;
  case LogEntry::LE_UPDATE:
    check = op->updateTuple();
    break;
  case LogEntry::LE_DELETE:
    check = op->deleteTuple();
    break;
  default:
    ndbout << "Log entry has wrong operation type."
	   << " Exiting...";
    exit(-1);
  }
  
  for (int i = 0; i < tup.m_values.size(); i++) 
  {
    const AttributeS * attr = tup.m_values[i];
    int size = attr->Desc->size;
    int arraySize = attr->Desc->arraySize;
    const char * dataPtr = attr->Data.string_value;
    
    const Uint32 length = (size / 8) * arraySize;
    if (attr->Desc->m_column->getPrimaryKey()) 
      op->equal(attr->Desc->attrId, dataPtr, length);
    else
      op->setValue(attr->Desc->attrId, dataPtr, length);
  }
  
#if 1
  trans->execute(Commit);
#else
  const int ret = trans->execute(Commit);
  // Both insert update and delete can fail during log running
  // and it's ok
  
  if (ret != 0)
  {
    ndbout << "execute failed: ";
    ndbout << trans->getNdbError() << endl;
    exit(-1);
  }
#endif
  
  m_ndb->closeTransaction(trans);
  m_logCount++;
}
Пример #25
0
int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
                bool fetch_across_commit, int parallelism)
{
  // Scan all records exclusive and delete 
  // them one by one
  int                  retryAttempt = 0;
  const int            retryMax = 10;
  int deletedRows = 0;
  int check;
  NdbTransaction *pTrans;
  NdbScanOperation *pOp;
  NdbError err;

  int par = parallelism;
  while (true){
  restart:
    if (retryAttempt++ >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }
    
    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      err = pNdb->getNdbError();
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	continue;
      }
      goto failed;
    }

    pOp = pTrans->getNdbScanOperation(pTab->getName());	
    if (pOp == NULL) {
      goto failed;
    }
    
    int flags = 0;
    flags |= _tupscan ? NdbScanOperation::SF_TupScan : 0;
    flags |= _diskscan ? NdbScanOperation::SF_DiskScan : 0;
    if( pOp->readTuples(NdbOperation::LM_Exclusive, 
			flags, par) ) {
      goto failed;
    }
    
    if(pTrans->execute(NdbTransaction::NoCommit) != 0){
      err = pTrans->getNdbError();    
      if(err.status == NdbError::TemporaryError){
	ERR(err);
	pNdb->closeTransaction(pTrans);
	NdbSleep_MilliSleep(50);
	continue;
      }
      goto failed;
    }
    
    while((check = pOp->nextResult(true)) == 0){
      do {
	if (pOp->deleteCurrentTuple() != 0){
	  goto failed;
	}
	deletedRows++;
      } while((check = pOp->nextResult(false)) == 0);
      
      if(check != -1){
        if (fetch_across_commit) {
          check = pTrans->execute(NdbTransaction::Commit);   
          pTrans->restart(); // new tx id
        } else {
          check = pTrans->execute(NdbTransaction::NoCommit);
        }
      }
      
      err = pTrans->getNdbError();    
      if(check == -1){
	if(err.status == NdbError::TemporaryError){
	  ERR(err);
	  pNdb->closeTransaction(pTrans);
	  NdbSleep_MilliSleep(50);
	  par = 1;
	  goto restart;
	}
	goto failed;
      }
    }
    if(check == -1){
      err = pTrans->getNdbError();    
      if(err.status == NdbError::TemporaryError){
	ERR(err);
	pNdb->closeTransaction(pTrans);
	NdbSleep_MilliSleep(50);
	par = 1;
	goto restart;
      }
      goto failed;
    }
    if (! fetch_across_commit &&
        pTrans->execute(NdbTransaction::Commit) != 0) {
      err = pTrans->getNdbError();
      goto failed;
    }
    pNdb->closeTransaction(pTrans);
    return NDBT_OK;
  }
  return NDBT_FAILED;
  
 failed:
  if(pTrans != 0) pNdb->closeTransaction(pTrans);
  ERR(err);
  return (err.code != 0 ? err.code : NDBT_FAILED);
}
Пример #26
0
static void run_slave_wait(struct Xxx &xxx, struct XxxR &xxxr)
{
  struct timeval old_end_time = xxxr.start_time, end_time;
  Ndb *ndb = xxx.ndb;
  const NdbDictionary::Table *myTable = xxx.table;
  int retry_sleep= 10; /* 10 milliseconds */
  int retries= 100;
  while (1)
  {
    Uint32 val;
    NdbTransaction *trans = ndb->startTransaction();
    if (trans == NULL)
      goto err;
    {
      NdbOperation *op = trans->getNdbOperation(myTable);
      if (op == NULL)
        APIERROR(trans->getNdbError());
      op->readTuple();
      op->equal(xxx.pk_col, xxxr.pk_val);
      op->getValue(xxx.col, (char *)&val);
      if (trans->execute(NdbTransaction::Commit))
        goto err;
    }
    /* read done, check time of read */
    gettimeofday(&end_time, 0);
    ndb->closeTransaction(trans);
    //fprintf(stderr, "read %u waiting for %u\n", val, xxxr.val);
    if (xxxr.val != val)
    {
      /* expected value not received yet */
      retries = 100;
      NdbSleep_MilliSleep(retry_sleep);
      old_end_time =  end_time;
      continue;
    }
    break;
err:
    const NdbError this_error= trans ?
      trans->getNdbError() : ndb->getNdbError();
    if (this_error.status == NdbError::TemporaryError)
    {
      if (retries--)
      {
        if (trans)
          ndb->closeTransaction(trans);
        NdbSleep_MilliSleep(retry_sleep);
        continue; // retry
      }
    }
    if (trans)
      ndb->closeTransaction(trans);
    APIERROR(this_error);
  }

  Int64 elapsed_usec1 =
    ((Int64)end_time.tv_sec - (Int64)xxxr.start_time.tv_sec)*1000*1000 +
    ((Int64)end_time.tv_usec - (Int64)xxxr.start_time.tv_usec);
  Int64 elapsed_usec2 =
    ((Int64)end_time.tv_sec - (Int64)old_end_time.tv_sec)*1000*1000 +
    ((Int64)end_time.tv_usec - (Int64)old_end_time.tv_usec);
  xxxr.latency =
    ((elapsed_usec1 - elapsed_usec2/2)+999)/1000;
}
Пример #27
0
void
BackupRestore::logEntry(const LogEntry & tup)
{
  if (!m_restore)
    return;

  NdbTransaction * trans = m_ndb->startTransaction();
  if (trans == NULL) 
  {
    // Deep shit, TODO: handle the error
    err << "Cannot start transaction" << endl;
    exitHandler();
  } // if
  
  const NdbDictionary::Table * table = get_table(tup.m_table->m_dictTable);
  NdbOperation * op = trans->getNdbOperation(table);
  if (op == NULL) 
  {
    err << "Cannot get operation: " << trans->getNdbError() << endl;
    exitHandler();
  } // if
  
  int check = 0;
  switch(tup.m_type)
  {
  case LogEntry::LE_INSERT:
    check = op->insertTuple();
    break;
  case LogEntry::LE_UPDATE:
    check = op->updateTuple();
    break;
  case LogEntry::LE_DELETE:
    check = op->deleteTuple();
    break;
  default:
    err << "Log entry has wrong operation type."
	   << " Exiting...";
    exitHandler();
  }

  if (check != 0) 
  {
    err << "Error defining op: " << trans->getNdbError() << endl;
    exitHandler();
  } // if
  
  Bitmask<4096> keys;
  for (Uint32 i= 0; i < tup.size(); i++) 
  {
    const AttributeS * attr = tup[i];
    int size = attr->Desc->size;
    int arraySize = attr->Desc->arraySize;
    const char * dataPtr = attr->Data.string_value;
    
    if (tup.m_table->have_auto_inc(attr->Desc->attrId))
      tup.m_table->update_max_auto_val(dataPtr,size*arraySize);

    const Uint32 length = (size / 8) * arraySize;
    if (attr->Desc->m_column->getPrimaryKey())
    {
      if(!keys.get(attr->Desc->attrId))
      {
	keys.set(attr->Desc->attrId);
	check= op->equal(attr->Desc->attrId, dataPtr, length);
      }
    }
    else
      check= op->setValue(attr->Desc->attrId, dataPtr, length);
    
    if (check != 0) 
    {
      err << "Error defining op: " << trans->getNdbError() << endl;
      exitHandler();
    } // if
  }
  
  const int ret = trans->execute(NdbTransaction::Commit);
  if (ret != 0)
  {
    // Both insert update and delete can fail during log running
    // and it's ok
    // TODO: check that the error is either tuple exists or tuple does not exist?
    bool ok= false;
    NdbError errobj= trans->getNdbError();
    switch(tup.m_type)
    {
    case LogEntry::LE_INSERT:
      if(errobj.status == NdbError::PermanentError &&
	 errobj.classification == NdbError::ConstraintViolation)
	ok= true;
      break;
    case LogEntry::LE_UPDATE:
    case LogEntry::LE_DELETE:
      if(errobj.status == NdbError::PermanentError &&
	 errobj.classification == NdbError::NoDataFound)
	ok= true;
      break;
    }
    if (!ok)
    {
      err << "execute failed: " << errobj << endl;
      exitHandler();
    }
  }
  
  m_ndb->closeTransaction(trans);
  m_logCount++;
}
Пример #28
0
int
select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
             int parallelism,
             Uint64* count_rows,
             NdbOperation::LockMode lock) {

    int                  retryAttempt = 0;
    const int            retryMax = 100;
    int                  check;
    NdbTransaction       *pTrans;
    NdbScanOperation	       *pOp;
    const Uint32 codeWords= 1;
    Uint32 codeSpace[ codeWords ];
    NdbInterpretedCode code(NULL, // Table is irrelevant
                            &codeSpace[0],
                            codeWords);
    if ((code.interpret_exit_last_row() != 0) ||
            (code.finalise() != 0))
    {
        ERR(code.getNdbError());
        return NDBT_FAILED;
    }

    while (true) {

        if (retryAttempt >= retryMax) {
            g_info << "ERROR: has retried this operation " << retryAttempt
                   << " times, failing!" << endl;
            return NDBT_FAILED;
        }

        pTrans = pNdb->startTransaction();
        if (pTrans == NULL) {
            const NdbError err = pNdb->getNdbError();

            if (err.status == NdbError::TemporaryError) {
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            return NDBT_FAILED;
        }
        pOp = pTrans->getNdbScanOperation(pTab->getName());
        if (pOp == NULL) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return NDBT_FAILED;
        }

        if( pOp->readTuples(NdbScanOperation::LM_Dirty) ) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return NDBT_FAILED;
        }


        check = pOp->setInterpretedCode(&code);
        if( check == -1 ) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return NDBT_FAILED;
        }

        Uint64 tmp;
        Uint32 row_size;
        pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&tmp);
        pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&row_size);
        check = pTrans->execute(NdbTransaction::NoCommit);
        if( check == -1 ) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return NDBT_FAILED;
        }

        Uint64 row_count = 0;
        int eof;
        while((eof = pOp->nextResult(true)) == 0) {
            row_count += tmp;
        }

        if (eof == -1) {
            const NdbError err = pTrans->getNdbError();

            if (err.status == NdbError::TemporaryError) {
                pNdb->closeTransaction(pTrans);
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            pNdb->closeTransaction(pTrans);
            return NDBT_FAILED;
        }

        pNdb->closeTransaction(pTrans);

        if (count_rows != NULL) {
            *count_rows = row_count;
        }

        return NDBT_OK;
    }
    return NDBT_FAILED;
}
Пример #29
0
void
BackupRestore::tuple(const TupleS & tup)
{
  if (!m_restore)
    return;
  while (1) 
  {
    NdbTransaction * trans = m_ndb->startTransaction();
    if (trans == NULL) 
    {
      // TODO: handle the error
      ndbout << "Cannot start transaction" << endl;
      exit(-1);
    } // if
    
    const TableS * table = tup.getTable();
    NdbOperation * op = trans->getNdbOperation(table->getTableName());
    if (op == NULL) 
    {
      ndbout << "Cannot get operation: ";
      ndbout << trans->getNdbError() << endl;
      exit(-1);
    } // if
    
    // TODO: check return value and handle error
    if (op->writeTuple() == -1) 
    {
      ndbout << "writeTuple call failed: ";
      ndbout << trans->getNdbError() << endl;
      exit(-1);
    } // if
    
    for (int i = 0; i < tup.getNoOfAttributes(); i++) 
    {
      const AttributeS * attr = tup[i];
      int size = attr->Desc->size;
      int arraySize = attr->Desc->arraySize;
      const char * dataPtr = attr->Data.string_value;
      
      const Uint32 length = (size * arraySize) / 8;
      if (attr->Desc->m_column->getPrimaryKey()) 
	op->equal(i, dataPtr, length);
    }
    
    for (int i = 0; i < tup.getNoOfAttributes(); i++) 
    {
      const AttributeS * attr = tup[i];
      int size = attr->Desc->size;
      int arraySize = attr->Desc->arraySize;
      const char * dataPtr = attr->Data.string_value;
      
      const Uint32 length = (size * arraySize) / 8;
      if (!attr->Desc->m_column->getPrimaryKey())
	if (attr->Data.null)
	  op->setValue(i, NULL, 0);
	else
	  op->setValue(i, dataPtr, length);
    }
    int ret = trans->execute(Commit);
    if (ret != 0)
    {
      ndbout << "execute failed: ";
      ndbout << trans->getNdbError() << endl;
      exit(-1);
    }
    m_ndb->closeTransaction(trans);
    if (ret == 0)
      break;
  }
  m_dataCount++;
}
int runPkReadMultiBasic(NDBT_Context* ctx, NDBT_Step* step){
  int loops = ctx->getNumLoops();
  int records = ctx->getNumRecords();
  const int MAX_NDBS = 200;
  Ndb* pNdb = GETNDB(step);
  Ndb_cluster_connection* conn = &pNdb->get_ndb_cluster_connection();

  int i = 0;
  HugoOperations hugoOps(*ctx->getTab());

  Ndb* ndbObjs[ MAX_NDBS ];
  NdbTransaction* transArray[ MAX_NDBS ];
  Ndb ** ready_ndbs;

  for (int j=0; j < MAX_NDBS; j++)
  {
    Ndb* ndb = new Ndb(conn);
    check(ndb->init() == 0, (*ndb));
    ndbObjs[ j ] = ndb;
  }

  while (i<loops) {
    ndbout << "Loop : " << i << ": ";
    int recordsLeft = records;

    do
    {
      /* Define and execute Pk read requests on
       * different Ndb objects
       */
      int ndbcnt = 0;
      int pollcnt = 0;
      int lumpsize = 1 + myRandom48(MIN(recordsLeft, MAX_NDBS));
      while(lumpsize &&
            recordsLeft &&
            ndbcnt < MAX_NDBS)
      {
        Ndb* ndb = ndbObjs[ ndbcnt ];
        NdbTransaction* trans = ndb->startTransaction();
        check(trans != NULL, (*ndb));
        NdbOperation* readOp = trans->getNdbOperation(ctx->getTab());
        check(readOp != NULL, (*trans));
        check(readOp->readTuple() == 0, (*readOp));
        check(hugoOps.equalForRow(readOp, recordsLeft) == 0, hugoOps);

        /* Read all other cols */
        for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++)
        {
          check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL,
                (*readOp));
        }

        /* Now send em off */
        trans->executeAsynchPrepare(NdbTransaction::Commit,
                                    NULL,
                                    NULL,
                                    NdbOperation::AbortOnError);
        ndb->sendPreparedTransactions();

        transArray[ndbcnt] = trans;
        global_poll_group->addNdb(ndb);

        ndbcnt++;
        pollcnt++;
        recordsLeft--;
        lumpsize--;
      };

      /* Ok, now wait for the Ndbs to complete */
      while (pollcnt)
      {
        /* Occasionally check with no timeout */
        Uint32 timeout_millis = myRandom48(2)?10000:0;
        int count = global_poll_group->wait(ready_ndbs, timeout_millis);

        if (count > 0)
        {
          for (int y=0; y < count; y++)
          {
            Ndb *ndb = ready_ndbs[y];
            check(ndb->pollNdb(0, 1) != 0, (*ndb));
          }
          pollcnt -= count;
        }
      }

      /* Ok, now close the transactions */
      for (int t=0; t < ndbcnt; t++)
      {
        transArray[t]->close();
      }
    } while (recordsLeft);

    i++;
  }

  for (int j=0; j < MAX_NDBS; j++)
  {
    delete ndbObjs[ j ];
  }

  return NDBT_OK;
}