int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); Ndb* pNdb = GETNDB(step); UtilTransactions utilTrans(*ctx->getTab()); NdbRestarter restarter; // Wait until we have enough records in db int count = 0; while (count < records){ if (utilTrans.selectCount(pNdb, 64, &count) != 0){ ctx->stopTest(); return NDBT_FAILED; } } // Restart cluster with abort if (restarter.restartAll(false, false, true) != 0){ ctx->stopTest(); return NDBT_FAILED; } // Stop the other thread ctx->stopTest(); if (restarter.waitClusterStarted(300) != 0){ return NDBT_FAILED; } if (pNdb->waitUntilReady() != 0){ return NDBT_FAILED; } return NDBT_OK; }
int runVerifyOne(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); Ndb* pNdb = GETNDB(step); int result = NDBT_OK; int count = 0; const NdbDictionary::Table* tab = GETNDB(step)->getDictionary()->getTable(ctx->getTab()->getName()); if(tab == 0) return NDBT_FAILED; UtilTransactions utilTrans(* tab); HugoTransactions hugoTrans(* tab); do{ // Check that there are as many records as we expected CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); g_err << "count = " << count; g_err << " records = " << records; g_err << endl; CHECK(count == records); // Read and verify every record CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); } while (false); return result; }
int main(int argc, const char** argv){ ndb_init(); int _parallelism = 240; const char* _tabname = NULL; const char* _indexname = NULL; int _help = 0; struct getargs args[] = { { "parallelism", 's', arg_integer, &_parallelism, "parallelism", "parallelism" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; char desc[] = "tabname indexname\n"\ "This program will verify the index [indexname] and compare it to data\n" "in table [tablename]\n"; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || argv[optind+1] == NULL || _help) { arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } _tabname = argv[optind]; _indexname = argv[optind+1]; // Connect to Ndb Ndb_cluster_connection con; if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb(&con, "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(MyNdb.waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; // Check if table exists in db const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); if(pTab == NULL){ ndbout << " Table " << _tabname << " does not exist!" << endl; return NDBT_ProgramExit(NDBT_FAILED); } int rows = 0; UtilTransactions utilTrans(*pTab); if (utilTrans.verifyIndex(&MyNdb, _indexname, _parallelism) != 0){ return NDBT_ProgramExit(NDBT_FAILED); } return NDBT_ProgramExit(NDBT_OK); }
int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); UtilTransactions utilTrans(*ctx->getTab()); if (utilTrans.clearTable2(GETNDB(step), records) != 0){ return NDBT_FAILED; } return NDBT_OK; }
int runClearTable(NDBT_Context* ctx, NDBT_Step* step) { UtilTransactions utilTrans(*ctx->getTab()); if (utilTrans.clearTable(GETNDB(step)) != 0){ return NDBT_FAILED; } return NDBT_OK; }
int runVerifyUndoData(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); Ndb* pNdb = GETNDB(step); int count = 0; int num = 5; if (records - 5 < 0) num = 1; const NdbDictionary::Table* tab = GETNDB(step)->getDictionary()->getTable(ctx->getTab()->getName()); if(tab == 0) { g_err << " Can't find table" << endl; return NDBT_FAILED; } UtilTransactions utilTrans(* tab); HugoTransactions hugoTrans(* tab); // Check that there are as many records as we expected if(utilTrans.selectCount(pNdb, 64, &count) != 0) { g_err << "Can't get records count" << endl; return NDBT_FAILED; } g_err << "count = " << count; g_err << " records = " << records; g_err << endl; if (count != records) { g_err << "The records count is not correct" << endl; return NDBT_FAILED; } // make sure all the update data is there NdbTransaction *pTransaction= pNdb->startTransaction(); if (pTransaction == NULL) { g_err << "Can't get transaction pointer" << endl; return NDBT_FAILED; } if(hugoTrans.setTransaction(pTransaction) != 0) { g_err << "Set transaction error" << endl; pNdb->closeTransaction(pTransaction); return NDBT_FAILED; } if(hugoTrans.pkReadRecord(pNdb, 0, records, NdbOperation::LM_Read) != 0) { g_err << "Can't read record" << endl; return NDBT_FAILED; } if(hugoTrans.verifyUpdatesValue(0, records) != 0) { g_err << "The records restored with undo log is not correct" << endl; return NDBT_FAILED; } hugoTrans.closeTransaction(pNdb); return NDBT_OK; }
int clear_table() { if(!g_paramters[P_LOAD].value) return 0; int rows = g_paramters[P_ROWS].value; UtilTransactions utilTrans(* g_tab); if (utilTrans.clearTable(g_ndb, rows) != 0) { g_err.println("Failed to clear table %s", g_tab->getName()); return -1; } return 0; }
int runClearTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); int i = 0; UtilTransactions utilTrans(*ctx->getTab()); while (ctx->isTestStopped() == false) { g_info << i << ": "; if (utilTrans.clearTable(GETNDB(step), records) != 0){ return NDBT_FAILED; } i++; } return NDBT_OK; }
int runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); Ndb* pNdb = GETNDB(step); NdbRestarter restarter; char tabName[255]; strncpy(tabName, ctx->getTab()->getName(), 255); ndbout << "tabName="<<tabName<<endl; int i = 0; int count; HugoTransactions hugoTrans(*ctx->getTab()); UtilTransactions utilTrans(*ctx->getTab()); while (i<loops && result == NDBT_OK) { g_info << i << ": "; int timeout = 120; // Test that the single user mode api can do everything CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); CHECK(restarter.waitClusterSingleUser(timeout) == 0); CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == records); CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == (records/2)); CHECK(utilTrans.clearTable(pNdb, records/2) == 0); CHECK(restarter.exitSingleUserMode() == 0); CHECK(restarter.waitClusterStarted(timeout) == 0); // Test create index in single user mode CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); CHECK(restarter.waitClusterSingleUser(timeout) == 0); CHECK(create_index_on_pk(pNdb, tabName) == 0); CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == records); CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); CHECK(drop_index_on_pk(pNdb, tabName) == 0); CHECK(restarter.exitSingleUserMode() == 0); CHECK(restarter.waitClusterStarted(timeout) == 0); // Test recreate index in single user mode CHECK(create_index_on_pk(pNdb, tabName) == 0); CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); CHECK(restarter.waitClusterSingleUser(timeout) == 0); CHECK(drop_index_on_pk(pNdb, tabName) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(create_index_on_pk(pNdb, tabName) == 0); CHECK(restarter.exitSingleUserMode() == 0); CHECK(restarter.waitClusterStarted(timeout) == 0); CHECK(drop_index_on_pk(pNdb, tabName) == 0); CHECK(utilTrans.clearTable(GETNDB(step), records) == 0); ndbout << "Restarting cluster" << endl; CHECK(restarter.restartAll() == 0); CHECK(restarter.waitClusterStarted(timeout) == 0); CHECK(pNdb->waitUntilReady(timeout) == 0); i++; } return result; }
inline int ScanInterpretTest::scanReadVerify(Ndb* pNdb, int records, int parallelism, ScanFilter& filter){ int retryAttempt = 0; const int retryMax = 100; int check; NdbConnection *pTrans; NdbScanOperation *pOp; while (true){ if (retryAttempt >= retryMax){ ndbout << "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) { if (pOp->getValue("KOL2") == 0){ ERR(pNdb->getNdbError()); return NDBT_FAILED; } ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if (check == -1) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); 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()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } } check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } int eof; int rows = 0; int rowsNoExist = 0; int rowsExist = 0; int existingRecordsNotFound = 0; int nonExistingRecordsFound = 0; NdbConnection* pExistTrans; NdbConnection* pNoExistTrans; while((eof = pOp->nextResult(true)) == 0){ pExistTrans = pNdb->startTransaction(); if (pExistTrans == NULL) { const NdbError err = pNdb->getNdbError(); ERR(err); return NDBT_FAILED; } pNoExistTrans = pNdb->startTransaction(); if (pNoExistTrans == NULL) { const NdbError err = pNdb->getNdbError(); ERR(err); return NDBT_FAILED; } do { rows++; if (filter.verifyRecord(row) == NDBT_OK){ rowsExist++; if (addRowToCheckTrans(pNdb, pExistTrans) != 0){ pNdb->closeTransaction(pTrans); pNdb->closeTransaction(pExistTrans); pNdb->closeTransaction(pNoExistTrans); return NDBT_FAILED; } }else{ rowsNoExist++; if (addRowToCheckTrans(pNdb, pNoExistTrans) != 0){ pNdb->closeTransaction(pTrans); pNdb->closeTransaction(pExistTrans); pNdb->closeTransaction(pNoExistTrans); return NDBT_FAILED; } } } while((eof = pOp->nextResult(false)) == 0); // Execute the transaction containing reads of // all the records that should be in the result table check = pExistTrans->execute(Commit); if( check == -1 ) { const NdbError err = pExistTrans->getNdbError(); ERR(err); if (err.code != 626){ pNdb->closeTransaction(pExistTrans); pNdb->closeTransaction(pNoExistTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; }else{ // Some of the records expected to be found wasn't // there existingRecordsNotFound = 1; } } pNdb->closeTransaction(pExistTrans); // Execute the transaction containing reads of // all the records that should NOT be in the result table check = pNoExistTrans->execute(Commit, CommitAsMuchAsPossible); if( check == -1 ) { const NdbError err = pNoExistTrans->getNdbError(); // The transactions error code should be zero if (err.code != 626){ ERR(err); pNdb->closeTransaction(pNoExistTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } // Loop through the no existing transaction and check that no // operations where successful const NdbOperation* pOp2 = NULL; while ((pOp2 = pNoExistTrans->getNextCompletedOperation(pOp2)) != NULL){ const NdbError err = pOp2->getNdbError(); if (err.code != 626){ ndbout << "err.code = " << err.code<< endl; nonExistingRecordsFound = 1; } } } pNdb->closeTransaction(pNoExistTrans); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } int testResult = NDBT_OK; int rowsResult = 0; UtilTransactions utilTrans(restab); if (utilTrans.selectCount(pNdb, 240, &rowsResult) != 0){ return NDBT_FAILED; } if (existingRecordsNotFound == 1){ ndbout << "!!! Expected records not found" << endl; testResult = NDBT_FAILED; } if (nonExistingRecordsFound == 1){ ndbout << "!!! Unxpected records found" << endl; testResult = NDBT_FAILED; } ndbout << rows << " rows scanned(" << rowsExist << " found, " << rowsResult<<" expected)" << endl; if (rowsResult != rowsExist){ ndbout << "!!! Number of rows in result table different from expected" << endl; testResult = NDBT_FAILED; } return testResult; } return NDBT_FAILED; }
int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; Ndb* pNdb = GETNDB(step); UtilTransactions utilTrans(*ctx->getTab()); HugoOperations hugoOps(*ctx->getTab()); NdbRestarter restarter; int restartGCI = pNdb->NdbTamper(Ndb::ReadRestartGCI, 0); ndbout << "restartGCI = " << restartGCI << endl; int count = 0; if (utilTrans.selectCount(pNdb, 64, &count) != 0){ return NDBT_FAILED; } // RULE1: The vector with saved records should have exactly as many // records with lower or same gci as there are in DB int recordsWithLowerOrSameGci = 0; unsigned i; for (i = 0; i < savedRecords.size(); i++){ if (savedRecords[i].m_gci <= restartGCI) recordsWithLowerOrSameGci++; } if (recordsWithLowerOrSameGci != count){ ndbout << "ERR: Wrong number of expected records" << endl; result = NDBT_FAILED; } // RULE2: The records found in db should have same or lower // gci as in the vector for (i = 0; i < savedRecords.size(); i++){ CHECK(hugoOps.startTransaction(pNdb) == 0); CHECK(hugoOps.pkReadRecord(pNdb, i) == 0); if (hugoOps.execute_Commit(pNdb) != 0){ // Record was not found in db' // Check record gci if (savedRecords[i].m_gci <= restartGCI){ ndbout << "ERR: Record "<<i<<" should have existed" << endl; result = NDBT_FAILED; } } else { // Record was found in db BaseString str = hugoOps.getRecordStr(0); // Check record string if (!(savedRecords[i].m_str == str)){ ndbout << "ERR: Record "<<i<<" str did not match "<< endl; result = NDBT_FAILED; } // Check record gci if (savedRecords[i].m_gci > restartGCI){ ndbout << "ERR: Record "<<i<<" should not have existed" << endl; result = NDBT_FAILED; } } CHECK(hugoOps.closeTransaction(pNdb) == 0); } ndbout << "There are " << count << " records in db" << endl; ndbout << "There are " << savedRecords.size() << " records in vector" << endl; ndbout << "There are " << recordsWithLowerOrSameGci << " records with lower or same gci than " << restartGCI << endl; return result; }