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; }
/* Producer thread */ int runV2MultiWait_Producer(NDBT_Context* ctx, NDBT_Step* step, int thd_id, int nthreads) { int records = ctx->getNumRecords(); HugoOperations hugoOps(*ctx->getTab()); /* For three threads (2 producers + 1 consumer) we loop 0-7. producer 0 is slow if (loop & 1) producer 1 is slow if (loop & 2) consumer is slow if (loop & 4) */ for (int loop = 0; loop < V2_NLOOPS; loop++) { ctx->getPropertyWait("LOOP", loop+1); bool slow = loop & (thd_id+1); for (int j=0; j < records; j++) { if(j % nthreads == thd_id) { Ndb* ndb = global_ndb_pool->getNdb(); NdbTransaction* trans = ndb->startTransaction(); check(trans != NULL, (*ndb)); ndb->setCustomData(trans); NdbOperation* readOp = trans->getNdbOperation(ctx->getTab()); check(readOp != NULL, (*trans)); check(readOp->readTuple() == 0, (*readOp)); check(hugoOps.equalForRow(readOp, j) == 0, hugoOps); /* Read all other cols */ for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++) { check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL, (*readOp)); } trans->executeAsynchPrepare(NdbTransaction::Commit, NULL, NULL, NdbOperation::AbortOnError); ndb->sendPreparedTransactions(); global_poll_group->push(ndb); if(slow) { int tm = myRandom48(3) * myRandom48(3); if(tm) NdbSleep_MilliSleep(tm); } } } } return NDBT_OK; }
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 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++; }
void BackupRestore::tuple(const TupleS & tup) { if (!m_restore) return; while (1) { NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // TODO: handle the error ndbout << "Cannot start transaction" << endl; exit(-1); } // if const TableS * table = tup.getTable(); NdbOperation * op = trans->getNdbOperation(table->getTableName()); if (op == NULL) { ndbout << "Cannot get operation: "; ndbout << trans->getNdbError() << endl; exit(-1); } // if // TODO: check return value and handle error if (op->writeTuple() == -1) { ndbout << "writeTuple call failed: "; ndbout << trans->getNdbError() << endl; exit(-1); } // if for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeS * attr = tup[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; const char * dataPtr = attr->Data.string_value; const Uint32 length = (size * arraySize) / 8; if (attr->Desc->m_column->getPrimaryKey()) op->equal(i, dataPtr, length); } for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeS * attr = tup[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; const char * dataPtr = attr->Data.string_value; const Uint32 length = (size * arraySize) / 8; if (!attr->Desc->m_column->getPrimaryKey()) if (attr->Data.null) op->setValue(i, NULL, 0); else op->setValue(i, dataPtr, length); } int ret = trans->execute(Commit); if (ret != 0) { ndbout << "execute failed: "; ndbout << trans->getNdbError() << endl; exit(-1); } m_ndb->closeTransaction(trans); if (ret == 0) break; } m_dataCount++; }
int runPkReadMultiBasic(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); const int MAX_NDBS = 200; Ndb* pNdb = GETNDB(step); Ndb_cluster_connection* conn = &pNdb->get_ndb_cluster_connection(); int i = 0; HugoOperations hugoOps(*ctx->getTab()); Ndb* ndbObjs[ MAX_NDBS ]; NdbTransaction* transArray[ MAX_NDBS ]; Ndb ** ready_ndbs; for (int j=0; j < MAX_NDBS; j++) { Ndb* ndb = new Ndb(conn); check(ndb->init() == 0, (*ndb)); ndbObjs[ j ] = ndb; } while (i<loops) { ndbout << "Loop : " << i << ": "; int recordsLeft = records; do { /* Define and execute Pk read requests on * different Ndb objects */ int ndbcnt = 0; int pollcnt = 0; int lumpsize = 1 + myRandom48(MIN(recordsLeft, MAX_NDBS)); while(lumpsize && recordsLeft && ndbcnt < MAX_NDBS) { Ndb* ndb = ndbObjs[ ndbcnt ]; NdbTransaction* trans = ndb->startTransaction(); check(trans != NULL, (*ndb)); NdbOperation* readOp = trans->getNdbOperation(ctx->getTab()); check(readOp != NULL, (*trans)); check(readOp->readTuple() == 0, (*readOp)); check(hugoOps.equalForRow(readOp, recordsLeft) == 0, hugoOps); /* Read all other cols */ for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++) { check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL, (*readOp)); } /* Now send em off */ trans->executeAsynchPrepare(NdbTransaction::Commit, NULL, NULL, NdbOperation::AbortOnError); ndb->sendPreparedTransactions(); transArray[ndbcnt] = trans; global_poll_group->addNdb(ndb); ndbcnt++; pollcnt++; recordsLeft--; lumpsize--; }; /* Ok, now wait for the Ndbs to complete */ while (pollcnt) { /* Occasionally check with no timeout */ Uint32 timeout_millis = myRandom48(2)?10000:0; int count = global_poll_group->wait(ready_ndbs, timeout_millis); if (count > 0) { for (int y=0; y < count; y++) { Ndb *ndb = ready_ndbs[y]; check(ndb->pollNdb(0, 1) != 0, (*ndb)); } pollcnt -= count; } } /* Ok, now close the transactions */ for (int t=0; t < ndbcnt; t++) { transArray[t]->close(); } } while (recordsLeft); i++; } for (int j=0; j < MAX_NDBS; j++) { delete ndbObjs[ j ]; } return NDBT_OK; }
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; }