void TableTailer::recover(int recoverFromId) { const NdbDictionary::Dictionary* database = getDatabase(mNdbConnection); const NdbDictionary::Index* index = getIndex(database, mTable.mTableName, mTable.mRecoveryIndex); NdbTransaction* transaction = startNdbTransaction(mNdbConnection); NdbIndexScanOperation* scanOp = getNdbIndexScanOperation(transaction, index); scanOp->readTuples(NdbOperation::LM_CommittedRead, NdbScanOperation::SF_OrderBy); scanOp->setBound(mTable.mRecoveryColumn.c_str(), NdbIndexScanOperation::BoundLT, (char*) & recoverFromId); NdbRecAttr * row[mTable.mNoColumns]; for (int i = 0; i < mTable.mNoColumns; i++) { row[i] = scanOp->getValue(mTable.mColumnNames[i].c_str()); } executeTransaction(transaction, NdbTransaction::Commit); while (scanOp->nextResult(true) == 0) { handleEvent(NdbDictionary::Event::TE_INSERT, NULL, row); } transaction->close(); }
int run_read() { int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; const Uint32 rows = g_paramters[P_ROWS].value; const Uint32 range = g_paramters[P_RANGE].value; start1 = NdbTick_CurrentMillisecond(); NdbConnection * pTrans = g_ndb->startTransaction(); if(!pTrans) { g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } NdbOperation * pOp; NdbScanOperation * pSp; NdbIndexOperation * pUp; NdbIndexScanOperation * pIp; Uint32 start_row = rand() % (rows - range); Uint32 stop_row = start_row + range; /** * 0 - serial pk * 1 - batch pk * 2 - serial uniq * 3 - batch uniq * 4 - index eq * 5 - range scan * 6 - interpreted scan */ int check = 0; void* res = (void*)~0; const Uint32 pk = 0; Uint32 cnt = 0; for(; start_row < stop_row; start_row++) { switch(g_paramters[P_OPER].value) { case 0: pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 1: for(; start_row<stop_row; start_row++) { pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } } break; case 2: pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 3: for(; start_row<stop_row; start_row++) { pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } } break; case 4: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row); break; case 5: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 6: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 7: pOp = pSp = pTrans->getNdbScanOperation(g_table); pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); NdbScanFilter filter(pOp) ; filter.begin(NdbScanFilter::AND); filter.ge(pk, start_row); filter.lt(pk, stop_row); filter.end(); start_row = stop_row; break; } assert(res); if(check != 0) { ndbout << pOp->getNdbError() << endl; ndbout << pTrans->getNdbError() << endl; } assert(check == 0); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } check = pTrans->execute(NoCommit); if(check != 0) { ndbout << pTrans->getNdbError() << endl; } assert(check == 0); if(g_paramters[P_OPER].value >= 4) { while((check = pSp->nextResult(true)) == 0) { cnt++; } if(check == -1) { err(pTrans->getNdbError()); return -1; } assert(check == 1); pSp->close(); } } assert(g_paramters[P_OPER].value < 4 || (cnt == range)); pTrans->close(); stop = NdbTick_CurrentMillisecond(); g_times[g_paramters[P_OPER].value] += (stop - start1); return 0; }
int run_scan(){ int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; int sample_rows = 0; int tot_rows = 0; NDB_TICKS sample_start = NdbTick_CurrentMillisecond(); Uint32 tot = g_paramters[P_ROWS].value; if(g_paramters[P_BOUND].value >= 2 || g_paramters[P_FILT].value == 2) iter *= g_paramters[P_ROWS].value; NdbScanOperation * pOp = 0; NdbIndexScanOperation * pIOp = 0; NdbConnection * pTrans = 0; int check = 0; for(int i = 0; i<iter; i++){ start1 = NdbTick_CurrentMillisecond(); pTrans = pTrans ? pTrans : g_ndb->startTransaction(); if(!pTrans){ g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } int par = g_paramters[P_PARRA].value; int bat = 0; // g_paramters[P_BATCH].value; NdbScanOperation::LockMode lm; switch(g_paramters[P_LOCK].value){ case 0: lm = NdbScanOperation::LM_CommittedRead; break; case 1: lm = NdbScanOperation::LM_Read; break; case 2: lm = NdbScanOperation::LM_Exclusive; break; default: abort(); } if(g_paramters[P_ACCESS].value == 0){ pOp = pTrans->getNdbScanOperation(g_tablename); assert(pOp); pOp->readTuples(lm, bat, par); } else { if(g_paramters[P_RESET].value == 0 || pIOp == 0) { pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename); bool ord = g_paramters[P_ACCESS].value == 2; pIOp->readTuples(lm, bat, par, ord); } else { pIOp->reset_bounds(); } switch(g_paramters[P_BOUND].value){ case 0: // All break; case 1: // None pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0); break; case 2: { // 1 row default: assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far int tot = g_paramters[P_ROWS].value; int row = rand() % tot; #if 0 fix_eq_bound(pIOp, row); #else pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row); #endif if(g_paramters[P_RESET].value == 2) goto execute; break; } case 3: { // read multi int multi = g_paramters[P_MULTI].value; int tot = g_paramters[P_ROWS].value; for(; multi > 0 && i < iter; --multi, i++) { int row = rand() % tot; pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row); pIOp->end_of_bound(i); } if(g_paramters[P_RESET].value == 2) goto execute; break; } } } assert(pOp); switch(g_paramters[P_FILT].value){ case 0: // All check = pOp->interpret_exit_ok(); break; case 1: // None check = pOp->interpret_exit_nok(); break; case 2: { // 1 row default: assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far abort(); #if 0 int tot = g_paramters[P_ROWS].value; int row = rand() % tot; NdbScanFilter filter(pOp) ; filter.begin(NdbScanFilter::AND); fix_eq(filter, pOp, row); filter.end(); break; #endif } } if(check != 0){ err(pOp->getNdbError()); return -1; } assert(check == 0); if(g_paramters[P_RESET].value == 1) g_paramters[P_RESET].value = 2; for(int i = 0; i<g_table->getNoOfColumns(); i++){ pOp->getValue(i); } if(g_paramters[P_RESET].value == 1) g_paramters[P_RESET].value = 2; execute: int rows = 0; check = pTrans->execute(NoCommit); assert(check == 0); int fetch = g_paramters[P_FETCH].value; while((check = pOp->nextResult(true)) == 0){ do { rows++; } while(!fetch && ((check = pOp->nextResult(false)) == 0)); if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 2); } if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 1); if(g_paramters[P_RESET].value == 0) { pTrans->close(); pTrans = 0; } stop = NdbTick_CurrentMillisecond(); int time_passed= (int)(stop - start1); sample_rows += rows; sum_time+= time_passed; tot_rows+= rows; if(sample_rows >= tot) { int sample_time = (int)(stop - sample_start); g_info << "Found " << sample_rows << " rows" << endl; g_err.println("Time: %d ms = %u rows/sec", sample_time, (1000*sample_rows)/sample_time); sample_rows = 0; sample_start = stop; } } g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows, (1000*tot_rows)/sum_time); return 0; }