Пример #1
0
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;
}
Пример #2
0
Ndb*
asyncDbConnect(int parallellism){
  NdbMutex_Lock(startupMutex);
  Ndb * pNDB = new Ndb("");
  
  pNDB->init(parallellism + 1);
  
  while(pNDB->waitUntilReady() != 0){
  }
  
  NdbMutex_Unlock(startupMutex);

  return pNDB;
}
Пример #3
0
int runBackupBank(NDBT_Context* ctx, NDBT_Step* step){
  int loops = ctx->getNumLoops();
  int l = 0;
  int maxSleep = 30; // Max seconds between each backup
  Ndb* pNdb = GETNDB(step);
  NdbBackup backup(GETNDB(step)->getNodeId()+1);
  unsigned minBackupId = ~0;
  unsigned maxBackupId = 0;
  unsigned backupId = 0;
  int result = NDBT_OK;

  while (l < loops && result != NDBT_FAILED){

    if (pNdb->waitUntilReady() != 0){
      result = NDBT_FAILED;
      continue;
    }

    // Sleep for a while
    NdbSleep_SecSleep(maxSleep);
    
    // Perform backup
    if (backup.start(backupId) != 0){
      ndbout << "backup.start failed" << endl;
      result = NDBT_FAILED;
      continue;
    }
    ndbout << "Started backup " << backupId << endl;

    // Remember min and max backupid
    if (backupId < minBackupId)
      minBackupId = backupId;

    if (backupId > maxBackupId)
      maxBackupId = backupId;
    
    ndbout << " maxBackupId = " << maxBackupId 
	   << ", minBackupId = " << minBackupId << endl;
    ctx->setProperty("MinBackupId", minBackupId);    
    ctx->setProperty("MaxBackupId", maxBackupId);    
    
    l++;
  }

  ctx->stopTest();

  return result;
}
Пример #4
0
UserHandle*
userDbConnect(uint32 createDb, const char *dbName)
{
  Ndb_cluster_connection *con= new Ndb_cluster_connection();
  if(con->connect(12, 5, 1) != 0)
  {
    ndbout << "Unable to connect to management server." << endl;
    return 0;
  }
  if (con->wait_until_ready(30,0) < 0)
  {
    ndbout << "Cluster nodes not ready in 30 seconds." << endl;
    return 0;
  }

  Ndb * pNdb = new Ndb(con, dbName);
  
  //printf("Initializing...\n");
  pNdb->init();
  
  //printf("Waiting...");
  while(pNdb->waitUntilReady() != 0){
    //printf("...");
  }
  //  printf("done\n");
  
  if( createDb )
    dbCreate(pNdb);
  

  UserHandle * uh = new UserHandle;
  uh->pNCC       = con;
  uh->pNDB       = pNdb;
  uh->pCurrTrans = 0;

  return uh;
}
Пример #5
0
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;
}
int main(int argc, const char** argv)
{
  ndb_init();
  int _row = 0;
  int _hex = 0;
  int _primaryKey = 0;
  const char* _tableName = NULL;

  struct getargs args[] = {
    { "row", 'r', 
      arg_integer, &_row, "The row number", "row" },
    { "primarykey", 'p', 
      arg_integer, &_primaryKey, "The primary key", "primarykey" },
    { "hex", 'h', 
      arg_flag, &_hex, "Print hex", "hex" }
  };

  int num_args = sizeof(args) / sizeof(args[0]);
  int optind = 0, i;

  if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) {
    arg_printusage(args, num_args, argv[0], "table name\n");
    return NDBT_WRONGARGS;
  }
  // Check if table name is supplied
  if (argv[optind] != NULL) 
    _tableName = argv[optind];


  const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName);
  //  const NDBT_Attribute* attribute = table->getAttribute(_column);

  g_info << "Table " << _tableName << endl
	 << "Row: " << _row << ", PrimaryKey: " << _primaryKey
	 << endl;

  Ndb_cluster_connection con;
  if(con.connect(12, 5, 1) != 0)
  {
    return NDBT_ProgramExit(NDBT_FAILED);
  }
  Ndb* ndb = new Ndb(&con, "TEST_DB");
  if (ndb->init() == 0 && ndb->waitUntilReady(30) == 0)
  {
    NdbConnection* conn = ndb->startTransaction();
    if (conn == NULL)
    {
      g_info << "ERROR: " << ndb->getNdbError() << endl;
      delete ndb;
      return -1;
    }
    NdbOperation* op = conn->getNdbOperation(_tableName);
    if (op == NULL)
    {
      g_info << "ERROR: " << conn->getNdbError() << endl;
      delete ndb;
      return -1;
    }
    op->readTuple();
    NdbRecAttr** data = new NdbRecAttr*[table->getNoOfColumns()];
    for (i = 0; i < table->getNoOfColumns(); i++)
    {
      const NdbDictionary::Column* c = table->getColumn(i);
      if (c->getPrimaryKey())
      {
	op->equal(c->getName(), _primaryKey);
	data[i] = op->getValue(c->getName(), NULL);
      }
      else
      {
	data[i] = op->getValue(c->getName(), NULL);
      }      
    }
    if (conn->execute(Commit) == 0)
    {
      // Print column names
      for (i = 0; i < table->getNoOfColumns(); i++)
      {
	const NdbDictionary::Column* c = table->getColumn(i);
	
	g_info 
	  << c->getName()
	  << "[" << c->getType() << "]   ";	  
      }
      g_info << endl;

      if (_hex)
      {
	g_info << hex;
      }
      for (i = 0; i < table->getNoOfColumns(); i++)
      {
	NdbRecAttr* a = data[i];
	ndbout << (* a) << " ";
      } // for   
      g_info << endl;   
    } // if (conn
    else
    {
      g_info << "Failed to commit read transaction... " 
	     << conn->getNdbError()
	     << ", commitStatus = " << conn->commitStatus()
	     << endl;
    }

    delete[] data;
    
    ndb->closeTransaction(conn);
  } // if (ndb.init
  else
  {
    g_info << "ERROR: Unable to connect to NDB, " 
	   << ndb->getNdbError() << endl;
  }
  delete ndb;

  return 0;
}
Пример #7
0
int main(int argc, char* argv[])
{
  // setlocale(LC_ALL, "");

  if (argc < 2) {
    printf("No connection string specified.\n");
    print_help();
    return -1;
  }
  if (argc < 3) {
    printf("No database specified.\n");
    print_help();
    return -1;
  }
  if (argc < 4) {
    printf("No filepath specified.\n");
    print_help();
    return -1;
  }  
  if (argc < 5) {
    printf("No table format file specified.\n");
    print_help();
    return -1;
  }
  if (argc >= 6) {
    tNoOfParallelTrans = atoi(argv[5]);
  }
  if (argc >= 7) {
    sleepTimeMilli = atoi(argv[6]);
  }

  strcpy(connstring, argv[1]);
  strcpy(database, argv[2]);
  strcpy(filepath, argv[3]);
  strcpy(tablefilepath, argv[4]);

  ifstream fin(tablefilepath);
  // first line is table name.
  string tmpTableName;
  getline(fin, tmpTableName);
  strcpy(tablename, tmpTableName.c_str());

  // find a "nokey" in table name
  istringstream lineReader(tmpTableName);
  string firstpart;
  if( getline(lineReader, firstpart, ' ') )
  {
    // printf("first part: %s", firstpart.c_str());
    string secondpart;
    if( getline(lineReader, secondpart) ) {
      // "firstpart secondpart"
      if (secondpart != NOKEY_IDENTIFIER) {
        cerr << "ERROR: could not recognize identifier: " << secondpart << endl;
        cerr << "Do you mean: '" << NOKEY_IDENTIFIER << "'?"<< endl;
        exit(-1);
      } else {
        noKey = true;
      }
      // printf("Attr: %s %s\n", key.c_str(), value.c_str());
    }
    strcpy(tablename, firstpart.c_str());
  } 


  // Initialize transaction array
  for(int i = 0 ; i < MAXTRANS ; i++) 
  {
    transaction[i].used = 0;
    transaction[i].conn = 0;
  }

  // each line is a column
  for (string row; getline(fin, row); ) {
    istringstream lineReader(row);
    string key;
    if( getline(lineReader, key, ' ') )
    {
      string value;
      if( getline(lineReader, value) ) {
        // "key value"
        fieldName.push_back(key);
        fieldType.push_back(value);
        // printf("Attr: %s %s\n", key.c_str(), value.c_str());
      }
    }
  }
  fin.close();

  Ndb_cluster_connection *conn = connect_to_cluster(connstring);

  Ndb* ndb = new Ndb(conn, database);
  if (ndb->init(1024) == -1)
  {
     // pass
  }
  ndb->waitUntilReady(10000);
  printf("Connected: database [%s], connstr [%s], #parallelTrans=[%d]. Load table [%s] from file [%s]...\n", database, connstring, tNoOfParallelTrans, tablename, filepath);

  // do_insert(*ndb);

  const NdbDictionary::Dictionary* myDict= ndb->getDictionary();
  // printf("table name: %s\n", tablename);
  const NdbDictionary::Table *myTable= myDict->getTable(tablename);

  if (myTable == NULL) 
    APIERROR(myDict->getNdbError());

  // Load the data
  bool dataleft = false;

  typedef vector<vector<string> > Rows;

  // Rows rows;
  ifstream input(filepath);
  char const row_delim = '\n';
  char const field_delim = '\t';
  int rowCounter = 0;
  for (string row; getline(input, row, row_delim); ) {

    // Find a slot in the transaction array
    async_callback_t * cb;
    // int retries = 0;
    int current = -1;

    int cursor = transTail + 1;
    if (cursor >= MAXTRANS) {
      cursor = 0;
    }

    for(int retries = 0; retries < MAX_TRANSALLOC_RETRY; retries++) {
      // for(int cursor=0; cursor < MAXTRANS; cursor++) 
      while(true)
      {
        if(transaction[cursor].used == 0)
        {          
          current = cursor;
          cb = new async_callback_t;
          /**
           * Set data used by the callback
           */
          cb->ndb = ndb;  //handle to Ndb object so that we can close transaction
                            // in the callback (alt. make myNdb global).

          cb->transaction = current; //This is the number (id)  of this transaction
          transaction[current].used = 1 ; //Mark the transaction as used
          transTail = current; // optimizing scan

          break;
        }
        else { // used
          cursor += 1; 
          if (cursor >= MAXTRANS) {
            cursor = 0;
          }

        }
      }
      if(current == -1) {
        cerr << "WARNING: Number of transactions in parallel exceeds the maximum. retrying..." << endl;
        usleep(1000);
        continue;
      } else {
        break;
      }
    }

    transaction[current].conn = ndb->startTransaction();

    istringstream ss(row);
    // NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
    NdbOperation *myOperation= transaction[current].conn->getNdbOperation(myTable);
    myOperation->insertTuple();

    // If no primary key is assigned, have to set the tupleId explicitly
    if (noKey) {
      unsigned long long tupleId = 0;
      // int
      // Ndb::getAutoIncrementValue(const char* aTableName,
      //                      Uint64 & autoValue, Uint32 cacheSize,
      //                      Uint64 step, Uint64 start)
      if (ndb->getAutoIncrementValue(myTable, tupleId, TUPLEID_FETCH_SIZE, 1, 1) != 0) {
        cerr << "Error occurs while getting tupleID to insert.\n";
        exit(-1);
      }

      myOperation->equal("$PK", tupleId);
      //if (tupleId % 10000 == 0) {
      //  cerr <<"DEBUG: set tupleID to " << tupleId << endl;
      //}
    }
    // Iterate for each field
    int i = 0;
    for (string field; getline(ss, field, field_delim); i++) {

      // For NULL value, do not set value for this field
      if (strcmp(field.c_str(), "\\N") == 0) {
        continue;
      }

      if (strcmp(fieldType[i].c_str(), "int") == 0) {
        // using a int64 to prevent problems..
        long long value = atoll(field.c_str());
        myOperation->setValue(fieldName[i].c_str(), value);
      }

      if (strcmp(fieldType[i].c_str(), "real") == 0) {
        double value = atof(field.c_str());
        myOperation->setValue(fieldName[i].c_str(), value);    
      }
      
      if (strcmp(fieldType[i].c_str(), "varchar") == 0) {
        char buffer[65535] = {};
        make_ndb_varchar(buffer, field.c_str());
        myOperation->setValue(fieldName[i].c_str(), buffer);
      }
      
      if (strcmp(fieldType[i].c_str(), "char") == 0) {
        char buffer[65535] = {};
        make_ndb_char(buffer, field.c_str());
        myOperation->setValue(fieldName[i].c_str(), buffer);
        // myOperation->setValue(fieldName[i].c_str(), field.c_str());
      }

      if (strcmp(fieldType[i].c_str(), "boolean") == 0) {
        int value = atoi(field.c_str());
        myOperation->setValue(fieldName[i].c_str(), value);
      }

      if (strcmp(fieldType[i].c_str(), "text") == 0) {
        NdbBlob *myBlobHandle = myOperation->getBlobHandle(fieldName[i].c_str());
        if (myBlobHandle == NULL) {
          cerr << "Hint: in the TSV file any TEXT/BLOB attribute must come after the primary key column.\n";
          APIERROR(myOperation->getNdbError());
        }
        myBlobHandle->setValue(field.c_str(), field.length());
        // myBlobHandle->setNull();
      }

    }

    transaction[current].conn->executeAsynchPrepare( NdbTransaction::Commit, 
                                         &callback, 
                                         cb
                                         );
    nPreparedTransactions++;
    rowCounter++;
    dataleft = true;
    /**
     * When we have prepared parallelism number of transactions ->
     * send the transaction to ndb. 
     * Next time we will deal with the transactions are in the 
     * callback. There we will see which ones that were successful
     * and which ones to retry.
     */
    if (nPreparedTransactions >= tNoOfParallelTrans)
    {
      // send-poll all transactions
      // close transaction is done in callback
      ndb->sendPollNdb(3000, tNoOfParallelTrans );
      nPreparedTransactions=0;
      dataleft = false;
      
      usleep(sleepTimeMilli);

    }

    // The SYNC way that can set multiple operations in one commit:
    // if (myTransaction->execute( NdbTransaction::NoCommit ) == -1)
    //   APIERROR(myTransaction->getNdbError());

    // if (rowCounter % TRANACTION_SIZE == 0) {
    //   // commit
    //   if (myTransaction->execute( NdbTransaction::Commit ) == -1)
    //     APIERROR(myTransaction->getNdbError());
    //   ndb->closeTransaction(myTransaction);
    //   myTransaction = ndb->startTransaction();
    //   dataleft = false;
    // }

  }

  if (dataleft) {
    ndb->sendPollNdb(3000, nPreparedTransactions );
    nPreparedTransactions=0;
      
    // SYNC way
    // if (myTransaction->execute( NdbTransaction::Commit ) == -1)
    //   APIERROR(myTransaction->getNdbError());
    // ndb->closeTransaction(myTransaction);    
  }

  ndb->waitUntilReady(10000);

  delete ndb;
  disconnect_from_cluster(conn);

  return EXIT_SUCCESS;
}
Пример #8
0
int main(int argc, char* argv[])
{
    ndb_init();
    int iRes = -1;
    g_nNumThreads = 0;
    g_nMaxCallsPerSecond = 0;
    long nSeed = 0;
    bool bStoredTable = true;
    bool bCreateTable = false;
    g_bWriteTuple = false;
    g_bReport = false;
    g_bReportPlus = false;
    
    for(int i=1; i<argc; ++i)
    {
        if(argv[i][0]=='-' || argv[i][0]=='/')
        {
            switch(argv[i][1])
            {
            case 't': 
                g_nNumThreads = atol(argv[i]+2); 
                break;
            case 's': 
                nSeed = atol(argv[i]+2); 
                break;
            case 'b': 
                g_nMaxContextIdPerThread = atol(argv[i]+2); 
                break;
            case 'm': 
                g_nStatusDataSize = atol(argv[i]+2); 
                if(g_nStatusDataSize>sizeof(STATUS_DATA))
                {
                    g_nStatusDataSize = sizeof(STATUS_DATA);
                }
                break;
            case 'i': 
                g_bInsertInitial = true;
                break;
            case 'v': 
                g_bVerifyInitial = true;
                break;
            case 'd':
                bCreateTable = true;
                break;
            case 'f': 
                bStoredTable = false;
                break;
            case 'w': 
                g_bWriteTuple = true;
                break;
            case 'r': 
                g_bReport = true;
                if(argv[i][2]=='+')
                {
                  g_bReportPlus = true;
                }
                break;
            case 'c':
                g_nMaxCallsPerSecond = atol(argv[i]+2);
                break;
            case '?':
            default:
                ShowHelp(argv[0]);
                return -1;
            }
        }
        else
        {
            ShowHelp(argv[0]);
            return -1;
        }
    }
    if(bCreateTable)
        puts("-d\tcreate the table");
    if(g_bInsertInitial)
        printf("-i\tinsert initial records\n");
    if(g_bVerifyInitial)
        printf("-v\tverify initial records\n");
    if(g_nNumThreads>0)
        printf("-t%ld\tnumber of threads making calls\n", g_nNumThreads);
    if(g_nNumThreads>0)
    {
        printf("-s%ld\toffset for primary key\n", nSeed);
        printf("-b%ld\tbatch size per thread\n", g_nMaxContextIdPerThread);
    }
    if(g_nMaxCallsPerSecond>0)
        printf("-c%ld\tmax number of calls per second for this process\n", g_nMaxCallsPerSecond);
    if(!bStoredTable)
        puts("-f\tno checkpointing and no logging to disk");
    if(g_bWriteTuple)
        puts("-w\tuse writeTuple instead of insertTuple");
    if(g_bReport)
        puts("-r\treport response time statistics");
    if(g_bReportPlus)
        puts("-r+\treport response time distribution");

    if(!bCreateTable && g_nNumThreads<=0)
    {
        ShowHelp(argv[0]);
        return -1;
    }
    printf("-m%ld\tsize of context data\n", g_nStatusDataSize);

    g_szTableName = (bStoredTable ? c_szTableNameStored : c_szTableNameTemp);
    
#ifdef NDB_WIN32
    SetConsoleCtrlHandler(ConsoleCtrlHandler, true); 
#else
    signal(SIGINT, CtrlCHandler);
#endif

    if(g_bReport)
    {
      g_plCountMillisecForCall = new long[c_nMaxMillisecForAllCall];
      memset(g_plCountMillisecForCall, 0, c_nMaxMillisecForAllCall*sizeof(long));
      g_plCountMillisecForTrans = new long[c_nMaxMillisecForAllTrans];
      memset(g_plCountMillisecForTrans, 0, c_nMaxMillisecForAllTrans*sizeof(long));
    }
    
    g_pNdbMutexIncrement = NdbMutex_Create();
    g_pNdbMutexPrintf = NdbMutex_Create();
#ifdef NDB_WIN32
    hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
#endif
    
    Ndb* pNdb = new Ndb(c_szDatabaseName);
    if(!pNdb)
    {
        printf("could not construct ndb\n");
        return 1;
    }
    
    if(pNdb->init(1) || pNdb->waitUntilReady())
    {
        ReportNdbError("could not initialize ndb\n", pNdb->getNdbError());
        delete pNdb;
        return 2;
    }

    if(bCreateTable)
    {
        printf("Create CallContext table\n");
	if (bStoredTable)
	{
	  if (CreateCallContextTable(pNdb, c_szTableNameStored, true))
	  {
            printf("Create table failed\n");
            delete pNdb;
            return 3;	    
	  }
	}
	else
	{
	  if (CreateCallContextTable(pNdb, c_szTableNameTemp, false))
	  {
            printf("Create table failed\n");
            delete pNdb;
            return 3;
	  }
	}
    }
    
    if(g_nNumThreads>0) 
    {
        printf("creating %d threads\n", (int)g_nNumThreads);
        if(g_bInsertInitial)
        {
            printf("each thread will insert %ld initial records, total %ld inserts\n", 
                g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread);
        }
        if(g_bVerifyInitial)
        {
            printf("each thread will verify %ld initial records, total %ld reads\n", 
                g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread);
        }

        g_nNumberOfInitialInsert = 0;
        g_nNumberOfInitialVerify = 0;

        NDB_TICKS tStartTime = NdbTick_CurrentMillisecond();
        NdbThread* pThreads[256];
        int pnStartingRecordNum[256];
        int ij;
        for(ij=0;ij<g_nNumThreads;ij++) 
        {
            pnStartingRecordNum[ij] = (ij*g_nMaxContextIdPerThread) + nSeed;
        }
        
        for(ij=0;ij<g_nNumThreads;ij++) 
        {
            pThreads[ij] = NdbThread_Create(RuntimeCallContext, 
                (void**)(pnStartingRecordNum+ij), 
                0, "RuntimeCallContext", NDB_THREAD_PRIO_LOW);
        }
        
        //Wait for the threads to finish
        for(ij=0;ij<g_nNumThreads;ij++) 
        {
            void* status;
            NdbThread_WaitFor(pThreads[ij], &status);
        }
        NDB_TICKS tEndTime = NdbTick_CurrentMillisecond();
        
        //Print time taken
        printf("Time Taken for %ld Calls is %ld msec (= %ld calls/sec)\n",
            g_nNumCallsProcessed, 
            (long)(tEndTime-tStartTime), 
            (long)((1000*g_nNumCallsProcessed)/(tEndTime-tStartTime)));

        if(g_bInsertInitial)
            printf("successfully inserted %ld tuples\n", g_nNumberOfInitialInsert);
        if(g_bVerifyInitial)
            printf("successfully verified %ld tuples\n", g_nNumberOfInitialVerify);
    }
    
    delete pNdb;

#ifdef NDB_WIN32
    CloseHandle(hShutdownEvent);
#endif
    NdbMutex_Destroy(g_pNdbMutexIncrement);
    NdbMutex_Destroy(g_pNdbMutexPrintf);

    if(g_bReport)
    {
      ReportResponseTimeStatistics("Calls", g_plCountMillisecForCall, c_nMaxMillisecForAllCall);
      ReportResponseTimeStatistics("Transactions", g_plCountMillisecForTrans, c_nMaxMillisecForAllTrans);

      delete[] g_plCountMillisecForCall;
      delete[] g_plCountMillisecForTrans;
    }

    return 0;
}
Пример #9
0
void* RuntimeCallContext(void* lpParam)
{
    long nNumCallsProcessed = 0;
    int nStartingRecordID = *(int*)lpParam;
    
    Ndb* pNdb;
    char* pchContextData = new char[g_nStatusDataSize];
    char szMsg[100];
    
    int iRes;
    const char* szOp;
    long iVersion;
    long iLockFlag;
    long iLockTime;
    long iLockTimeUSec;
    
    pNdb = new Ndb("TEST_DB");
    if(!pNdb)
    {
        NdbMutex_Lock(g_pNdbMutexPrintf);
        printf("new Ndb failed\n");
        NdbMutex_Unlock(g_pNdbMutexPrintf);
        delete[] pchContextData;
        return 0;
    }
    
    if(pNdb->init(1) || pNdb->waitUntilReady())
    {
        ReportNdbError("init of Ndb failed", pNdb->getNdbError());
        delete pNdb;
        delete[] pchContextData;
        return 0;
    }

    if(g_bInsertInitial)
    {
        if(InsertInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread))
        {
            delete pNdb;
            delete[] pchContextData;
            return 0;
        }
    }

    if(g_bVerifyInitial)
    {
        NdbError err;
        memset(&err, 0, sizeof(err));
        if(VerifyInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread))
        {
            delete pNdb;
            delete[] pchContextData;
            return 0;
        }
    }
    if(g_bInsertInitial || g_bVerifyInitial)
    {
        delete[] pchContextData;
        return 0;
    }

    long nContextID = nStartingRecordID;
#ifdef NDB_WIN32
    while(WaitForSingleObject(hShutdownEvent,0) != WAIT_OBJECT_0)
#else
    while(!bShutdownEvent)
#endif
    {
        ++nContextID;
        nContextID %= g_nMaxContextIdPerThread;
        nContextID += nStartingRecordID;

        bool bTimeLatency = (nContextID==100);
        
        NDB_TICKS tStartCall = NdbTick_CurrentMillisecond();
        for (int i=0; i < 20; i++)
        {
            int nRetry = 0;
            NdbError err;
            memset(&err, 0, sizeof(err));
            NDB_TICKS tStartTrans = NdbTick_CurrentMillisecond();
            switch(i)
            {
            case 3:
            case 6:
            case 9: 
            case 11: 
            case 12: 
            case 15: 
            case 18:   // Query Record
                szOp = "Read";
                iRes = RetryQueryTransaction(pNdb, nContextID, &iVersion, &iLockFlag, 
                    &iLockTime, &iLockTimeUSec, pchContextData, err, nRetry);
                break;
                
            case 19:    // Delete Record
                szOp = "Delete";
                iRes = RetryDeleteTransaction(pNdb, nContextID, err, nRetry);
                break;
                
            case 0: // Insert Record
                szOp = "Insert";
                iRes = RetryInsertTransaction(pNdb, nContextID, 1, 1, 1, 1, STATUS_DATA, err, nRetry);
                break;
                
            default:    // Update Record
                szOp = "Update";
                iRes = RetryUpdateTransaction(pNdb, nContextID, err, nRetry);
                break;
            }
            NDB_TICKS tEndTrans = NdbTick_CurrentMillisecond();
            long lMillisecForThisTrans = (long)(tEndTrans-tStartTrans);

            if(g_bReport)
            {
              assert(lMillisecForThisTrans>=0 && lMillisecForThisTrans<c_nMaxMillisecForAllTrans);
              InterlockedIncrement(g_plCountMillisecForTrans+lMillisecForThisTrans);
            }

            if(nRetry>0)
            {
                sprintf(szMsg, "%s retried %d times, time %ld msec.", 
                    szOp, nRetry, lMillisecForThisTrans);
                ReportNdbError(szMsg, err);
            }
            else if(bTimeLatency)
            {
                NdbMutex_Lock(g_pNdbMutexPrintf);
                printf("%s = %ld msec.\n", szOp, lMillisecForThisTrans);
                NdbMutex_Unlock(g_pNdbMutexPrintf);
            }

            if(iRes)
            {
                sprintf(szMsg, "%s failed after %ld calls, terminating thread", 
                    szOp, nNumCallsProcessed);
                ReportNdbError(szMsg, err);
                delete pNdb;
                delete[] pchContextData;
                return 0;
            }
        }
        NDB_TICKS tEndCall = NdbTick_CurrentMillisecond();
        long lMillisecForThisCall = (long)(tEndCall-tStartCall);

        if(g_bReport)
        {
          assert(lMillisecForThisCall>=0 && lMillisecForThisCall<c_nMaxMillisecForAllCall);
          InterlockedIncrement(g_plCountMillisecForCall+lMillisecForThisCall);
        }

        if(bTimeLatency)
        {
            NdbMutex_Lock(g_pNdbMutexPrintf);
            printf("Total time for call is %ld msec.\n", (long)lMillisecForThisCall);
            NdbMutex_Unlock(g_pNdbMutexPrintf);
        }
        
        nNumCallsProcessed++;
        InterlockedIncrementAndReport();
        if(g_nMaxCallsPerSecond>0)
        {
            int iMillisecToSleep = (1000*g_nNumThreads)/g_nMaxCallsPerSecond;
            iMillisecToSleep -= lMillisecForThisCall;
            if(iMillisecToSleep>0)
            {
                NdbSleep_MilliSleep(iMillisecToSleep);
            }
        }
    }

    NdbMutex_Lock(g_pNdbMutexPrintf);
    printf("Terminating thread after %ld calls\n", nNumCallsProcessed);
    NdbMutex_Unlock(g_pNdbMutexPrintf);
    
    delete pNdb;
    delete[] pchContextData;
    return 0;
}
Пример #10
0
int main(int argc, const char** argv) {
    ndb_init();

    int operationType = 0;
    int tupTest = 0;
    int scanTest = 0;

    Ndb* pNdb = new Ndb("TEST_DB");
    pNdb->init();

    if (argc != 4  ||  sscanf(argv[1],"%d", &operationType) != 1) {
        operationType = 1 ;
    }
    if (argc != 4  ||  sscanf(argv[2],"%d", &tupTest) != 1) {
        tupTest = 1 ;
    }
    if (argc != 4  ||  sscanf(argv[3],"%d", &scanTest) != 1) {
        scanTest = 1 ;
    }

    ndbout << endl
           << "Test the interpreter in TUP using SimpleTable with\n"
           << nRecords << " records" << endl << endl ;

    if (pNdb->waitUntilReady(30) != 0) {
        ndbout << "NDB is not ready" << endl;
        return -1;
    }

    // Init the pk and attr values.
    for (int i = 0; i < NUMBEROFRECORDS; i ++)
        pkValue[i] = attrValue[i] = i ;

    setAttrNames() ;
    setTableNames() ;

    const void * p = NDBT_Table::discoverTableFromDb(pNdb, tableName);
    if (p != 0) {
        create_table(pNdb);
    }

    write_rows(pNdb);

    ndbout << endl << "Starting interpreter in TUP test." << endl << "Operation type: " ;

    switch(operationType) {
    case 1:
        ndbout << "openScanRead" << endl;
        scan_rows(pNdb,  operationType,  tupTest,  scanTest);
        break;
    case 2:
        ndbout << "openScanExclusive" << endl;
        scan_rows(pNdb,  operationType,  tupTest,  scanTest);
        break;
    case 3:
        ndbout << "interpretedUpdateTuple" << endl;
        update_rows(pNdb,  tupTest,  operationType);
        break;
    case 4:
        ndbout << "interpretedDirtyUpdate" << endl;
        update_rows(pNdb,  tupTest,  operationType);
        break;
    case 5:
        ndbout << "interpretedDeleteTuple" << endl;
        delete_rows(pNdb,  tupTest,  operationType);
        break;
    case 6:
        ndbout << "deleteTuple" << endl;
        break;
    case 7:
        ndbout << "insertTuple" << endl;
        break;
    case 8:
        ndbout << "updateTuple" << endl;
        break;
    case 9:
        ndbout << "writeTuple" << endl;
        break;
    case 10:
        ndbout << "readTuple" << endl;
        break;
    case 11:
        ndbout << "readTupleExclusive" << endl;
        break;
    case 12:
        ndbout << "simpleRead" << endl;
        break;
    case 13:
        ndbout << "dirtyRead" << endl;
        break;
    case 14:
        ndbout << "dirtyUpdate" << endl;
        break;
    case 15:
        ndbout << "dirtyWrite" << endl;
        break;
    default:
        break ;

    }

//  read_and_verify_rows(pNdb, false);

//  delete_rows(pNdb, 0, 0) ;
    delete pNdb ;

    if (bTestPassed == 0) {
        ndbout << "OK: test passed" << endl;
        exit(0);
    } else {
        ndbout << "FAIL: test failed" << endl;
        exit(-1);
    }
}