int
run_read() {
    int iter = g_paramters[P_LOOPS].value;
    NDB_TICKS start1, stop;
    int sum_time= 0;

    const Uint32 rows = g_paramters[P_ROWS].value;
    const Uint32 range = g_paramters[P_RANGE].value;

    start1 = NdbTick_CurrentMillisecond();
    NdbConnection * pTrans = g_ndb->startTransaction();
    if(!pTrans) {
        g_err << "Failed to start transaction" << endl;
        err(g_ndb->getNdbError());
        return -1;
    }

    NdbOperation * pOp;
    NdbScanOperation * pSp;
    NdbIndexOperation * pUp;
    NdbIndexScanOperation * pIp;

    Uint32 start_row = rand() % (rows - range);
    Uint32 stop_row = start_row + range;

    /**
     * 0 - serial pk
     * 1 - batch pk
     * 2 - serial uniq
     * 3 - batch uniq
     * 4 - index eq
     * 5 - range scan
     * 6 - interpreted scan
     */
    int check = 0;
    void* res = (void*)~0;
    const Uint32 pk = 0;
    Uint32 cnt = 0;
    for(; start_row < stop_row; start_row++) {
        switch(g_paramters[P_OPER].value) {
        case 0:
            pOp = pTrans->getNdbOperation(g_table);
            check = pOp->readTuple();
            check = pOp->equal(pk, start_row);
            break;
        case 1:
            for(; start_row<stop_row; start_row++) {
                pOp = pTrans->getNdbOperation(g_table);
                check = pOp->readTuple();
                check = pOp->equal(pk, start_row);
                for(int j = 0; j<g_tab->getNoOfColumns(); j++) {
                    res = pOp->getValue(j);
                    assert(res);
                }
            }
            break;
        case 2:
            pOp = pTrans->getNdbIndexOperation(g_unique, g_table);
            check = pOp->readTuple();
            check = pOp->equal(pk, start_row);
            break;
        case 3:
            for(; start_row<stop_row; start_row++) {
                pOp = pTrans->getNdbIndexOperation(g_unique, g_table);
                check = pOp->readTuple();
                check = pOp->equal(pk, start_row);
                for(int j = 0; j<g_tab->getNoOfColumns(); j++) {
                    res = pOp->getValue(j);
                    assert(res);
                }
            }
            break;
        case 4:
            pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
            pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
            check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row);
            break;
        case 5:
            pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
            pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
            check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
            check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
            start_row = stop_row;
            break;
        case 6:
            pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
            pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true);
            check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
            check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
            start_row = stop_row;
            break;
        case 7:
            pOp = pSp = pTrans->getNdbScanOperation(g_table);
            pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
            NdbScanFilter filter(pOp) ;
            filter.begin(NdbScanFilter::AND);
            filter.ge(pk, start_row);
            filter.lt(pk, stop_row);
            filter.end();
            start_row = stop_row;
            break;
        }

        assert(res);
        if(check != 0) {
            ndbout << pOp->getNdbError() << endl;
            ndbout << pTrans->getNdbError() << endl;
        }
        assert(check == 0);

        for(int j = 0; j<g_tab->getNoOfColumns(); j++) {
            res = pOp->getValue(j);
            assert(res);
        }

        check = pTrans->execute(NoCommit);
        if(check != 0) {
            ndbout << pTrans->getNdbError() << endl;
        }
        assert(check == 0);
        if(g_paramters[P_OPER].value >= 4) {
            while((check = pSp->nextResult(true)) == 0) {
                cnt++;
            }

            if(check == -1) {
                err(pTrans->getNdbError());
                return -1;
            }
            assert(check == 1);
            pSp->close();
        }
    }
    assert(g_paramters[P_OPER].value < 4 || (cnt == range));

    pTrans->close();

    stop = NdbTick_CurrentMillisecond();
    g_times[g_paramters[P_OPER].value] += (stop - start1);
    return 0;
}
int
HugoTransactions::scanReadRecords(Ndb* pNdb, 
				  int records,
				  int abortPercent,
				  int parallelism, 
				  NdbOperation::LockMode lm,
                                  int scan_flags)
{
  
  int                  retryAttempt = 0;
  int                  check, a;
  NdbScanOperation	       *pOp;

  while (true){

    if (retryAttempt >= m_retryMax){
      g_err << "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){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = getScanOperation(pTrans);
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if( pOp ->readTuples(lm, scan_flags, parallelism) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
  
    for(a = 0; a<tab.getNoOfColumns(); a++){
      if((row.attributeStore(a) = 
	  pOp->getValue(tab.getColumn(a)->getName())) == 0) {
	ERR(pTrans->getNdbError());
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }

    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      const NdbError err = pTrans->getNdbError();
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    // Abort after 1-100 or 1-records rows
    int ranVal = rand();
    int abortCount = ranVal % (records == 0 ? 100 : records); 
    bool abortTrans = false;
    if (abort > 0){
      // Abort if abortCount is less then abortPercent 
      if (abortCount < abortPercent) 
	abortTrans = true;
    }
    
    int eof;
    int rows = 0;
    while((eof = pOp->nextResult(true)) == 0){
      rows++;
      if (calc.verifyRowValues(&row) != 0){
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }

      if (abortCount == rows && abortTrans == true){
	ndbout << "Scan is aborted" << endl;
	g_info << "Scan is aborted" << endl;
	pOp->close();
	if( check == -1 ) {
	  ERR(pTrans->getNdbError());
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
	
	closeTransaction(pNdb);
	return NDBT_OK;
      }
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR_INFO(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	switch (err.code){
	case 488:
	case 245:
	case 490:
	  // Too many active scans, no limit on number of retry attempts
	  break;
	default:
	  retryAttempt++;
	}
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    closeTransaction(pNdb);

    g_info << rows << " rows have been read" << endl;
    if (records != 0 && rows != records){
      g_err << "Check expected number of records failed" << endl 
	    << "  expected=" << records <<", " << endl
	    << "  read=" << rows << endl;
      return NDBT_FAILED;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #3
0
inline 
int 
ScanFunctions::scanReadFunctions(Ndb* pNdb,
				 int records,
				 int parallelism,
				 ActionType action,
				 bool exclusive){
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int sleepTime = 10;
  int                  check;
  NdbConnection	       *pTrans = 0;
  NdbScanOperation     *pOp = 0;

  while (true){
    if (retryAttempt >= retryMax){
      g_err << "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){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }
    
    // Execute the scan without defining a scan operation
    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    if( pOp->readTuples(exclusive ? 
			NdbScanOperation::LM_Exclusive : 
			NdbScanOperation::LM_Read) ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    
    if (action == OnlyOpenScanOnce){
      // Call openScan one more time when it's already defined
      if( pOp->readTuples(NdbScanOperation::LM_Read) ) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }
    }
    
    if (action==EqualAfterOpenScan){
      check = pOp->equal(tab.getColumn(0)->getName(), 10);
      if( check == -1 ) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }	
    }
    
    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    for(int a = 0; a<tab.getNoOfColumns(); a++){
      if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }
    }      
    
    check = pTrans->execute(NoCommit);
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    int abortCount = records / 10;
    bool abortTrans = (action==CloseWithoutStop);
    int eof;
    int rows = 0;
    eof = pOp->nextResult();
    
    while(eof == 0){
      rows++;
      
      if (abortCount == rows && abortTrans == true){
	g_info << "Scan is aborted after "<<abortCount<<" rows" << endl;
	
	if (action != CloseWithoutStop){
	  // Test that we can closeTrans without stopScan
	  pOp->close();
	  if( check == -1 ) {
	    ERR(pTrans->getNdbError());
	    pNdb->closeTransaction(pTrans);
	    return NDBT_FAILED;
	  }
	}

	
	pNdb->closeTransaction(pTrans);
	return NDBT_OK;
      }
      
      if(action == CheckInactivityTimeOut){
	if ((rows % (records / 10)) == 0){
	  // Sleep for a long time before calling nextScanResult
	  if (sleepTime > 1)
	    sleepTime--;
	  g_info << "Sleeping "<<sleepTime<<" secs " << endl;
	  NdbSleep_SecSleep(sleepTime); 
	}
      }

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

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	
	// Be cruel, call nextScanResult after error
	for(int i=0; i<10; i++){
	  eof = pOp->nextResult();
	  if(eof == 0){
	    g_err << "nextScanResult returned eof = " << eof << endl
		   << " That is an error when there are no more records" << endl;
	    return NDBT_FAILED;
	  }
	}
	// Be cruel end

	pNdb->closeTransaction(pTrans);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	g_info << "Starting over" << endl;

	// If test is CheckInactivityTimeOut
	// error 296 is expected
	if ((action == CheckInactivityTimeOut) &&
	    (err.code == 296))
	  return NDBT_OK;

	continue;
      }
      ERR(err);
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    if (action == NextScanWhenNoMore){
      g_info << "Calling nextScanresult when there are no more records" << endl;
      for(int i=0; i<10; i++){
	eof = pOp->nextResult();
	if(eof == 0){
	  g_err << "nextScanResult returned eof = " << eof << endl
		 << " That is an error when there are no more records" << endl;
	  return NDBT_FAILED;
	}
      }

    }
    if(action == CheckInactivityBeforeClose){
      // Sleep for a long time before calling close
      g_info << "NdbSleep_SecSleep(5) before close transaction" << endl;
      NdbSleep_SecSleep(5); 
    }
    if(action == NoCloseTransaction)
      g_info << "Forgetting to close transaction" << endl;
    else
      pNdb->closeTransaction(pTrans);

    g_info << rows << " rows have been read" << endl;
    if (records != 0 && rows != records){
      g_err << "Check expected number of records failed" << endl 
	     << "  expected=" << records <<", " << endl
	     << "  read=" << rows <<  endl;
      return NDBT_FAILED;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;


}
Exemple #4
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;
}