/** * Callback executed when transaction has return from NDB */ static void callback(int result, NdbTransaction* trans, void* aObject) { async_callback_t * cbData = (async_callback_t *)aObject; if (result<0) { /** * Error: Temporary or permanent? */ if (asynchErrorHandler(trans, (Ndb*)cbData->ndb)) { closeTransaction((Ndb*)cbData->ndb, cbData); while(populate((Ndb*)cbData->ndb, cbData->data, cbData) < 0) milliSleep(10); } else { std::cout << "Restore: Failed to restore data " << "due to a unrecoverable error. Exiting..." << std::endl; delete cbData; asynchExitHandler((Ndb*)cbData->ndb); } } else { /** * OK! close transaction */ closeTransaction((Ndb*)cbData->ndb, cbData); delete cbData; } }
int DBTransactionContext::execute(DBOperationSet *operations, int _execType, int _abortOption, int force) { int rval; int opListSize = operations->size; NdbTransaction::ExecType execType = static_cast<NdbTransaction::ExecType>(_execType); NdbOperation::AbortOption abortOption = static_cast<NdbOperation::AbortOption>(_abortOption); bool doClose = (execType != NdbTransaction::NoCommit); if(! ndbTransaction) { startTransaction(operations->getKeyOperation(0)); } operations->prepare(ndbTransaction); if(operations->hasBlobReadOperations()) { ndbTransaction->execute(NdbTransaction::NoCommit); DEBUG_PRINT("BLOB EXECUTE DONE"); } rval = ndbTransaction->execute(execType, abortOption, force); DEBUG_PRINT("EXECUTE sync : %s %d operation%s %s => return: %d error: %d", modes[execType], opListSize, (opListSize == 1 ? "" : "s"), (doClose ? " & close transaction" : ""), rval, ndbTransaction->getNdbError().code); if(doClose) { closeTransaction(); } return rval; }
/* ** Write data to an jt-file. */ static int jtWrite( sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ int rc; jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){ if( iOfst==0 ){ jt_file *pMain = locateDatabaseHandle(p->zName); assert( pMain ); if( iAmt==28 ){ /* Zeroing the first journal-file header. This is the end of a ** transaction. */ closeTransaction(pMain); }else if( iAmt!=12 ){ /* Writing the first journal header to a journal file. This happens ** when a transaction is first started. */ u8 *z = (u8 *)zBuf; pMain->nPage = decodeUint32(&z[16]); pMain->nPagesize = decodeUint32(&z[24]); if( SQLITE_OK!=(rc=openTransaction(pMain, p)) ){ return rc; } } } if( p->iMaxOff<(iOfst + iAmt) ){ p->iMaxOff = iOfst + iAmt; } } if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){ if( iAmt<p->nPagesize && p->nPagesize%iAmt==0 && iOfst>=(PENDING_BYTE+512) && iOfst+iAmt<=PENDING_BYTE+p->nPagesize ){ /* No-op. This special case is hit when the backup code is copying a ** to a database with a larger page-size than the source database and ** it needs to fill in the non-locking-region part of the original ** pending-byte page. */ }else{ u32 pgno = iOfst/p->nPagesize + 1; assert( (iAmt==1||iAmt==p->nPagesize) && ((iOfst+iAmt)%p->nPagesize)==0 ); assert( pgno<=p->nPage || p->nSync>0 ); assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) ); } } rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){ jt_file *pMain = locateDatabaseHandle(p->zName); int rc2 = readJournalFile(p, pMain); if( rc==SQLITE_OK ) rc = rc2; } return rc; }
/* ** Delete the file located at zPath. If the dirSync argument is true, ** ensure the file-system modifications are synced to disk before ** returning. */ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int nPath = strlen(zPath); if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){ /* Deleting a journal file. The end of a transaction. */ jt_file *pMain = locateDatabaseHandle(zPath); if( pMain ){ closeTransaction(pMain); } } return sqlite3OsDelete(g.pVfs, zPath, dirSync); }
void Soprano::Index::CLuceneIndex::close() { // qDebug() << "CLuceneIndex::close in thread " << QThread::currentThreadId(); clearError(); if ( d->transactionID ) { closeTransaction( d->transactionID ); } QMutexLocker lock( &d->mutex ); d->closeReader(); d->closeWriter(); // qDebug() << "CLuceneIndex::close done in thread " << QThread::currentThreadId(); }
extern "C" void* NdbThreadFuncUpdate(void* pArg) { myRandom48Init((long int)NdbTick_CurrentMillisecond()); unsigned nSucc = 0; unsigned nFail = 0; Ndb* pNdb = NULL ; pNdb = new Ndb("TEST_DB"); VerifyMethodInt(pNdb, init()); VerifyMethodInt(pNdb, waitUntilReady()); while(NdbMutex_Trylock(g_pNdbMutex)) { Uint32 nWarehouse = myRandom48(g_nWarehouseCount); NdbConnection* pNdbConnection = NULL ; VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); CHK_TR(pNdbConnection) ; // epaulsa NdbOperation* pNdbOperationW = NULL ; VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple()); VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1))); Uint32 nWarehouseSum = 0; for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) { NdbOperation* pNdbOperationD = NULL ; VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict)); VerifyMethodInt(pNdbOperationD, interpretedUpdateTuple()); VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse)); VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict)); VerifyMethodInt(pNdbOperationD, incValue(c_szDistrictCount, Uint32(1))); Uint32 nDistrictSum = myRandom48(100); nWarehouseSum += nDistrictSum; VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum)); } VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum)); int iExec = pNdbConnection->execute(Commit); int iError = pNdbConnection->getNdbError().code; if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); } if(iExec==0) { ++nSucc; } else { ++nFail; } VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); } ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl; NdbMutex_Unlock(g_pNdbMutex); delete pNdb; pNdb = NULL ; return NULL; }
/* ** Close an jt-file. */ static int jtClose(sqlite3_file *pFile){ jt_file **pp; jt_file *p = (jt_file *)pFile; closeTransaction(p); enterJtMutex(); if( p->zName ){ for(pp=&g.pList; *pp!=p; pp=&(*pp)->pNext); *pp = p->pNext; } leaveJtMutex(); return sqlite3OsClose(p->pReal); }
static int jtWrite( sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ int rc; jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){ if( iOfst==0 ){ jt_file *pMain = locateDatabaseHandle(p->zName); assert( pMain ); if( iAmt==28 ){ closeTransaction(pMain); }else if( iAmt!=12 ){ u8 *z = (u8 *)zBuf; pMain->nPage = decodeUint32(&z[16]); pMain->nPagesize = decodeUint32(&z[24]); if( SQLITE_OK!=(rc=openTransaction(pMain, p)) ){ return rc; } } } if( p->iMaxOff<(iOfst + iAmt) ){ p->iMaxOff = iOfst + iAmt; } } if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){ if( iAmt<p->nPagesize && p->nPagesize%iAmt==0 && iOfst>=(PENDING_BYTE+512) && iOfst+iAmt<=PENDING_BYTE+p->nPagesize ){ }else{ u32 pgno = iOfst/p->nPagesize + 1; assert( (iAmt==1||iAmt==p->nPagesize) && ((iOfst+iAmt)%p->nPagesize)==0 ); assert( pgno<=p->nPage || p->nSync>0 ); assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) ); } } rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){ jt_file *pMain = locateDatabaseHandle(p->zName); int rc2 = readJournalFile(p, pMain); if( rc==SQLITE_OK ) rc = rc2; } return rc; }
/* ** Truncate an jt-file. */ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){ jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){ /* Truncating a journal file. This is the end of a transaction. */ jt_file *pMain = locateDatabaseHandle(p->zName); closeTransaction(pMain); } if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){ u32 pgno; u32 locking_page = (u32)(PENDING_BYTE/p->nPagesize+1); for(pgno=size/p->nPagesize+1; pgno<=p->nPage; pgno++){ assert( pgno==locking_page || sqlite3BitvecTest(p->pWritable, pgno) ); } } return sqlite3OsTruncate(p->pReal, size); }
/* ** This function is called when a new transaction is opened, just after ** the first journal-header is written to the journal file. */ static int openTransaction(jt_file *pMain, jt_file *pJournal){ unsigned char *aData; sqlite3_file *p = pMain->pReal; int rc = SQLITE_OK; closeTransaction(pMain); aData = sqlite3_malloc(pMain->nPagesize); pMain->pWritable = sqlite3BitvecCreate(pMain->nPage); pMain->aCksum = sqlite3_malloc(sizeof(u32) * (pMain->nPage + 1)); pJournal->iMaxOff = 0; if( !pMain->pWritable || !pMain->aCksum || !aData ){ rc = SQLITE_IOERR_NOMEM; }else if( pMain->nPage>0 ){ u32 iTrunk; int iSave; int iSave2; stop_ioerr_simulation(&iSave, &iSave2); /* Read the database free-list. Add the page-number for each free-list ** leaf to the jt_file.pWritable bitvec. */ rc = sqlite3OsRead(p, aData, pMain->nPagesize, 0); if( rc==SQLITE_OK ){ u32 nDbsize = decodeUint32(&aData[28]); if( nDbsize>0 && memcmp(&aData[24], &aData[92], 4)==0 ){ u32 iPg; for(iPg=nDbsize+1; iPg<=pMain->nPage; iPg++){ sqlite3BitvecSet(pMain->pWritable, iPg); } } } iTrunk = decodeUint32(&aData[32]); while( rc==SQLITE_OK && iTrunk>0 ){ u32 nLeaf; u32 iLeaf; sqlite3_int64 iOff = (iTrunk-1)*pMain->nPagesize; rc = sqlite3OsRead(p, aData, pMain->nPagesize, iOff); nLeaf = decodeUint32(&aData[4]); for(iLeaf=0; rc==SQLITE_OK && iLeaf<nLeaf; iLeaf++){ u32 pgno = decodeUint32(&aData[8+4*iLeaf]); sqlite3BitvecSet(pMain->pWritable, pgno); } iTrunk = decodeUint32(aData); } /* Calculate and store a checksum for each page in the database file. */ if( rc==SQLITE_OK ){ int ii; for(ii=0; rc==SQLITE_OK && ii<pMain->nPage; ii++){ i64 iOff = (i64)(pMain->nPagesize) * (i64)ii; if( iOff==PENDING_BYTE ) continue; rc = sqlite3OsRead(pMain->pReal, aData, pMain->nPagesize, iOff); pMain->aCksum[ii] = genCksum(aData, pMain->nPagesize); } } start_ioerr_simulation(iSave, iSave2); } sqlite3_free(aData); return rc; }
int HugoTransactions::lockRecords(Ndb* pNdb, int records, int percentToLock, int lockTime){ // Place a lock on percentToLock% of the records in the Db // Keep the locks for lockTime ms, commit operation // and lock som other records int r = 0; int retryAttempt = 0; int check; NdbOperation::LockMode lm = NdbOperation::LM_Exclusive; // Calculate how many records to lock in each batch if (percentToLock <= 0) percentToLock = 1; double percentVal = (double)percentToLock / 100; int lockBatch = (int)(records * percentVal); if (lockBatch <= 0) lockBatch = 1; allocRows(lockBatch); while (r < records){ if(r + lockBatch > records) lockBatch = records - r; g_info << "|- Locking " << lockBatch << " records..." << endl; if (retryAttempt >= m_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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } if(pkReadRecord(pNdb, r, lockBatch, lm) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // NoCommit lockTime times with 100 millis interval int sleepInterval = 50; int lockCount = lockTime / sleepInterval; int commitCount = 0; do { 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; } for (int b=0; (b<lockBatch) && (r+b<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } } commitCount++; NdbSleep_MilliSleep(sleepInterval); } while (commitCount < lockCount); // Really commit the trans, puuh! check = pTrans->execute(Commit, 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; } else{ for (int b=0; (b<lockBatch) && (r<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } r++; // Read next record } } closeTransaction(pNdb); } deallocRows(); g_info << "|- Record locking completed" << endl; return NDBT_OK; }
int UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, const NdbDictionary::Index* pIndex, int parallelism, bool transactional){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; NDBT_ResultRow row(tab); parallelism = 1; 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) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { const NdbError err = pNdb->getNdbError(); closeTransaction(pNdb); ERR(err); if (err.status == NdbError::TemporaryError){ NdbSleep_MilliSleep(50); retryAttempt++; continue; } return NDBT_FAILED; } int rs; if(transactional){ rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism); } else { rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallelism); } if( rs != 0 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Read all attributes for (int 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; } int eof; int rows = 0; while((eof = pOp->nextResult()) == 0){ rows++; // ndbout << row.c_str().c_str() << endl; if (readRowFromTableAndIndex(pNdb, pTrans, pIndex, row) != NDBT_OK){ while((eof= pOp->nextResult(false)) == 0); if(eof == 2) eof = pOp->nextResult(true); // this should give -1 if(eof == -1) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; goto restart; } } closeTransaction(pNdb); return NDBT_FAILED; } } if (eof == -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; } closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; }
int UtilTransactions::selectCount(Ndb* pNdb, int parallelism, int* count_rows, NdbOperation::LockMode lm, NdbConnection* pTrans){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; if(!pTrans) pTrans = pNdb->startTransaction(); while (true){ if (retryAttempt >= retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pOp = getScanOperation(pTrans); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(lm) ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(0){ NdbScanFilter sf(pOp); sf.begin(NdbScanFilter::OR); sf.eq(2, (Uint32)30); sf.end(); } else { check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } check = pTrans->execute(NoCommit, AbortOnError); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } int eof; int rows = 0; while((eof = pOp->nextResult()) == 0){ rows++; } if (eof == -1) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); if (count_rows != NULL){ *count_rows = rows; } return NDBT_OK; } return NDBT_FAILED; }
int UtilTransactions::clearTable(Ndb* pNdb, NdbScanOperation::ScanFlag flags, int records, int parallelism){ // Scan all records exclusive and delete // them one by one int retryAttempt = 0; const int retryMax = 10; int deletedRows = 0; int check; 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 = getScanOperation(pTrans); if (pOp == NULL) { err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } if( pOp->readTuples(NdbOperation::LM_Exclusive, flags, par) ) { err = pTrans->getNdbError(); goto failed; } if(pTrans->execute(NoCommit, AbortOnError) != 0){ err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); 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){ check = pTrans->execute(Commit, AbortOnError); pTrans->restart(); } err = pTrans->getNdbError(); if(check == -1){ if(err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } } if(check == -1){ err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; failed: if(pTrans != 0) closeTransaction(pNdb); ERR(err); return (err.code != 0 ? err.code : NDBT_FAILED); }
int UtilTransactions::scanReadRecords(Ndb* pNdb, int parallelism, NdbOperation::LockMode lm, int records, int noAttribs, int *attrib_list, ReadCallBackFn* fn){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; NDBT_ResultRow row(tab); 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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = getScanOperation(pTrans); if (pOp == NULL) { const NdbError err = pNdb->getNdbError(); closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } if( pOp->readTuples(lm, 0, 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; } // Call getValue for all the attributes supplied in attrib_list // ************************************************ for (int a = 0; a < noAttribs; a++){ if (attrib_list[a] < tab.getNoOfColumns()){ g_info << "getValue(" << attrib_list[a] << ")" << endl; if ((row.attributeStore(attrib_list[a]) = pOp->getValue(tab.getColumn(attrib_list[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; } int eof; int rows = 0; while((eof = pOp->nextResult()) == 0){ rows++; // Call callback for each record returned if(fn != NULL) fn(&row); } if (eof == -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; } closeTransaction(pNdb); g_info << rows << " rows have been read" << endl; if (records != 0 && rows != records){ g_info << "Check expected number of records failed" << endl << " expected=" << records <<", " << endl << " read=" << rows << endl; return NDBT_FAILED; } return NDBT_OK; } return NDBT_FAILED; }
int HugoTransactions::loadTableStartFrom(Ndb* pNdb, int startFrom, int records, int batch, bool allowConstraintViolation, int doSleep, bool oneTrans, int value, bool abort){ int check; int retryAttempt = 0; int retryMax = 5; bool first_batch = true; const int org = batch; const int cols = tab.getNoOfColumns(); const int brow = tab.getRowSizeInBytes(); const int bytes = 12 + brow + 4 * cols; batch = (batch * 256); // -> 512 -> 65536k per commit batch = batch/bytes; // batch = batch == 0 ? 1 : batch; if(batch != org){ g_info << "batch = " << org << " rowsize = " << bytes << " -> rows/commit = " << batch << endl; } Uint32 orgbatch = batch; g_info << "|- Inserting records..." << endl; for (int c=0 ; c<records; ){ bool closeTrans = true; if(c + batch > records) batch = records - c; if (retryAttempt >= retryMax){ g_info << "Record " << c << " could not be inserted, has retried " << retryAttempt << " times " << endl; // Reset retry counters and continue with next record retryAttempt = 0; c++; } if (doSleep > 0) NdbSleep_MilliSleep(doSleep); // if (first_batch || !oneTrans) { if (first_batch || !pTrans) { first_batch = false; 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; } } if(pkInsertRecord(pNdb, c + startFrom, batch, value) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Execute the transaction and insert the record if (!oneTrans || (c + batch) >= records) { // closeTrans = true; closeTrans = false; if (!abort) { check = pTrans->execute(Commit, AbortOnError); if(check != -1) m_latest_gci = pTrans->getGCI(); pTrans->restart(); } else { check = pTrans->execute(NoCommit, AbortOnError); if (check != -1) { check = pTrans->execute( Rollback ); closeTransaction(pNdb); } } } else { closeTrans = false; check = pTrans->execute(NoCommit, AbortOnError); } if(check == -1 ) { const NdbError err = pTrans->getNdbError(); closeTransaction(pNdb); pTrans= 0; switch(err.status){ case NdbError::Success: ERR(err); g_info << "ERROR: NdbError reports success when transcaction failed" << endl; return NDBT_FAILED; break; case NdbError::TemporaryError: ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; batch = 1; continue; break; case NdbError::UnknownResult: ERR(err); return NDBT_FAILED; break; case NdbError::PermanentError: if (allowConstraintViolation == true){ switch (err.classification){ case NdbError::ConstraintViolation: // Tuple already existed, OK but should be reported g_info << c << ": " << err.code << " " << err.message << endl; c++; continue; break; default: break; } } ERR(err); return err.code; break; } } else{ if (closeTrans) { closeTransaction(pNdb); pTrans= 0; } } // Step to next record c = c+batch; retryAttempt = 0; } if(pTrans) closeTransaction(pNdb); return NDBT_OK; }
int UtilTransactions::compare(Ndb* pNdb, const char* tab_name2, int flags){ NdbError err; int return_code= 0, row_count= 0; int retryAttempt = 0, retryMax = 10; HugoCalculator calc(tab); NDBT_ResultRow row(tab); const NdbDictionary::Table* tmp= pNdb->getDictionary()->getTable(tab_name2); if(tmp == 0) { g_err << "Unable to lookup table: " << tab_name2 << endl << pNdb->getDictionary()->getNdbError() << endl; return -1; } const NdbDictionary::Table& tab2= *tmp; HugoOperations cmp(tab2); UtilTransactions count(tab2); while (true){ loop: if (retryAttempt++ >= retryMax){ g_err << "ERROR: compare has retried this operation " << retryAttempt << " times, failing!" << endl; return -1; } NdbScanOperation *pOp= 0; pTrans = pNdb->startTransaction(); if (pTrans == NULL) { err = pNdb->getNdbError(); goto error; } pOp= pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(err= pTrans->getNdbError()); goto error; } if( pOp->readTuples(NdbScanOperation::LM_Read) ) { ERR(err= pTrans->getNdbError()); goto error; } if( pOp->interpret_exit_ok() == -1 ) { ERR(err= pTrans->getNdbError()); goto error; } // Read all attributes { for (int a = 0; a < tab.getNoOfColumns(); a++){ if ((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(err= pTrans->getNdbError()); goto error; } } } if( pTrans->execute(NoCommit, AbortOnError) == -1 ) { ERR(err= pTrans->getNdbError()); goto error; } row_count= 0; { int eof; while((eof = pOp->nextResult(true)) == 0) { do { row_count++; if(cmp.startTransaction(pNdb) != NDBT_OK) { ERR(err= pNdb->getNdbError()); goto error; } int rowNo= calc.getIdValue(&row); if(cmp.pkReadRecord(pNdb, rowNo, 1) != NDBT_OK) { ERR(err= cmp.getTransaction()->getNdbError()); goto error; } if(cmp.execute_Commit(pNdb) != NDBT_OK || cmp.getTransaction()->getNdbError().code) { ERR(err= cmp.getTransaction()->getNdbError()); goto error; } if(row != cmp.get_row(0)) { g_err << "COMPARE FAILED" << endl; g_err << row << endl; g_err << cmp.get_row(0) << endl; return_code++; } retryAttempt= 0; cmp.closeTransaction(pNdb); } while((eof = pOp->nextResult(false)) == 0); } if (eof == -1) { err = pTrans->getNdbError(); goto error; } } closeTransaction(pNdb); g_info << row_count << " rows compared" << endl; { int row_count2; if(count.selectCount(pNdb, 0, &row_count2) != NDBT_OK) { g_err << "Failed to count rows in tab_name2" << endl; return -1; } g_info << row_count2 << " rows in tab_name2 - failed " << return_code << endl; return (row_count == row_count2 ? return_code : 1); } error: if(err.status == NdbError::TemporaryError) { g_err << err << endl; NdbSleep_MilliSleep(50); closeTransaction(pNdb); if(cmp.getTransaction()) cmp.closeTransaction(pNdb); goto loop; } g_err << "ERROR" << endl; g_err << err << endl; break; } close: closeTransaction(pNdb); return return_code; }
int HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, int records, int batch){ int updated = 0; int r = 0; int retryAttempt = 0; int check, a; while (r < records){ if (retryAttempt >= m_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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTupleExclusive(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Read update value for(a = 0; a<tab.getNoOfColumns(); a++){ if (calc.isUpdateCol(a) == true){ 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; } int updates = calc.getUpdatesValue(&row) + 1; NdbOperation* pUpdOp; pUpdOp = pTrans->getNdbOperation(tab.getName()); if (pUpdOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pUpdOp->interpretedUpdateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // PKs if (equalForRow(pUpdOp, r) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Update col for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == true)){ // TODO switch for 32/64 bit const NdbDictionary::Column* attr = tab.getColumn(a); Uint32 valToIncWith = 1; check = pUpdOp->incValue(attr->getName(), valToIncWith); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } // Remaining attributes for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == false)){ if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(Commit, 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); ndbout << "r = " << r << endl; closeTransaction(pNdb); return NDBT_FAILED; } else{ updated++; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); r++; // Read next record } g_info << "|- " << updated << " records updated" << endl; return NDBT_OK; }
int HugoTransactions::indexReadRecords(Ndb* pNdb, const char * idxName, int records, int batch){ int reads = 0; int r = 0; int retryAttempt = 0; int check, a; NdbOperation *pOp; NdbIndexScanOperation *sOp; const NdbDictionary::Index* pIndex = pNdb->getDictionary()->getIndex(idxName, tab.getName()); const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex); if (batch == 0) { g_info << "ERROR: Argument batch == 0 in indexReadRecords(). " << "Not allowed." << endl; return NDBT_FAILED; } if (ordered) { batch = 1; } allocRows(batch); while (r < records){ if (retryAttempt >= m_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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } for(int b=0; (b<batch) && (r+b < records); b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTuple(); } else { pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (sOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = sOp->readTuples(); } if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(Commit, AbortOnError); check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true)); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } switch(err.code){ case 626: // Tuple did not exist g_info << r << ": " << err.code << " " << err.message << endl; r++; break; default: ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } else{ for (int b=0; (b<batch) && (r+b<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } reads++; r++; } if(ordered && sOp->nextResult(true) == 0){ ndbout << "Error when comparing records " << " - index op next_result to many" << endl; closeTransaction(pNdb); return NDBT_FAILED; } } closeTransaction(pNdb); } deallocRows(); g_info << reads << " records read" << endl; return NDBT_OK; }
int HugoTransactions::indexUpdateRecords(Ndb* pNdb, const char * idxName, int records, int batch){ int updated = 0; int r = 0; int retryAttempt = 0; int check, a, b; NdbOperation *pOp; NdbScanOperation * sOp; const NdbDictionary::Index* pIndex = pNdb->getDictionary()->getIndex(idxName, tab.getName()); const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex); if (ordered){ batch = 1; } allocRows(batch); while (r < records){ if (retryAttempt >= m_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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } for(b = 0; b<batch && (b+r)<records; b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTupleExclusive(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } else { pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = 0; sOp->readTuplesExclusive(); } // Define primary keys if (equalForRow(pOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(NoCommit, AbortOnError); check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true)); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ NdbSleep_MilliSleep(50); retryAttempt++; continue; } return NDBT_FAILED; } if(ordered && check != 0){ g_err << check << " - Row: " << r << " not found!!" << endl; closeTransaction(pNdb); return NDBT_FAILED; } for(b = 0; b<batch && (b+r)<records; b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } int updates = calc.getUpdatesValue(rows[b]) + 1; NdbOperation* pUpdOp; if(!ordered){ pUpdOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); check = (pUpdOp == 0 ? -1 : pUpdOp->updateTuple()); } else { pUpdOp = sOp->updateCurrentTuple(); } if (pUpdOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(!ordered) { if (equalForRow(pUpdOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } } for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){ ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } } check = pTrans->execute(Commit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ NdbSleep_MilliSleep(50); retryAttempt++; continue; } ndbout << "r = " << r << endl; return NDBT_FAILED; } else { updated += batch; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); r+= batch; // Read next record } g_info << "|- " << updated << " records updated" << endl; return NDBT_OK; }
int HugoTransactions::pkUpdateRecords(Ndb* pNdb, int records, int batch, int doSleep){ int updated = 0; int r = 0; int retryAttempt = 0; int check, b; allocRows(batch); g_info << "|- Updating records (batch=" << batch << ")..." << endl; int batch_no = 0; while (r < records){ if(r + batch > records) batch = records - r; if (m_thr_count != 0 && m_thr_no != batch_no % m_thr_count) { r += batch; batch_no++; continue; } if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } if (doSleep > 0) NdbSleep_MilliSleep(doSleep); 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; } if(pkReadRecord(pNdb, r, batch, NdbOperation::LM_Exclusive) != NDBT_OK) { 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; } MicroSecondTimer timer_start; MicroSecondTimer timer_stop; bool timer_active = m_stats_latency != 0 && r >= batch && // first batch is "warmup" r + batch != records; // last batch is usually partial if (timer_active) NdbTick_getMicroTimer(&timer_start); if(pIndexScanOp) { int rows_found = 0; while((check = pIndexScanOp->nextResult(true)) == 0) { do { if (calc.verifyRowValues(rows[0]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } int updates = calc.getUpdatesValue(rows[0]) + 1; if(pkUpdateRecord(pNdb, r+rows_found, 1, updates) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } rows_found++; } while((check = pIndexScanOp->nextResult(false)) == 0); if(check != 2) break; if((check = pTrans->execute(NoCommit, AbortOnError)) != 0) break; } if(check != 1 || rows_found != batch) { closeTransaction(pNdb); return NDBT_FAILED; } } else { for(b = 0; b<batch && (b+r)<records; b++) { if (calc.verifyRowValues(rows[b]) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } int updates = calc.getUpdatesValue(rows[b]) + 1; if(pkUpdateRecord(pNdb, r+b, 1, updates) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } check = pTrans->execute(Commit, 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); ndbout << "r = " << r << endl; closeTransaction(pNdb); return NDBT_FAILED; } else{ updated += batch; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); if (timer_active) { NdbTick_getMicroTimer(&timer_stop); NDB_TICKS ticks = NdbTick_getMicrosPassed(timer_start, timer_stop); m_stats_latency->addObservation((double)ticks); } r += batch; // Read next record batch_no++; } deallocRows(); g_info << "|- " << updated << " records updated" << endl; return NDBT_OK; }
int HugoTransactions::pkReadRecords(Ndb* pNdb, int records, int batch, NdbOperation::LockMode lm){ int reads = 0; int r = 0; int retryAttempt = 0; int check; if (batch == 0) { g_info << "ERROR: Argument batch == 0 in pkReadRecords(). Not allowed." << endl; return NDBT_FAILED; } while (r < records){ if(r + batch > records) batch = records - r; if (retryAttempt >= m_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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } MicroSecondTimer timer_start; MicroSecondTimer timer_stop; bool timer_active = m_stats_latency != 0 && r >= batch && // first batch is "warmup" r + batch != records; // last batch is usually partial if (timer_active) NdbTick_getMicroTimer(&timer_start); if(pkReadRecord(pNdb, r, batch, lm) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pTrans->execute(Commit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } switch(err.code){ case 626: // Tuple did not exist g_info << r << ": " << err.code << " " << err.message << endl; r++; break; default: ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } else { if(pIndexScanOp) { int rows_found = 0; while((check = pIndexScanOp->nextResult()) == 0) { rows_found++; if (calc.verifyRowValues(rows[0]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } } if(check != 1 || rows_found > batch) { closeTransaction(pNdb); return NDBT_FAILED; } else if(rows_found < batch) { if(batch == 1){ g_info << r << ": not found" << endl; abort(); } else g_info << "Found " << rows_found << " of " << batch << " rows" << endl; } r += batch; reads += rows_found; } else { for (int b=0; (b<batch) && (r+b<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } reads++; r++; } } } closeTransaction(pNdb); if (timer_active) { NdbTick_getMicroTimer(&timer_stop); NDB_TICKS ticks = NdbTick_getMicrosPassed(timer_start, timer_stop); m_stats_latency->addObservation((double)ticks); } } deallocRows(); g_info << reads << " records read" << endl; return NDBT_OK; }
int HugoTransactions::fillTableStartFrom(Ndb* pNdb, int startFrom, int batch){ int check; int retryAttempt = 0; int retryMax = 5; const int org = batch; const int cols = tab.getNoOfColumns(); const int brow = tab.getRowSizeInBytes(); const int bytes = 12 + brow + 4 * cols; batch = (batch * 256); // -> 512 -> 65536k per commit batch = batch/bytes; // batch = batch == 0 ? 1 : batch; if(batch != org){ g_info << "batch = " << org << " rowsize = " << bytes << " -> rows/commit = " << batch << endl; } for (int c=startFrom ; ; ){ if (retryAttempt >= retryMax){ g_info << "Record " << c << " could not be inserted, has retried " << retryAttempt << " times " << endl; // Reset retry counters and continue with next record retryAttempt = 0; c++; } 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; } if(pkInsertRecord(pNdb, c, batch) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Execute the transaction and insert the record check = pTrans->execute(Commit, CommitAsMuchAsPossible); if(check == -1 ) { const NdbError err = pTrans->getNdbError(); closeTransaction(pNdb); switch(err.status){ case NdbError::Success: ERR(err); g_info << "ERROR: NdbError reports success when transcaction failed" << endl; return NDBT_FAILED; break; case NdbError::TemporaryError: ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; break; case NdbError::UnknownResult: ERR(err); return NDBT_FAILED; break; case NdbError::PermanentError: // if (allowConstraintViolation == true){ // switch (err.classification){ // case NdbError::ConstraintViolation: // // Tuple already existed, OK but should be reported // g_info << c << ": " << err.code << " " << err.message << endl; // c++; // continue; // break; // default: // break;es // } // } // Check if this is the "db full" error if (err.classification==NdbError::InsufficientSpace){ ERR(err); return NDBT_OK; } if (err.classification == NdbError::ConstraintViolation){ ERR(err); break; } ERR(err); return NDBT_FAILED; break; } } else{ m_latest_gci = pTrans->getGCI(); closeTransaction(pNdb); } // Step to next record c = c+batch; retryAttempt = 0; } return NDBT_OK; }
int HugoTransactions::pkDelRecords(Ndb* pNdb, int records, int batch, bool allowConstraintViolation, int doSleep){ // TODO Batch is not implemented int deleted = 0; int r = 0; int retryAttempt = 0; int check; g_info << "|- Deleting records..." << endl; int batch_no = 0; while (r < records){ if(r + batch > records) batch = records - r; if (m_thr_count != 0 && m_thr_no != batch_no % m_thr_count) { r += batch; batch_no++; continue; } if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } if (doSleep > 0) NdbSleep_MilliSleep(doSleep); 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; } MicroSecondTimer timer_start; MicroSecondTimer timer_stop; bool timer_active = m_stats_latency != 0 && r >= batch && // first batch is "warmup" r + batch != records; // last batch is usually partial if (timer_active) NdbTick_getMicroTimer(&timer_start); if(pkDeleteRecord(pNdb, r, batch) != NDBT_OK) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pTrans->execute(Commit, AbortOnError); if( check == -1) { const NdbError err = pTrans->getNdbError(); switch(err.status){ case NdbError::TemporaryError: ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; break; case NdbError::PermanentError: if (allowConstraintViolation == true){ switch (err.classification){ case NdbError::ConstraintViolation: // Tuple did not exist, OK but should be reported g_info << r << ": " << err.code << " " << err.message << endl; continue; break; default: break; } } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; break; default: ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } else { deleted += batch; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); if (timer_active) { NdbTick_getMicroTimer(&timer_stop); NDB_TICKS ticks = NdbTick_getMicrosPassed(timer_start, timer_stop); m_stats_latency->addObservation((double)ticks); } r += batch; // Read next record batch_no++; } g_info << "|- " << deleted << " records deleted" << endl; return NDBT_OK; }
int UtilTransactions::copyTableData(Ndb* pNdb, const char* destName){ // Scan all records and copy // them to destName table int retryAttempt = 0; const int retryMax = 10; int insertedRows = 0; int parallelism = 240; int check; NdbScanOperation *pOp; NDBT_ResultRow row(tab); 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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 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; } // Read all attributes for (int 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 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } int eof; while((eof = pOp->nextResult(true)) == 0){ do { insertedRows++; if (addRowToInsert(pNdb, pTrans, row, destName) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } } while((eof = pOp->nextResult(false)) == 0); check = pTrans->execute(Commit, AbortOnError); pTrans->restart(); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } if (eof == -1) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); // If error = 488 there should be no limit on number of retry attempts if (err.code != 488) retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); g_info << insertedRows << " rows copied" << endl; return NDBT_OK; } return NDBT_FAILED; }
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; }
extern "C" void* NdbThreadFuncRead(void* pArg) { myRandom48Init((long int)NdbTick_CurrentMillisecond()); unsigned nSucc = 0; unsigned nFail = 0; NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse]; NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse]; Ndb* pNdb = NULL ; pNdb = new Ndb("TEST_DB"); VerifyMethodInt(pNdb, init()); VerifyMethodInt(pNdb, waitUntilReady()); while(NdbMutex_Trylock(g_pNdbMutex)) { Uint32 nWarehouse = myRandom48(g_nWarehouseCount); NdbConnection* pNdbConnection = NULL ; VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); CHK_TR(pNdbConnection) ; // epaulsa NdbOperation* pNdbOperationW = NULL ; VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); VerifyMethodInt(pNdbOperationW, readTuple()); VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); NdbRecAttr* pNdbRecAttrWSum; VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0)); NdbRecAttr* pNdbRecAttrWCnt; VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0)); for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) { NdbOperation* pNdbOperationD = NULL ; VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict)); VerifyMethodInt(pNdbOperationD, readTuple()); VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse)); VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict)); VerifyMethodPtr(ppNdbRecAttrDSum[nDistrict], pNdbOperationD, getValue(c_szDistrictSum, 0)); VerifyMethodPtr(ppNdbRecAttrDCnt[nDistrict], pNdbOperationD, getValue(c_szDistrictCount, 0)); } int iExec = pNdbConnection->execute(Commit); int iError = pNdbConnection->getNdbError().code; if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); } if(iExec==0) { Uint32 nSum = 0; Uint32 nCnt = 0; for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) { nSum += ppNdbRecAttrDSum[nDistrict]->u_32_value(); nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value(); } if(nSum!=pNdbRecAttrWSum->u_32_value() || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) { ndbout << "INCONSISTENT!" << endl; ndbout << "iExec==" << iExec << endl; ndbout << "iError==" << iError << endl; ndbout << endl; ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", "; ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl; ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl; for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) { ndbout << c_szDistrictSum << "[" << nDistrict << "]==" << ppNdbRecAttrDSum[nDistrict]->u_32_value() << ", "; ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl; } VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); delete pNdb; pNdb = NULL ; delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; NDBT_ProgramExit(NDBT_FAILED); } ++nSucc; } else { ++nFail; } VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); } ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl; NdbMutex_Unlock(g_pNdbMutex); delete pNdb; pNdb = NULL ; delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; return NULL; }
int UtilTransactions::verifyOrderedIndex(Ndb* pNdb, const NdbDictionary::Index* pIndex, int parallelism, bool transactional){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; NdbIndexScanOperation * iop = 0; NDBT_ResultRow scanRow(tab); NDBT_ResultRow pkRow(tab); NDBT_ResultRow indexRow(tab); const char * indexName = pIndex->getName(); int res; parallelism = 1; 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){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 0, 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; } if(get_values(pOp, scanRow)) { abort(); } 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; } int eof; int rows = 0; while(check == 0 && (eof = pOp->nextResult()) == 0){ rows++; bool null_found= false; for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); if (scanRow.attributeStore(col->getName())->isNULL()) { null_found= true; break; } } // Do pk lookup NdbOperation * pk = pTrans->getNdbOperation(tab.getName()); if(!pk || pk->readTuple()) goto error; if(equal(&tab, pk, scanRow) || get_values(pk, pkRow)) goto error; if(!null_found) { if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName, tab.getName()))) { if(iop->readTuples(NdbScanOperation::LM_CommittedRead, parallelism)) goto error; iop->interpret_exit_ok(); if(get_values(iop, indexRow)) goto error; } else if(!iop || iop->reset_bounds()) { goto error; } if(equal(pIndex, iop, scanRow)) goto error; } check = pTrans->execute(NoCommit, AbortOnError); if(check) goto error; if(scanRow.c_str() != pkRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(!null_found) { if((res= iop->nextResult()) != 0){ g_err << "Failed to find row using index: " << res << endl; ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(scanRow.c_str() != indexRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(iop->nextResult() == 0){ g_err << "Found extra row!!" << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } } } if (eof == -1 || check == -1) { error: const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); iop = 0; closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; rows--; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; }