void TableTailer::createListenerEvent() { NdbDictionary::Dictionary *myDict = mNdbConnection->getDictionary(); if (!myDict) LOG_NDB_API_ERROR(mNdbConnection->getNdbError()); const NdbDictionary::Table *table = myDict->getTable(mTable.mTableName.c_str()); if (!table) LOG_NDB_API_ERROR(myDict->getNdbError()); NdbDictionary::Event myEvent(mEventName.c_str(), *table); for(int i=0; i< mTable.mNoEvents; i++){ myEvent.addTableEvent(mTable.mWatchEvents[i]); } const char* columns[mTable.mNoColumns]; for(int i=0; i< mTable.mNoColumns; i++){ columns[i] = mTable.mColumnNames[i].c_str(); } myEvent.addEventColumns(mTable.mNoColumns, columns); //myEvent.mergeEvents(merge_events); // Add event to database if (myDict->createEvent(myEvent) == 0) myEvent.print(); else if (myDict->getNdbError().classification == NdbError::SchemaObjectExists) { LOG_ERROR("Event creation failed, event exists, dropping Event..."); if (myDict->dropEvent(mEventName.c_str())) LOG_NDB_API_ERROR(myDict->getNdbError()); // try again // Add event to database if (myDict->createEvent(myEvent)) LOG_NDB_API_ERROR(myDict->getNdbError()); } else LOG_NDB_API_ERROR(myDict->getNdbError()); }
int runDDL(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb= GETNDB(step); NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); const int tables = NDBT_Tables::getNumTables(); while(!ctx->isTestStopped()) { const int tab_no = rand() % (tables); NdbDictionary::Table tab = *NDBT_Tables::getTable(tab_no); BaseString name= tab.getName(); name.appfmt("-%d", step->getStepNo()); tab.setName(name.c_str()); if(pDict->createTable(tab) == 0) { HugoTransactions hugoTrans(* pDict->getTable(name.c_str())); if (hugoTrans.loadTable(pNdb, 10000) != 0){ return NDBT_FAILED; } while(pDict->dropTable(tab.getName()) != 0 && pDict->getNdbError().code != 4009) g_err << pDict->getNdbError() << endl; sleep(1); } } return NDBT_OK; }
int runCreateIndexT1(NDBT_Context* ctx, NDBT_Step* step) { Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); const NdbDictionary::Table* pTab = pDict->getTable("T1"); if (pTab == 0) { g_err << "getTable(T1) error: " << pDict->getNdbError() << endl; return NDBT_FAILED; } NdbDictionary::Index ind; ind.setName("T1X1"); ind.setTable("T1"); ind.setType(NdbDictionary::Index::OrderedIndex); ind.setLogging(false); ind.addColumn("KOL2"); ind.addColumn("KOL3"); ind.addColumn("KOL4"); if (pDict->createIndex(ind, *pTab) != 0) { g_err << "createIndex(T1X1) error: " << pDict->getNdbError() << endl; return NDBT_FAILED; } return NDBT_OK; }
int NDBT_TestSuite::createTables(Ndb_cluster_connection& con) const { Ndb ndb(&con, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; i<m_tables_in_test.size(); i++) { const char *tab_name= m_tables_in_test[i].c_str(); if (pDict->dropTable(tab_name) != 0 && pDict->getNdbError().code != 723) // No such table { g_err << "runCreateTables: Failed to drop table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if(NDBT_Tables::createTable(&ndb, tab_name, !getLogging()) != 0) { g_err << "runCreateTables: Failed to create table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if (i == 0){ // Update ctx with a pointer to the first created table const NdbDictionary::Table* pTab2 = pDict->getTable(tab_name); ctx->setTab(pTab2); } g_info << "created " << tab_name << endl; } return NDBT_OK; }
static int runCreateTable(NDBT_Context* ctx, NDBT_Step* step) { Ndb ndb(&ctx->m_cluster_connection, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); const NdbDictionary::Table* pTab = ctx->getTab(); const char *tab_name= pTab->getName(); if (pDict->dropTable(tab_name) != 0 && pDict->getNdbError().code != 723) // No such table { g_err << "runCreateTable: Failed to drop table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if(NDBT_Tables::createTable(&ndb, tab_name, !ctx->getSuite()->getLogging()) != 0) { g_err << "runCreateTable: Failed to create table " << tab_name << pDict->getNdbError() << endl; return NDBT_FAILED; } // Update ctx with a pointer to the created table const NdbDictionary::Table* pTab2 = pDict->getTable(tab_name); ctx->setTab(pTab2); ctx->setProperty("$table", tab_name); return NDBT_OK; }
static void createIndex(Ndb &myNdb, bool includePrimary, unsigned int noOfIndexes) { Uint64 before, after; NdbDictionary::Dictionary* dict = myNdb.getDictionary(); char indexName[] = "PNUMINDEX0000"; int res; for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) { sprintf(indexName, "PNUMINDEX%.4u", indexNum); NdbDictionary::Index index(indexName); index.setTable("PERSON"); index.setType(NdbDictionary::Index::UniqueHashIndex); if (includePrimary) { const char* attr_arr[] = {"NAME", "PNUM1", "PNUM3"}; index.addIndexColumns(3, attr_arr); } else { const char* attr_arr[] = {"PNUM1", "PNUM3"}; index.addIndexColumns(2, attr_arr); } before = NdbTick_CurrentMillisecond(); if ((res = dict->createIndex(index)) == -1) { error_handler(dict->getNdbError()); } after = NdbTick_CurrentMillisecond(); ndbout << "Created index " << indexName << ", " << after - before << " msec" << endl; } }
void ListTablesCall::doAsyncCallback(Local<Object> ctx) { DEBUG_MARKER(UDEB_DETAIL); Handle<Value> cb_args[2]; const char * & dbName = arg1; DEBUG_PRINT("RETURN VAL: %d", return_val); if(return_val == -1) { cb_args[0] = NdbError_Wrapper(dict->getNdbError()); cb_args[1] = Null(); } else { cb_args[0] = Null(); // no error /* ListObjects has returned tables in all databases; we need to filter here on database name. */ int * stack = new int[list.count]; unsigned int nmatch = 0; for(unsigned i = 0; i < list.count ; i++) { if(strcmp(dbName, list.elements[i].database) == 0) { stack[nmatch++] = i; } } DEBUG_PRINT("arg1/nmatch/list.count: %s/%d/%d", arg1,nmatch,list.count); Local<Array> cb_list = Array::New(nmatch); for(unsigned int i = 0; i < nmatch ; i++) { cb_list->Set(i, String::New(list.elements[stack[i]].name)); } cb_args[1] = cb_list; delete[] stack; } callback->Call(ctx, 2, cb_args); }
static int drop_all_tables() { NdbDictionary::Dictionary * dict = g_ndb->getDictionary(); require(dict); BaseString db = g_ndb->getDatabaseName(); BaseString schema = g_ndb->getSchemaName(); NdbDictionary::Dictionary::List list; if (dict->listObjects(list, NdbDictionary::Object::TypeUndefined) == -1){ g_err << "Failed to list tables: " << endl << dict->getNdbError() << endl; return -1; } for (unsigned i = 0; i < list.count; i++) { NdbDictionary::Dictionary::List::Element& elt = list.elements[i]; switch (elt.type) { case NdbDictionary::Object::SystemTable: case NdbDictionary::Object::UserTable: g_ndb->setDatabaseName(elt.database); g_ndb->setSchemaName(elt.schema); if(dict->dropTable(elt.name) != 0){ g_err << "Failed to drop table: " << elt.database << "/" << elt.schema << "/" << elt.name <<endl; g_err << dict->getNdbError() << endl; return -1; } break; case NdbDictionary::Object::UniqueHashIndex: case NdbDictionary::Object::OrderedIndex: case NdbDictionary::Object::HashIndexTrigger: case NdbDictionary::Object::IndexTrigger: case NdbDictionary::Object::SubscriptionTrigger: case NdbDictionary::Object::ReadOnlyConstraint: default: break; } } g_ndb->setDatabaseName(db.c_str()); g_ndb->setSchemaName(schema.c_str()); return 0; }
bool BackupRestore::table(const TableS & table){ if (!m_restore_meta) { return true; } NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); if (dict->createTable(*table.m_dictTable) == -1) { err << "Create table " << table.getTableName() << " failed: " << dict->getNdbError() << endl; return false; } info << "Successfully restored table " << table.getTableName()<< endl ; return true; }
static int dropEvent(Ndb *pNdb, const NdbDictionary::Table &tab) { char eventName[1024]; sprintf(eventName,"%s_EVENT",tab.getName()); NdbDictionary::Dictionary *myDict = pNdb->getDictionary(); if (!myDict) { g_err << "Dictionary not found " << pNdb->getNdbError().code << " " << pNdb->getNdbError().message << endl; return NDBT_FAILED; } if (myDict->dropEvent(eventName)) { g_err << "Failed to drop event: " << myDict->getNdbError().code << " : " << myDict->getNdbError().message << endl; return NDBT_FAILED; } return NDBT_OK; }
static int runDropIndex(NDBT_Context* ctx, NDBT_Step* step) { const NdbDictionary::Table* pTab = ctx->getTab(); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); NdbDictionary::Dictionary::List list; if (pDic->listIndexes(list, pTab->getName()) != 0) { g_err << pTab->getName() << ": listIndexes failed" << endl; ERR(pDic->getNdbError()); return NDBT_FAILED; } for (unsigned i = 0; i < list.count; i++) { NDBT_Index* pInd = new NDBT_Index(list.elements[i].name); pInd->setTable(pTab->getName()); g_info << "Drop index:" << endl << *pInd; if (pInd->dropIndexInDb(pNdb) != 0) { return NDBT_FAILED; } } return NDBT_OK; }
int NDBT_Tables::create_default_tablespace(Ndb* pNdb) { NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); int res; NdbDictionary::LogfileGroup lg = pDict->getLogfileGroup("DEFAULT-LG"); if (strcmp(lg.getName(), "DEFAULT-LG") != 0) { lg.setName("DEFAULT-LG"); lg.setUndoBufferSize(8*1024*1024); res = pDict->createLogfileGroup(lg); if(res != 0){ g_err << "Failed to create logfilegroup:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } { NdbDictionary::Undofile uf = pDict->getUndofile(0, "undofile01.dat"); if (strcmp(uf.getPath(), "undofile01.dat") != 0) { uf.setPath("undofile01.dat"); uf.setSize(32*1024*1024); uf.setLogfileGroup("DEFAULT-LG"); res = pDict->createUndofile(uf, true); if(res != 0){ g_err << "Failed to create undofile:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } } { NdbDictionary::Undofile uf = pDict->getUndofile(0, "undofile02.dat"); if (strcmp(uf.getPath(), "undofile02.dat") != 0) { uf.setPath("undofile02.dat"); uf.setSize(32*1024*1024); uf.setLogfileGroup("DEFAULT-LG"); res = pDict->createUndofile(uf, true); if(res != 0){ g_err << "Failed to create undofile:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } } NdbDictionary::Tablespace ts = pDict->getTablespace("DEFAULT-TS"); if (strcmp(ts.getName(), "DEFAULT-TS") != 0) { ts.setName("DEFAULT-TS"); ts.setExtentSize(1024*1024); ts.setDefaultLogfileGroup("DEFAULT-LG"); res = pDict->createTablespace(ts); if(res != 0){ g_err << "Failed to create tablespace:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } { NdbDictionary::Datafile df = pDict->getDatafile(0, "datafile01.dat"); if (strcmp(df.getPath(), "datafile01.dat") != 0) { df.setPath("datafile01.dat"); df.setSize(64*1024*1024); df.setTablespace("DEFAULT-TS"); res = pDict->createDatafile(df, true); if(res != 0){ g_err << "Failed to create datafile:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } } { NdbDictionary::Datafile df = pDict->getDatafile(0, "datafile02.dat"); if (strcmp(df.getPath(), "datafile02.dat") != 0) { df.setPath("datafile02.dat"); df.setSize(64*1024*1024); df.setTablespace("DEFAULT-TS"); res = pDict->createDatafile(df, true); if(res != 0){ g_err << "Failed to create datafile:" << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } } } return NDBT_OK; }
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; }
int runPostUpgradeChecks(NDBT_Context* ctx, NDBT_Step* step) { /** * Table will be dropped/recreated * automatically by NDBT... * so when we enter here, this is already tested */ NdbBackup backup; ndbout << "Starting backup..." << flush; if (backup.start() != 0) { ndbout << "Failed" << endl; return NDBT_FAILED; } ndbout << "done" << endl; if ((ctx->getProperty("NoDDL", Uint32(0)) == 0) && (ctx->getProperty("KeepFS", Uint32(0)) != 0)) { /** * Bug48227 * Upgrade with FS 6.3->7.0, followed by table * create, followed by Sys restart resulted in * table loss. */ Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary *pDict = pNdb->getDictionary(); { NdbDictionary::Dictionary::List l; pDict->listObjects(l); for (Uint32 i = 0; i<l.count; i++) ndbout_c("found %u : %s", l.elements[i].id, l.elements[i].name); } pDict->dropTable("I3"); if (NDBT_Tables::createTable(pNdb, "I3")) { ndbout_c("Failed to create table!"); ndbout << pDict->getNdbError() << endl; return NDBT_FAILED; } { NdbDictionary::Dictionary::List l; pDict->listObjects(l); for (Uint32 i = 0; i<l.count; i++) ndbout_c("found %u : %s", l.elements[i].id, l.elements[i].name); } NdbRestarter res; if (res.restartAll() != 0) { ndbout_c("restartAll() failed"); return NDBT_FAILED; } if (res.waitClusterStarted() != 0) { ndbout_c("waitClusterStarted() failed"); return NDBT_FAILED; } if (pDict->getTable("I3") == 0) { ndbout_c("Table disappered"); return NDBT_FAILED; } } return NDBT_OK; }
static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab, bool merge_events = true, bool report = true) { char eventName[1024]; sprintf(eventName,"%s_EVENT",tab.getName()); NdbDictionary::Dictionary *myDict = pNdb->getDictionary(); if (!myDict) { g_err << "Dictionary not found " << pNdb->getNdbError().code << " " << pNdb->getNdbError().message << endl; return NDBT_FAILED; } myDict->dropEvent(eventName); NdbDictionary::Event myEvent(eventName); myEvent.setTable(tab.getName()); myEvent.addTableEvent(NdbDictionary::Event::TE_ALL); for(int a = 0; a < tab.getNoOfColumns(); a++) { myEvent.addEventColumn(a); } myEvent.mergeEvents(merge_events); if (report) myEvent.setReport(NdbDictionary::Event::ER_SUBSCRIBE); int res = myDict->createEvent(myEvent); // Add event to database if (res == 0) myEvent.print(); else if (myDict->getNdbError().classification == NdbError::SchemaObjectExists) { g_info << "Event creation failed event exists\n"; res = myDict->dropEvent(eventName); if (res) { g_err << "Failed to drop event: " << myDict->getNdbError().code << " : " << myDict->getNdbError().message << endl; return NDBT_FAILED; } // try again res = myDict->createEvent(myEvent); // Add event to database if (res) { g_err << "Failed to create event (1): " << myDict->getNdbError().code << " : " << myDict->getNdbError().message << endl; return NDBT_FAILED; } } else { g_err << "Failed to create event (2): " << myDict->getNdbError().code << " : " << myDict->getNdbError().message << endl; return NDBT_FAILED; } return NDBT_OK; }
int main(int argc, const char** argv){ ndb_init(); int _temp = false; int _help = 0; int _all = 0; int _print = 0; const char* _connectstr = NULL; int _diskbased = 0; const char* _tsname = NULL; int _trans = false; struct getargs args[] = { { "all", 'a', arg_flag, &_all, "Create/print all tables", 0 }, { "print", 'p', arg_flag, &_print, "Print table(s) instead of creating it", 0}, { "temp", 't', arg_flag, &_temp, "Temporary table", 0 }, { "trans", 'x', arg_flag, &_trans, "Use single schema trans", 0 }, { "connstr", 'c', arg_string, &_connectstr, "Connect string", "cs" }, { "diskbased", 0, arg_flag, &_diskbased, "Store attrs on disk if possible", 0 }, { "tsname", 0, arg_string, &_tsname, "Tablespace name", "ts" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; char desc[] = "tabname\n"\ "This program will create one table in Ndb.\n"\ "The tables may be selected from a fixed list of tables\n"\ "defined in NDBT_Tables class\n"; if(getarg(args, num_args, argc, argv, &optind) || _help){ arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } if(argv[optind] == NULL && !_all){ arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } g_diskbased = _diskbased; g_tsname = _tsname; int res = 0; if(_print){ /** * Print instead of creating */ if(optind < argc){ for(int i = optind; i<argc; i++){ NDBT_Tables::print(argv[i]); } } else { NDBT_Tables::printAll(); } } else { /** * Creating */ // Connect to Ndb Ndb_cluster_connection con(_connectstr); 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); } while(MyNdb.waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; NdbDictionary::Dictionary* MyDic = MyNdb.getDictionary(); if (_trans) { if (MyDic->beginSchemaTrans() == -1) { ERR(MyDic->getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } } if(_all){ res = NDBT_Tables::createAllTables(&MyNdb, _temp); } else { int tmp; for(int i = optind; i<argc; i++){ ndbout << "Trying to create " << argv[i] << endl; if((tmp = NDBT_Tables::createTable(&MyNdb, argv[i], _temp, false, g_create_hook)) != 0) res = tmp; } } if (_trans) { if (MyDic->endSchemaTrans() == -1) { ERR(MyDic->getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } } } if(res != 0) return NDBT_ProgramExit(NDBT_FAILED); else return NDBT_ProgramExit(NDBT_OK); }
int main(int argc, const char** argv){ ndb_init(); int _help = 0; int _p = 0; const char * db = "TEST_DB"; const char* _connectstr = NULL; struct getargs args[] = { { "database", 'd', arg_string, &db, "database", 0 }, { "connstr", 'c', arg_string, &_connectstr, "Connect string", "cs" }, { "partitions", 'p', arg_integer, &_p, "New no of partitions", 0}, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; char desc[] = "tabname\n" \ "This program will alter no of partitions of table in Ndb.\n"; if(getarg(args, num_args, argc, argv, &optind) || _help){ arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } if(argv[optind] == NULL) { arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } // Connect to Ndb Ndb_cluster_connection con(_connectstr); if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb(&con, db ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } while(MyNdb.waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; NdbDictionary::Dictionary* MyDic = MyNdb.getDictionary(); for (int i = optind; i<argc; i++) { printf("altering %s/%s...", db, argv[i]); const NdbDictionary::Table* oldTable = MyDic->getTable(argv[i]); if (oldTable == 0) { ndbout << "Failed to retrieve table " << argv[i] << ": " << MyDic->getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } NdbDictionary::Table newTable = *oldTable; newTable.setFragmentCount(_p); if (MyDic->beginSchemaTrans() != 0) goto err; if (MyDic->prepareHashMap(*oldTable, newTable) != 0) goto err; if (MyDic->alterTable(*oldTable, newTable) != 0) goto err; if (MyDic->endSchemaTrans()) goto err; ndbout_c("done"); } return NDBT_ProgramExit(NDBT_OK); err: NdbError err = MyDic->getNdbError(); if (MyDic->hasSchemaTrans()) MyDic->endSchemaTrans(NdbDictionary::Dictionary::SchemaTransAbort); ndbout << "Failed! " << err << endl; return NDBT_ProgramExit(NDBT_FAILED); }
bool BackupRestore::table(const TableS & table){ if (!m_restore && !m_restore_meta) return true; const char * name = table.getTableName(); /** * Ignore blob tables */ if(match_blob(name) >= 0) return true; const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table.m_dictTable); if(tmptab.m_indexType != NdbDictionary::Index::Undefined){ m_indexes.push_back(table.m_dictTable); return true; } BaseString tmp(name); Vector<BaseString> split; if(tmp.split(split, "/") != 3){ err << "Invalid table name format `" << name << "`" << endl; return false; } m_ndb->setDatabaseName(split[0].c_str()); m_ndb->setSchemaName(split[1].c_str()); NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); if(m_restore_meta){ NdbDictionary::Table copy(*table.m_dictTable); copy.setName(split[2].c_str()); /* update min and max rows to reflect the table, this to ensure that memory is allocated properly in the ndb kernel */ copy.setMinRows(table.getNoOfRecords()); if (table.getNoOfRecords() > copy.getMaxRows()) { copy.setMaxRows(table.getNoOfRecords()); } if (dict->createTable(copy) == -1) { err << "Create table `" << table.getTableName() << "` failed: " << dict->getNdbError() << endl; return false; } info << "Successfully restored table `" << table.getTableName() << "`" << endl; } const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); if(tab == 0){ err << "Unable to find table: `" << split[2].c_str() << "`" << endl; return false; } const NdbDictionary::Table* null = 0; m_new_tables.fill(table.m_dictTable->getTableId(), null); m_new_tables[table.m_dictTable->getTableId()] = tab; return true; }
int NDBT_TestSuite::execute(int argc, const char** argv){ int res = NDBT_FAILED; /* Arguments: Run only a subset of tests -n testname Which test to run Recommendations to test functions: --records Number of records to use(default: 10000) --loops Number of loops to execute in the test(default: 100) Other parameters should: * be calculated from the above two parameters * be divided into different test cases, ex. one testcase runs with FragmentType = Single and another perfoms the same test with FragmentType = Large * let the test case iterate over all/subset of appropriate parameters ex. iterate over FragmentType = Single to FragmentType = AllLarge Remeber that the intention is that it should be _easy_ to run a complete test suite without any greater knowledge of what should be tested ie. keep arguments at a minimum */ char **_argv= (char **)argv; if (!my_progname) my_progname= _argv[0]; const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&_argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:i:F:L"; #endif if ((ho_error=handle_options(&argc, &_argv, my_long_options, ndb_std_get_one_option))) { usage(); return NDBT_ProgramExit(NDBT_WRONGARGS); } if (opt_print == true){ printExecutionTree(); return 0; } if (opt_print_html == true){ printExecutionTreeHTML(); return 0; } if (opt_print_cases == true){ printCases(); return 0; } if (opt_verbose) setOutputLevel(2); // Show g_info else setOutputLevel(0); // Show only g_err ? remote_mgm = opt_remote_mgm; records = opt_records; loops = opt_loops; timer = opt_timer; Ndb_cluster_connection con; if(con.connect(12, 5, 1)) { return NDBT_ProgramExit(NDBT_FAILED); } if (opt_seed == 0) { opt_seed = NdbTick_CurrentMillisecond(); } ndbout_c("random seed: %u", opt_seed); srand(opt_seed); srandom(opt_seed); global_flag_skip_invalidate_cache = 1; { Ndb ndb(&con, "TEST_DB"); ndb.init(1024); if (ndb.waitUntilReady(500)){ g_err << "Ndb was not ready" << endl; return NDBT_ProgramExit(NDBT_FAILED); } NdbDictionary::Dictionary* pDict = ndb.getDictionary(); int num_tables= argc; if (argc == 0) num_tables = NDBT_Tables::getNumTables(); for(int i = 0; i<num_tables; i++) { if (argc == 0) m_tables_in_test.push_back(NDBT_Tables::getTable(i)->getName()); else m_tables_in_test.push_back(_argv[i]); if (createAllTables == true) { const char *tab_name= m_tables_in_test[i].c_str(); const NdbDictionary::Table* pTab = pDict->getTable(tab_name); if (pTab && pDict->dropTable(tab_name) != 0) { g_err << "ERROR0: Failed to drop table " << tab_name << pDict->getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } if(NDBT_Tables::createTable(&ndb, tab_name) != 0) { g_err << "ERROR1: Failed to create table " << tab_name << pDict->getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } } } } if(argc == 0){ // No table specified res = executeAll(con, opt_testname); } else { testSuiteTimer.doStart(); for(int i = 0; i<argc; i++){ executeOne(con, _argv[i], opt_testname); } testSuiteTimer.doStop(); res = report(opt_testname); } if (res == NDBT_OK && createAllTables == true) { Ndb ndb(&con, "TEST_DB"); ndb.init(1024); if (ndb.waitUntilReady(500)){ g_err << "Ndb was not ready" << endl; return NDBT_ProgramExit(NDBT_FAILED); } NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; i<m_tables_in_test.size(); i++) { pDict->dropTable(m_tables_in_test[i].c_str()); } } return NDBT_ProgramExit(res); }
int runBasic(NDBT_Context* ctx, NDBT_Step* step) { Uint32 useRangeScanT1 = ctx->getProperty("UseRangeScanT1", (uint32)0); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * pDict = pNdb->getDictionary(); int records = ctx->getNumRecords(); int result = NDBT_OK; int l = 0; while (!ctx->isTestStopped()) { for (unsigned i = 0; i<table_list.size(); i++) { const NdbDictionary::Table* tab = pDict->getTable(table_list[i].c_str()); HugoTransactions trans(* tab); switch(l % 4) { case 0: trans.loadTable(pNdb, records); trans.scanUpdateRecords(pNdb, records); trans.pkUpdateRecords(pNdb, records); trans.pkReadUnlockRecords(pNdb, records); break; case 1: trans.scanUpdateRecords(pNdb, records); // TODO make pkInterpretedUpdateRecords work on any table // (or check if it does) if (strcmp(tab->getName(), "T1") == 0) trans.pkInterpretedUpdateRecords(pNdb, records); if (strcmp(tab->getName(), "T1") == 0 && useRangeScanT1) { const NdbDictionary::Index* pInd = pDict->getIndex("T1X1", "T1"); if (pInd == 0) { g_err << "getIndex(T1X1) error: " << pDict->getNdbError() << endl; return NDBT_FAILED; } // bug#13834481 - bound values do not matter const Uint32 lo = 0x11110000; const Uint32 hi = 0xaaaa0000; HugoTransactions::HugoBound bound_arr[6]; int bound_cnt = 0; for (int j = 0; j <= 1; j++) { int n = rand() % 4; for (int i = 0; i < n; i++) { HugoTransactions::HugoBound& b = bound_arr[bound_cnt++]; b.attr = i; b.type = (j == 0 ? 0 : 2); // LE/GE b.value = (j == 0 ? &lo : &hi); } } g_info << "range scan T1 with " << bound_cnt << " bounds" << endl; if (trans.scanReadRecords(pNdb, pInd, records, 0, 0, NdbOperation::LM_Read, 0, bound_cnt, bound_arr) != 0) { const NdbError& err = trans.getNdbError(); /* * bug#13834481 symptoms include timeouts and error 1231. * Check for any non-temporary error. */ if (err.status == NdbError::TemporaryError) { g_info << "range scan T1 temporary error: " << err << endl; } if (err.status != NdbError::TemporaryError) { g_err << "range scan T1 permanent error: " << err << endl; return NDBT_FAILED; } } } trans.clearTable(pNdb, records/2); trans.loadTable(pNdb, records/2); break; case 2: trans.clearTable(pNdb, records/2); trans.loadTable(pNdb, records/2); trans.clearTable(pNdb, records/2); break; case 3: if (createDropEvent(ctx, step)) { return NDBT_FAILED; } break; } } l++; } return result; }
bool BackupRestore::endOfTables(){ if(!m_restore_meta) return true; NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); for(size_t i = 0; i<m_indexes.size(); i++){ NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]); Vector<BaseString> split; { BaseString tmp(indtab.m_primaryTable.c_str()); if (tmp.split(split, "/") != 3) { err << "Invalid table name format `" << indtab.m_primaryTable.c_str() << "`" << endl; return false; } } m_ndb->setDatabaseName(split[0].c_str()); m_ndb->setSchemaName(split[1].c_str()); const NdbDictionary::Table * prim = dict->getTable(split[2].c_str()); if(prim == 0){ err << "Unable to find base table `" << split[2].c_str() << "` for index `" << indtab.getName() << "`" << endl; return false; } NdbTableImpl& base = NdbTableImpl::getImpl(*prim); NdbIndexImpl* idx; Vector<BaseString> split_idx; { BaseString tmp(indtab.getName()); if (tmp.split(split_idx, "/") != 4) { err << "Invalid index name format `" << indtab.getName() << "`" << endl; return false; } } if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base)) { err << "Failed to create index `" << split_idx[3] << "` on " << split[2].c_str() << endl; return false; } idx->setName(split_idx[3].c_str()); if(dict->createIndex(* idx) != 0) { delete idx; err << "Failed to create index `" << split_idx[3].c_str() << "` on `" << split[2].c_str() << "`" << endl << dict->getNdbError() << endl; return false; } delete idx; info << "Successfully created index `" << split_idx[3].c_str() << "` on `" << split[2].c_str() << "`" << endl; } return true; }
int main(int argc, char** argv) { if (argc < 3) { std::cout << "Arguments are <connect_string cluster> <timeout> [m(merge events)|d(debug)].\n"; exit(-1); } const char *connectstring = argv[1]; int timeout = atoi(argv[2]); ndb_init(); bool merge_events = argc > 3 && strchr(argv[3], 'm') != 0; #ifdef VM_TRACE bool dbug = argc > 3 && strchr(argv[3], 'd') != 0; if (dbug) DBUG_PUSH("d:t:"); if (dbug) putenv("API_SIGNAL_LOG=-"); #endif Ndb_cluster_connection *cluster_connection= new Ndb_cluster_connection(connectstring); // Object representing the cluster int r= cluster_connection->connect(5 /* retries */, 3 /* delay between retries */, 1 /* verbose */); if (r > 0) { std::cout << "Cluster connect failed, possibly resolved with more retries.\n"; exit(-1); } else if (r < 0) { std::cout << "Cluster connect failed.\n"; exit(-1); } if (cluster_connection->wait_until_ready(30,30)) { std::cout << "Cluster was not ready within 30 secs." << std::endl; exit(-1); } Ndb* myNdb= new Ndb(cluster_connection, "TEST_DB"); // Object representing the database if (myNdb->init() == -1) APIERROR(myNdb->getNdbError()); const char *eventName= "CHNG_IN_t0"; const char *eventTableName= "t0"; const int noEventColumnName= 5; const char *eventColumnName[noEventColumnName]= {"c0", "c1", "c2", "c3", "c4" }; // Create events myCreateEvent(myNdb, eventName, eventTableName, eventColumnName, noEventColumnName, merge_events); // Normal values and blobs are unfortunately handled differently.. typedef union { NdbRecAttr* ra; NdbBlob* bh; } RA_BH; int i, j, k, l; j = 0; while (j < timeout) { // Start "transaction" for handling events NdbEventOperation* op; printf("create EventOperation\n"); if ((op = myNdb->createEventOperation(eventName)) == NULL) APIERROR(myNdb->getNdbError()); op->mergeEvents(merge_events); printf("get values\n"); RA_BH recAttr[noEventColumnName]; RA_BH recAttrPre[noEventColumnName]; // primary keys should always be a part of the result for (i = 0; i < noEventColumnName; i++) { if (i < 4) { recAttr[i].ra = op->getValue(eventColumnName[i]); recAttrPre[i].ra = op->getPreValue(eventColumnName[i]); } else if (merge_events) { recAttr[i].bh = op->getBlobHandle(eventColumnName[i]); recAttrPre[i].bh = op->getPreBlobHandle(eventColumnName[i]); } } // set up the callbacks printf("execute\n"); // This starts changes to "start flowing" if (op->execute()) APIERROR(op->getNdbError()); NdbEventOperation* the_op = op; i= 0; while (i < timeout) { // printf("now waiting for event...\n"); int r = myNdb->pollEvents(1000); // wait for event or 1000 ms if (r > 0) { // printf("got data! %d\n", r); while ((op= myNdb->nextEvent())) { assert(the_op == op); i++; switch (op->getEventType()) { case NdbDictionary::Event::TE_INSERT: printf("%u INSERT", i); break; case NdbDictionary::Event::TE_DELETE: printf("%u DELETE", i); break; case NdbDictionary::Event::TE_UPDATE: printf("%u UPDATE", i); break; default: abort(); // should not happen } printf(" gci=%d\n", (int)op->getGCI()); for (k = 0; k <= 1; k++) { printf(k == 0 ? "post: " : "pre : "); for (l = 0; l < noEventColumnName; l++) { if (l < 4) { NdbRecAttr* ra = k == 0 ? recAttr[l].ra : recAttrPre[l].ra; if (ra->isNULL() >= 0) { // we have a value if (ra->isNULL() == 0) { // we have a non-null value if (l < 2) printf("%-5u", ra->u_32_value()); else printf("%-5.4s", ra->aRef()); } else printf("%-5s", "NULL"); } else printf("%-5s", "-"); // no value } else if (merge_events) { int isNull; NdbBlob* bh = k == 0 ? recAttr[l].bh : recAttrPre[l].bh; bh->getDefined(isNull); if (isNull >= 0) { // we have a value if (! isNull) { // we have a non-null value Uint64 length = 0; bh->getLength(length); // read into buffer unsigned char* buf = new unsigned char [length]; memset(buf, 'X', length); Uint32 n = length; bh->readData(buf, n); // n is in/out assert(n == length); // pretty-print bool first = true; Uint32 i = 0; while (i < n) { unsigned char c = buf[i++]; Uint32 m = 1; while (i < n && buf[i] == c) i++, m++; if (! first) printf("+"); printf("%u%c", m, c); first = false; } printf("[%u]", n); delete [] buf; } else printf("%-5s", "NULL"); } else printf("%-5s", "-"); // no value } } printf("\n"); } } } else printf("timed out (%i)\n", timeout); } // don't want to listen to events anymore if (myNdb->dropEventOperation(the_op)) APIERROR(myNdb->getNdbError()); the_op = 0; j++; } { NdbDictionary::Dictionary *myDict = myNdb->getDictionary(); if (!myDict) APIERROR(myNdb->getNdbError()); // remove event from database if (myDict->dropEvent(eventName)) APIERROR(myDict->getNdbError()); } delete myNdb; delete cluster_connection; ndb_end(0); return 0; }
static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) { NdbDictionary::Dictionary* dict = myNdb.getDictionary(); NdbDictionary::Table table("PERSON"); //NdbDictionary::Column column(); // Bug NdbDictionary::Column column; int res; column.setName("NAME"); column.setType(NdbDictionary::Column::Char); column.setLength((longKey)? 1024 // 1KB => long key :12); column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); if (twoKey) { column.setName("KEY2"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); } column.setName("PNUM1"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM2"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM3"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM4"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("AGE"); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("STRING_AGE"); column.setType(NdbDictionary::Column::Char); column.setLength(1); column.setLength(256); column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); if ((res = dict->createTable(table)) == -1) { error_handler(dict->getNdbError()); } else ndbout << "Created table" << ((longKey)?" with long key":"") <<endl; }
bool BackupRestore::object(Uint32 type, const void * ptr) { if (!m_restore_meta) return true; NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); switch(type){ case DictTabInfo::Tablespace: { NdbDictionary::Tablespace old(*(NdbDictionary::Tablespace*)ptr); Uint32 id = old.getObjectId(); if (!m_no_restore_disk) { NdbDictionary::LogfileGroup * lg = m_logfilegroups[old.getDefaultLogfileGroupId()]; old.setDefaultLogfileGroup(* lg); info << "Creating tablespace: " << old.getName() << "..." << flush; int ret = dict->createTablespace(old); if (ret) { NdbError errobj= dict->getNdbError(); info << "FAILED" << endl; err << "Create tablespace failed: " << old.getName() << ": " << errobj << endl; return false; } info << "done" << endl; } NdbDictionary::Tablespace curr = dict->getTablespace(old.getName()); NdbError errobj = dict->getNdbError(); if ((int) errobj.classification == (int) ndberror_cl_none) { NdbDictionary::Tablespace* currptr = new NdbDictionary::Tablespace(curr); NdbDictionary::Tablespace * null = 0; m_tablespaces.set(currptr, id, null); debug << "Retreived tablespace: " << currptr->getName() << " oldid: " << id << " newid: " << currptr->getObjectId() << " " << (void*)currptr << endl; return true; } err << "Failed to retrieve tablespace \"" << old.getName() << "\": " << errobj << endl; return false; break; } case DictTabInfo::LogfileGroup: { NdbDictionary::LogfileGroup old(*(NdbDictionary::LogfileGroup*)ptr); Uint32 id = old.getObjectId(); if (!m_no_restore_disk) { info << "Creating logfile group: " << old.getName() << "..." << flush; int ret = dict->createLogfileGroup(old); if (ret) { NdbError errobj= dict->getNdbError(); info << "FAILED" << endl; err << "Create logfile group failed: " << old.getName() << ": " << errobj << endl; return false; } info << "done" << endl; } NdbDictionary::LogfileGroup curr = dict->getLogfileGroup(old.getName()); NdbError errobj = dict->getNdbError(); if ((int) errobj.classification == (int) ndberror_cl_none) { NdbDictionary::LogfileGroup* currptr = new NdbDictionary::LogfileGroup(curr); NdbDictionary::LogfileGroup * null = 0; m_logfilegroups.set(currptr, id, null); debug << "Retreived logfile group: " << currptr->getName() << " oldid: " << id << " newid: " << currptr->getObjectId() << " " << (void*)currptr << endl; return true; } err << "Failed to retrieve logfile group \"" << old.getName() << "\": " << errobj << endl; return false; break; } case DictTabInfo::Datafile: { if (!m_no_restore_disk) { NdbDictionary::Datafile old(*(NdbDictionary::Datafile*)ptr); NdbDictionary::ObjectId objid; old.getTablespaceId(&objid); NdbDictionary::Tablespace * ts = m_tablespaces[objid.getObjectId()]; debug << "Connecting datafile " << old.getPath() << " to tablespace: oldid: " << objid.getObjectId() << " newid: " << ts->getObjectId() << endl; old.setTablespace(* ts); info << "Creating datafile \"" << old.getPath() << "\"..." << flush; if (dict->createDatafile(old)) { NdbError errobj= dict->getNdbError(); info << "FAILED" << endl; err << "Create datafile failed: " << old.getPath() << ": " << errobj << endl; return false; } info << "done" << endl; } return true; break; } case DictTabInfo::Undofile: { if (!m_no_restore_disk) { NdbDictionary::Undofile old(*(NdbDictionary::Undofile*)ptr); NdbDictionary::ObjectId objid; old.getLogfileGroupId(&objid); NdbDictionary::LogfileGroup * lg = m_logfilegroups[objid.getObjectId()]; debug << "Connecting undofile " << old.getPath() << " to logfile group: oldid: " << objid.getObjectId() << " newid: " << lg->getObjectId() << " " << (void*)lg << endl; old.setLogfileGroup(* lg); info << "Creating undofile \"" << old.getPath() << "\"..." << flush; if (dict->createUndofile(old)) { NdbError errobj= dict->getNdbError(); info << "FAILED" << endl; err << "Create undofile failed: " << old.getPath() << ": " << errobj << endl; return false; } info << "done" << endl; } return true; break; } } return true; }
bool BackupRestore::table(const TableS & table){ if (!m_restore && !m_restore_meta) return true; const char * name = table.getTableName(); /** * Ignore blob tables */ if(match_blob(name) >= 0) return true; const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table.m_dictTable); if ((int) tmptab.m_indexType != (int) NdbDictionary::Index::Undefined){ m_indexes.push_back(table.m_dictTable); return true; } BaseString tmp(name); Vector<BaseString> split; if(tmp.split(split, "/") != 3){ err << "Invalid table name format `" << name << "`" << endl; return false; } m_ndb->setDatabaseName(split[0].c_str()); m_ndb->setSchemaName(split[1].c_str()); NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); if(m_restore_meta) { NdbDictionary::Table copy(*table.m_dictTable); copy.setName(split[2].c_str()); Uint32 id; if (copy.getTablespace(&id)) { debug << "Connecting " << name << " to tablespace oldid: " << id << flush; NdbDictionary::Tablespace* ts = m_tablespaces[id]; debug << " newid: " << ts->getObjectId() << endl; copy.setTablespace(* ts); } if (copy.getDefaultNoPartitionsFlag()) { /* Table was defined with default number of partitions. We can restore it with whatever is the default in this cluster. We use the max_rows parameter in calculating the default number. */ Uint32 no_nodes = m_cluster_connection->no_db_nodes(); copy.setFragmentCount(get_no_fragments(copy.getMaxRows(), no_nodes)); set_default_nodegroups(©); } else { /* Table was defined with specific number of partitions. It should be restored with the same number of partitions. It will either be restored in the same node groups as when backup was taken or by using a node group map supplied to the ndb_restore program. */ Uint16 *ng_array = (Uint16*)copy.getFragmentData(); Uint16 no_parts = copy.getFragmentCount(); if (map_nodegroups(ng_array, no_parts)) { if (translate_frm(©)) { err << "Create table " << table.getTableName() << " failed: "; err << "Translate frm error" << endl; return false; } } copy.setFragmentData((const void *)ng_array, no_parts << 1); } /** * Force of varpart was introduced in 5.1.18, telco 6.1.7 and 6.2.1 * Since default from mysqld is to add force of varpart (disable with * ROW_FORMAT=FIXED) we force varpart onto tables when they are restored * from backups taken with older versions. This will be wrong if * ROW_FORMAT=FIXED was used on original table, however the likelyhood of * this is low, since ROW_FORMAT= was a NOOP in older versions. */ if (table.getBackupVersion() < MAKE_VERSION(5,1,18)) copy.setForceVarPart(true); else if (getMajor(table.getBackupVersion()) == 6 && (table.getBackupVersion() < MAKE_VERSION(6,1,7) || table.getBackupVersion() == MAKE_VERSION(6,2,0))) copy.setForceVarPart(true); /* update min and max rows to reflect the table, this to ensure that memory is allocated properly in the ndb kernel */ copy.setMinRows(table.getNoOfRecords()); if (table.getNoOfRecords() > copy.getMaxRows()) { copy.setMaxRows(table.getNoOfRecords()); } NdbTableImpl &tableImpl = NdbTableImpl::getImpl(copy); if (table.getBackupVersion() < MAKE_VERSION(5,1,0) && !m_no_upgrade){ for(int i= 0; i < copy.getNoOfColumns(); i++) { NdbDictionary::Column::Type t = copy.getColumn(i)->getType(); if (t == NdbDictionary::Column::Varchar || t == NdbDictionary::Column::Varbinary) tableImpl.getColumn(i)->setArrayType(NdbDictionary::Column::ArrayTypeShortVar); if (t == NdbDictionary::Column::Longvarchar || t == NdbDictionary::Column::Longvarbinary) tableImpl.getColumn(i)->setArrayType(NdbDictionary::Column::ArrayTypeMediumVar); } } if (dict->createTable(copy) == -1) { err << "Create table `" << table.getTableName() << "` failed: " << dict->getNdbError() << endl; if (dict->getNdbError().code == 771) { /* The user on the cluster where the backup was created had specified specific node groups for partitions. Some of these node groups didn't exist on this cluster. We will warn the user of this and inform him of his option. */ err << "The node groups defined in the table didn't exist in this"; err << " cluster." << endl << "There is an option to use the"; err << " the parameter ndb-nodegroup-map to define a mapping from"; err << endl << "the old nodegroups to new nodegroups" << endl; } return false; } info << "Successfully restored table `" << table.getTableName() << "`" << endl; } const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); if(tab == 0){ err << "Unable to find table: `" << split[2].c_str() << "`" << endl; return false; } if(m_restore_meta) { if (tab->getFrmData()) { // a MySQL Server table is restored, thus an event should be created BaseString event_name("REPL$"); event_name.append(split[0].c_str()); event_name.append("/"); event_name.append(split[2].c_str()); NdbDictionary::Event my_event(event_name.c_str()); my_event.setTable(*tab); my_event.addTableEvent(NdbDictionary::Event::TE_ALL); // add all columns to the event bool has_blobs = false; for(int a= 0; a < tab->getNoOfColumns(); a++) { my_event.addEventColumn(a); NdbDictionary::Column::Type t = tab->getColumn(a)->getType(); if (t == NdbDictionary::Column::Blob || t == NdbDictionary::Column::Text) has_blobs = true; } if (has_blobs) my_event.mergeEvents(true); while ( dict->createEvent(my_event) ) // Add event to database { if (dict->getNdbError().classification == NdbError::SchemaObjectExists) { info << "Event for table " << table.getTableName() << " already exists, removing.\n"; if (!dict->dropEvent(my_event.getName())) continue; } err << "Create table event for " << table.getTableName() << " failed: " << dict->getNdbError() << endl; dict->dropTable(split[2].c_str()); return false; } info << "Successfully restored table event " << event_name << endl ; } } const NdbDictionary::Table* null = 0; m_new_tables.fill(table.m_dictTable->getTableId(), null); m_new_tables[table.m_dictTable->getTableId()] = tab; return true; }
int main(int argc, const char** argv){ ndb_init(); int _help = 0; const char* db = 0; const char* connectstring1 = 0; const char* connectstring2 = 0; struct getargs args[] = { { "connectstring1", 'c', arg_string, &connectstring1, "connectstring1", "" }, { "connectstring2", 'C', arg_string, &connectstring2, "connectstring2", "" }, { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0, i; char desc[] = "<tabname>+ \nThis program listen to events on specified tables\n"; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || _help) { arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } // Connect to Ndb Ndb_cluster_connection con(connectstring1); if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb( &con, db ? db : "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; Ndb_cluster_connection *con2 = NULL; Ndb *ndb2 = NULL; if (connectstring2) { con2 = new Ndb_cluster_connection(connectstring2); if(con2->connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } ndb2 = new Ndb( con2, db ? db : "TEST_DB" ); if(ndb2->init() != 0){ ERR(ndb2->getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(ndb2->waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; } int result = 0; NdbDictionary::Dictionary *myDict = MyNdb.getDictionary(); Vector<NdbDictionary::Event*> events; Vector<NdbEventOperation*> event_ops; int sz = 0; for(i= optind; i<argc; i++) { const NdbDictionary::Table* table= myDict->getTable(argv[i]); if(!table) { ndbout_c("Could not find table: %s, skipping", argv[i]); continue; } BaseString name; name.appfmt("EV-%s", argv[i]); NdbDictionary::Event *myEvent= new NdbDictionary::Event(name.c_str()); myEvent->setTable(table->getName()); myEvent->addTableEvent(NdbDictionary::Event::TE_ALL); for(int a = 0; a < table->getNoOfColumns(); a++){ myEvent->addEventColumn(a); } if (myDict->createEvent(* myEvent)) { if(myDict->getNdbError().classification == NdbError::SchemaObjectExists) { g_info << "Event creation failed event exists. Removing...\n"; if (myDict->dropEvent(name.c_str())) { g_err << "Failed to drop event: " << myDict->getNdbError() << endl; result = 1; goto end; } // try again if (myDict->createEvent(* myEvent)) { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } else { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } events.push_back(myEvent); NdbEventOperation* pOp = MyNdb.createEventOperation(name.c_str()); if ( pOp == NULL ) { g_err << "Event operation creation failed" << endl; result = 1; goto end; } event_values.push_back(Vector<NdbRecAttr *>()); event_pre_values.push_back(Vector<NdbRecAttr *>()); for (int a = 0; a < table->getNoOfColumns(); a++) { event_values[sz]. push_back(pOp->getValue(table->getColumn(a)->getName())); event_pre_values[sz]. push_back(pOp->getPreValue(table->getColumn(a)->getName())); } event_ops.push_back(pOp); { struct Table_info ti; ti.id = sz; table_infos.push_back(ti); } pOp->setCustomData((void *)&table_infos[sz]); sz++; } for(i= 0; i<(int)event_ops.size(); i++) { if (event_ops[i]->execute()) { g_err << "operation execution failed: " << event_ops[i]->getNdbError() << endl; result = 1; goto end; } } struct Trans_arg trans_arg; while(true) { while(MyNdb.pollEvents(100) == 0); NdbEventOperation* pOp= MyNdb.nextEvent(); while(pOp) { Uint64 gci= pOp->getGCI(); Uint64 cnt_i= 0, cnt_u= 0, cnt_d= 0; if (ndb2) do_begin(ndb2, trans_arg); do { switch(pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: cnt_i++; if (ndb2) do_insert(trans_arg, pOp); break; case NdbDictionary::Event::TE_DELETE: cnt_d++; if (ndb2) do_delete(trans_arg, pOp); break; case NdbDictionary::Event::TE_UPDATE: cnt_u++; if (ndb2) do_update(trans_arg, pOp); break; case NdbDictionary::Event::TE_CLUSTER_FAILURE: break; case NdbDictionary::Event::TE_ALTER: break; case NdbDictionary::Event::TE_DROP: break; case NdbDictionary::Event::TE_NODE_FAILURE: break; case NdbDictionary::Event::TE_SUBSCRIBE: case NdbDictionary::Event::TE_UNSUBSCRIBE: break; default: /* We should REALLY never get here. */ ndbout_c("Error: unknown event type: %u", (Uint32)pOp->getEventType()); abort(); } } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI()); if (ndb2) do_commit(trans_arg); ndbout_c("GCI: %lld events: %lld(I) %lld(U) %lld(D)", gci, cnt_i, cnt_u, cnt_d); } } end: for(i= 0; i<(int)event_ops.size(); i++) MyNdb.dropEventOperation(event_ops[i]); if (ndb2) delete ndb2; if (con2) delete con2; return NDBT_ProgramExit(NDBT_OK); }
void GetTableCall::run() { DEBUG_PRINT("GetTableCall::run() [%s.%s]", arg1, arg2); return_val = -1; /* dbName is optional; if not present, set it from ndb database name */ if(strlen(dbName)) { ndb->setDatabaseName(dbName); } else { dbName = ndb->getDatabaseName(); } dict = ndb->getDictionary(); ndb_table = dict->getTable(tableName); if(ndb_table) { /* Ndb object used to create NdbRecords and to cache auto-increment values */ per_table_ndb = new Ndb(& ndb->get_ndb_cluster_connection()); DEBUG_PRINT("per_table_ndb %s.%s %p\n", dbName, tableName, per_table_ndb); per_table_ndb->init(); /* List the indexes */ return_val = dict->listIndexes(idx_list, tableName); } if(return_val == 0) { /* Fetch the indexes now. These calls may perform network IO, populating the (connection) global and (Ndb) local dictionary caches. Later, in the JavaScript main thread, we will call getIndex() again knowing that the caches are populated. */ for(unsigned int i = 0 ; i < idx_list.count ; i++) { const NdbDictionary::Index * idx = dict->getIndex(idx_list.elements[i].name, tableName); /* It is possible to get an index for a recently dropped table rather than the desired table. This is a known bug likely to be fixed later. */ const char * idx_table_name = idx->getTable(); const NdbDictionary::Table * idx_table = dict->getTable(idx_table_name); if(idx_table == 0 || idx_table->getObjectVersion() != ndb_table->getObjectVersion()) { dict->invalidateIndex(idx); idx = dict->getIndex(idx_list.elements[i].name, tableName); } } } else { DEBUG_PRINT("listIndexes() returned %i", return_val); ndbError = & dict->getNdbError(); return; } /* List the foreign keys and keep the list around for doAsyncCallback to create js objects * Currently there is no listForeignKeys so we use the more generic listDependentObjects * specifying the table metadata object. */ return_val = dict->listDependentObjects(fk_list, *ndb_table); if (return_val == 0) { /* Fetch the foreign keys and associated parent tables now. * These calls may perform network IO, populating * the (connection) global and (Ndb) local dictionary caches. Later, * in the JavaScript main thread, we will call getForeignKey() again knowing * that the caches are populated. * We only care about foreign keys where this table is the child table, not the parent table. */ for(unsigned int i = 0 ; i < fk_list.count ; i++) { NdbDictionary::ForeignKey fk; if (fk_list.elements[i].type == NdbDictionary::Object::ForeignKey) { const char * fk_name = fk_list.elements[i].name; int fkGetCode = dict->getForeignKey(fk, fk_name); DEBUG_PRINT("getForeignKey for %s returned %i", fk_name, fkGetCode); // see if the foreign key child table is this table if(splitNameMatchesDbAndTable(fk.getChildTable())) { // the foreign key child table is this table; get the parent table ++fk_count; DEBUG_PRINT("Getting ParentTable"); splitter.splitName(fk.getParentTable()); ndb->setDatabaseName(splitter.part1); // temp for next call const NdbDictionary::Table * parent_table = dict->getTable(splitter.part3); ndb->setDatabaseName(dbName); // back to expected value DEBUG_PRINT("Parent table getTable returned %s", parent_table->getName()); } } } } else { DEBUG_PRINT("listDependentObjects() returned %i", return_val); ndbError = & dict->getNdbError(); } }
void NDBT_TestSuite::execute(Ndb_cluster_connection& con, Ndb* ndb, const NdbDictionary::Table* pTab, const char* _testname){ int result; for (unsigned t = 0; t < tests.size(); t++){ if (_testname != NULL && strcasecmp(tests[t]->getName(), _testname) != 0) continue; if (tests[t]->m_all_tables && tests[t]->m_has_run) { continue; } if (tests[t]->isVerify(pTab) == false) { continue; } tests[t]->initBeforeTest(); NdbDictionary::Dictionary* pDict = ndb->getDictionary(); const NdbDictionary::Table* pTab2 = pDict->getTable(pTab->getName()); if (createTable == true){ if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0){ numTestsFail++; numTestsExecuted++; g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); continue; } if (NDBT_Tables::createTable(ndb, pTab->getName(), false, false, g_create_hook, this) != 0) { numTestsFail++; numTestsExecuted++; g_err << "ERROR1: Failed to create table " << pTab->getName() << pDict->getNdbError() << endl; tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); continue; } pTab2 = pDict->getTable(pTab->getName()); } else if(!pTab2) { pTab2 = pTab; } ctx = new NDBT_Context(con); ctx->setTab(pTab2); ctx->setNumRecords(records); ctx->setNumLoops(loops); if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); result = tests[t]->execute(ctx); tests[t]->saveTestResult(pTab, result); if (result != NDBT_OK) numTestsFail++; else numTestsOk++; numTestsExecuted++; if (result == NDBT_OK && createTable == true && createAllTables == false){ pDict->dropTable(pTab->getName()); } tests[t]->m_has_run = true; delete ctx; } }
int main(int argc, char** argv) { NDB_INIT(argv[0]); const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:F:L"; #endif if ((ho_error=handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option))) return NDBT_ProgramExit(NDBT_WRONGARGS); DBUG_ENTER("main"); Ndb_cluster_connection con(opt_connect_str); if(con.connect(12, 5, 1)) { DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED)); } Ndb ndb(&con,_dbname); ndb.init(); while (ndb.waitUntilReady() != 0); NdbDictionary::Dictionary * dict = ndb.getDictionary(); int no_error= 1; int i; // create all tables Vector<const NdbDictionary::Table*> pTabs; if (argc == 0) { NDBT_Tables::dropAllTables(&ndb); NDBT_Tables::createAllTables(&ndb); for (i= 0; no_error && i < NDBT_Tables::getNumTables(); i++) { const NdbDictionary::Table *pTab= dict->getTable(NDBT_Tables::getTable(i)->getName()); if (pTab == 0) { ndbout << "Failed to create table" << endl; ndbout << dict->getNdbError() << endl; no_error= 0; break; } pTabs.push_back(pTab); } } else { for (i= 0; no_error && argc; argc--, i++) { dict->dropTable(argv[i]); NDBT_Tables::createTable(&ndb, argv[i]); const NdbDictionary::Table *pTab= dict->getTable(argv[i]); if (pTab == 0) { ndbout << "Failed to create table" << endl; ndbout << dict->getNdbError() << endl; no_error= 0; break; } pTabs.push_back(pTab); } } pTabs.push_back(NULL); // create an event for each table for (i= 0; no_error && pTabs[i]; i++) { HugoTransactions ht(*pTabs[i]); if (ht.createEvent(&ndb)){ no_error= 0; break; } } // create an event operation for each event Vector<NdbEventOperation *> pOps; for (i= 0; no_error && pTabs[i]; i++) { char buf[1024]; sprintf(buf, "%s_EVENT", pTabs[i]->getName()); NdbEventOperation *pOp= ndb.createEventOperation(buf, 1000); if ( pOp == NULL ) { no_error= 0; break; } pOps.push_back(pOp); } // get storage for each event operation for (i= 0; no_error && pTabs[i]; i++) { int n_columns= pTabs[i]->getNoOfColumns(); for (int j = 0; j < n_columns; j++) { pOps[i]->getValue(pTabs[i]->getColumn(j)->getName()); pOps[i]->getPreValue(pTabs[i]->getColumn(j)->getName()); } } // start receiving events for (i= 0; no_error && pTabs[i]; i++) { if ( pOps[i]->execute() ) { no_error= 0; break; } } // create a "shadow" table for each table Vector<const NdbDictionary::Table*> pShadowTabs; for (i= 0; no_error && pTabs[i]; i++) { char buf[1024]; sprintf(buf, "%s_SHADOW", pTabs[i]->getName()); dict->dropTable(buf); if (dict->getTable(buf)) { no_error= 0; break; } NdbDictionary::Table table_shadow(*pTabs[i]); table_shadow.setName(buf); dict->createTable(table_shadow); pShadowTabs.push_back(dict->getTable(buf)); if (!pShadowTabs[i]) { no_error= 0; break; } } // create a hugo operation per table Vector<HugoOperations *> hugo_ops; for (i= 0; no_error && pTabs[i]; i++) { hugo_ops.push_back(new HugoOperations(*pTabs[i])); } int n_records= 3; // insert n_records records per table do { if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } for (i= 0; no_error && pTabs[i]; i++) { hugo_ops[i]->pkInsertRecord(&ndb, 0, n_records); } if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } } while(0); // copy events and verify do { if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } while (0); // update n_records-1 records in first table do { if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } hugo_ops[0]->pkUpdateRecord(&ndb, n_records-1); if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } } while(0); // copy events and verify do { if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } while (0); { NdbRestarts restarts; for (int j= 0; j < 10; j++) { // restart a node if (no_error) { int timeout = 240; if (restarts.executeRestart("RestartRandomNodeAbort", timeout)) { no_error= 0; break; } } // update all n_records records on all tables if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } for (int r= 0; r < n_records; r++) { for (i= 0; pTabs[i]; i++) { hugo_ops[i]->pkUpdateRecord(&ndb, r); } } if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } // copy events and verify if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } } // drop the event operations for (i= 0; i < (int)pOps.size(); i++) { if (ndb.dropEventOperation(pOps[i])) { no_error= 0; } } if (no_error) DBUG_RETURN(NDBT_ProgramExit(NDBT_OK)); DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED)); }
void TableTailer::removeListenerEvent() { NdbDictionary::Dictionary *myDict = mNdbConnection->getDictionary(); if (!myDict) LOG_NDB_API_ERROR(mNdbConnection->getNdbError()); // remove event from database if (myDict->dropEvent(mEventName.c_str())) LOG_NDB_API_ERROR(myDict->getNdbError()); }