Esempio n. 1
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);
}
Esempio n. 2
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;
}
Esempio n. 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;
}
Esempio n. 4
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;
}
Esempio n. 5
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++;
}
Esempio n. 6
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;
}
Esempio n. 7
0
int scanReadRecords(Ndb* pNdb,
                    const NdbDictionary::Table* pTab,
                    const NdbDictionary::Index* pIdx,
                    int parallel,
                    int _lock,
                    bool headers,
                    bool useHexFormat,
                    char delimiter, bool order, bool descending) {

    int                  retryAttempt = 0;
    const int            retryMax = 100;
    int                  check;
    NdbTransaction       *pTrans;
    NdbScanOperation	       *pOp;
    NdbIndexScanOperation * pIOp= 0;

    NDBT_ResultRow * row = new NDBT_ResultRow(*pTab, delimiter);

    while (true) {

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

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

            if (err.status == NdbError::TemporaryError) {
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            return -1;
        }


        pOp = (!pIdx) ? pTrans->getNdbScanOperation(pTab->getName()) :
              pIOp=pTrans->getNdbIndexScanOperation(pIdx->getName(), pTab->getName());

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

        int rs;
        unsigned scan_flags = 0;
        if (_tup) scan_flags |= NdbScanOperation::SF_TupScan;
        switch(_lock + (3 * order)) {
        case 1:
            rs = pOp->readTuples(NdbScanOperation::LM_Read, scan_flags, parallel);
            break;
        case 2:
            rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, scan_flags, parallel);
            break;
        case 3:
            rs = pIOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallel,
                                  true, descending);
            break;
        case 4:
            rs = pIOp->readTuples(NdbScanOperation::LM_Read, 0, parallel, true, descending);
            break;
        case 5:
            rs = pIOp->readTuples(NdbScanOperation::LM_Exclusive, 0, parallel, true, descending);
            break;
        case 0:
        default:
            rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, scan_flags, parallel);
            break;
        }
        if( rs != 0 ) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return -1;
        }

        if(0) {
            NdbScanFilter sf(pOp);
#if 0
            sf.begin(NdbScanFilter::AND);
            sf.le(0, (Uint32)10);

            sf.end();
#elif 0
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)10);
            sf.lt(0, (Uint32)20);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)30);
            sf.lt(0, (Uint32)40);
            sf.end();
            sf.end();
#elif 1
            sf.begin(NdbScanFilter::AND);
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)10);
            sf.lt(0, (Uint32)20);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)30);
            sf.lt(0, (Uint32)40);
            sf.end();
            sf.end();
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)0);
            sf.lt(0, (Uint32)50);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)100);
            sf.lt(0, (Uint32)200);
            sf.end();
            sf.end();
            sf.end();
#endif
        } else {
            check = pOp->interpret_exit_ok();
            if( check == -1 ) {
                ERR(pTrans->getNdbError());
                pNdb->closeTransaction(pTrans);
                return -1;
            }
        }

        bool disk= false;
        for(int a = 0; a<pTab->getNoOfColumns(); a++)
        {
            const NdbDictionary::Column* col = pTab->getColumn(a);
            if(col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
                disk= true;

            if (!nodata)
                if((row->attributeStore(a) = pOp->getValue(col)) == 0)
                {
                    ERR(pTrans->getNdbError());
                    pNdb->closeTransaction(pTrans);
                    return -1;
                }
        }

        NdbRecAttr * disk_ref= 0;
        if(_dumpDisk && disk)
            disk_ref = pOp->getValue(NdbDictionary::Column::DISK_REF);

        NdbRecAttr * rowid= 0, *frag = 0, *gci = 0;
        if (use_rowid)
        {
            frag = pOp->getValue(NdbDictionary::Column::FRAGMENT);
            rowid = pOp->getValue(NdbDictionary::Column::ROWID);
        }

        if (use_gci)
        {
            gci = pOp->getValue(NdbDictionary::Column::ROW_GCI);
        }

        check = pTrans->execute(NdbTransaction::NoCommit);
        if( check == -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 -1;
        }

        if (rowid)
            ndbout << "ROWID\t";

        if (gci)
            ndbout << "\tGCI";

        if (headers && !nodata)
            row->header(ndbout);

        if (disk_ref)
            ndbout << "\tDISK_REF";

        ndbout << endl;

        int eof;
        int rows = 0;
        eof = pOp->nextResult();

        while(eof == 0) {
            rows++;

            if (useHexFormat)
                ndbout.setHexFormat(1);

            if (rowid)
            {
                ndbout << "[ fragment: " << frag->u_32_value()
                       << " m_page: " << rowid->u_32_value()
                       << " m_page_idx: " << *(Uint32*)(rowid->aRef() + 4) << " ]";
                ndbout << "\t";
            }

            if (gci)
            {
                if (gci->isNULL())
                    ndbout << "NULL\t";
                else
                    ndbout << gci->u_64_value() << "\t";
            }

            if (!nodata)
                ndbout << (*row);

            if(disk_ref)
            {
                ndbout << "\t";
                ndbout << "[ m_file_no: " << *(Uint16*)(disk_ref->aRef()+6)
                       << " m_page: " << disk_ref->u_32_value()
                       << " m_page_idx: " << *(Uint16*)(disk_ref->aRef() + 4) << " ]";
            }

            if (rowid || disk_ref || gci || !nodata)
                ndbout << endl;
            eof = pOp->nextResult();
        }
        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 -1;
        }

        pNdb->closeTransaction(pTrans);

        ndbout << rows << " rows returned" << endl;

        return 0;
    }
    return -1;
}
Esempio n. 8
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);
}
Esempio n. 9
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;

}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
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++;
}
Esempio n. 13
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;
}
Esempio n. 14
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);
}
const NdbError & DBScanHelper::getNdbError() {
  return tx->getNdbError();
}
Esempio n. 16
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++;
}
Esempio n. 17
0
static int
runBug14702377(NDBT_Context* ctx, NDBT_Step* step)
{
    Ndb* pNdb = GETNDB(step);
    NdbDictionary::Dictionary * pDict = pNdb->getDictionary();
    int records = ctx->getNumRecords();
    int result = NDBT_OK;

    while (ctx->getProperty("HalfStartedDone", (Uint32)0) == 0)
    {
        ndbout << "Wait for half started..." << endl;
        NdbSleep_SecSleep(15);
    }
    ndbout << "Got half started" << endl;

    while (1)
    {
        require(table_list.size() == 1);
        const char* tabname = table_list[0].c_str();
        const NdbDictionary::Table* tab = 0;
        CHK2((tab = pDict->getTable(tabname)) != 0,
             tabname << ": " << pDict->getNdbError());
        const int ncol = tab->getNoOfColumns();

        {
            HugoTransactions trans(*tab);
            CHK2(trans.loadTable(pNdb, records) == 0, trans.getNdbError());
        }

        for (int r = 0; r < records; r++)
        {
            // with 1000 records will surely hit bug case
            const int lm = myRandom48(4); // 2
            const int nval = myRandom48(ncol + 1); // most
            const bool exist = myRandom48(2); // false

            NdbTransaction* pTx = 0;
            NdbOperation* pOp = 0;
            CHK2((pTx = pNdb->startTransaction()) != 0,
                 pNdb->getNdbError());
            CHK2((pOp = pTx->getNdbOperation(tab)) != 0,
                 pTx->getNdbError());
            CHK2((pOp->readTuple((NdbOperation::LockMode)lm)) == 0,
                 pOp->getNdbError());

            for (int id = 0; id <= 0; id++)
            {
                const NdbDictionary::Column* c = tab->getColumn(id);
                require(c != 0 && c->getPrimaryKey() &&
                        c->getType() == NdbDictionary::Column::Unsigned);
                Uint32 val = myRandom48(records);
                if (!exist)
                    val = 0xaaaa0000 + myRandom48(0xffff + 1);
                const char* valp = (const char*)&val;
                CHK2(pOp->equal(id, valp) == 0, pOp->getNdbError());
            }
            CHK2(result == NDBT_OK, "failed");

            for (int id = 0; id < nval; id++)
            {
                const NdbDictionary::Column* c = tab->getColumn(id);
                require(c != 0 && (id == 0 || !c->getPrimaryKey()));
                CHK2(pOp->getValue(id) != 0, pOp->getNdbError());
            }
            CHK2(result == NDBT_OK, "failed");

            char info1[200];
            sprintf(info1, "lm=%d nval=%d exist=%d",
                    lm, nval, exist);
            g_info << "PK read T1 exec: " << info1 << endl;
            Uint64 t1 = NdbTick_CurrentMillisecond();
            int ret = pTx->execute(NdbTransaction::NoCommit);
            Uint64 t2 = NdbTick_CurrentMillisecond();
            int msec = (int)(t2-t1);
            const NdbError& txerr = pTx->getNdbError();
            const NdbError& operr = pOp->getNdbError();
            char info2[200];
            sprintf(info2, "%s msec=%d ret=%d txerr=%d operr=%d",
                    info1, msec, ret, txerr.code, operr.code);
            g_info << "PK read T1 done: " << info2 << endl;

            if (ret == 0 && txerr.code == 0 && operr.code == 0)
            {
                CHK2(exist, "row should not be found: " << info2);
            }
            else if (ret == 0 && txerr.code == 626 && operr.code == 626)
            {
                CHK2(!exist, "row should be found: " << info2);
            }
            else if (txerr.status == NdbError::TemporaryError)
            {
                g_err << "PK read T1 temporary error (tx): " << info2 << endl;
                NdbSleep_MilliSleep(50);
            }
            else if (operr.status == NdbError::TemporaryError)
            {
                g_err << "PK read T1 temporary error (op): " << info2 << endl;
                NdbSleep_MilliSleep(50);
            }
            else
            {
                // gets 4012 before bugfix
                CHK2(false, "unexpected error: " << info2);
            }
            pNdb->closeTransaction(pTx);
            pTx = 0;
        }

        break;
    }

    g_err << "Clear half started hold..." << endl;
    ctx->setProperty("HalfStartedHold", (Uint32)0);
    return result;
}