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); }
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; }
// // 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; }
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; }
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++; }
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; }
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; }
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); }
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; }
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; }
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; }
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++; }
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; }
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(); }
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++; }
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; }