Ndb* JniNdbEventStreamingImp::create_ndb_connection(const char* database) {
    Ndb* ndb = new Ndb(mClusterConnection, database);
    if (ndb->init() == -1) {

        LOG_NDB_API_ERROR(ndb->getNdbError());
    }

    return ndb;
}
Пример #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;
}
Ndb * NdbPool::getNdb() {
  Ndb * n;
  lock();
  if(list) {
    n = list;
    list = (Ndb *) n->getCustomData();
    size--;
  }
  else {
    n = new Ndb(conn);
    n->init();
    created++;
  }
  unlock();
  return n;
}
Пример #4
0
static int
prepare_master_or_slave(Ndb &myNdb,
                        const char* table,
                        const char* pk,
                        Uint32 pk_val,
                        const char* col,
                        struct Xxx &xxx,
                        struct XxxR &xxxr)
{
  if (myNdb.init())
    APIERROR(myNdb.getNdbError());
  const NdbDictionary::Dictionary* myDict = myNdb.getDictionary();
  const NdbDictionary::Table *myTable = myDict->getTable(table);
  if (myTable == NULL) 
    APIERROR(myDict->getNdbError());
  const NdbDictionary::Column *myPkCol = myTable->getColumn(pk);
  if (myPkCol == NULL)
    APIERROR(myDict->getNdbError());
  if (myPkCol->getType() != NdbDictionary::Column::Unsigned)
  {
    PRINT_ERROR(0, "Primary key column not of type unsigned");
    exit(-1);
  }
  const NdbDictionary::Column *myCol = myTable->getColumn(col);
  if (myCol == NULL)
    APIERROR(myDict->getNdbError());
  if (myCol->getType() != NdbDictionary::Column::Unsigned)
  {
    PRINT_ERROR(0, "Update column not of type unsigned");
    exit(-1);
  }

  xxx.ndb = &myNdb;
  xxx.table = myTable;
  xxx.pk_col = myPkCol->getColumnNo();
  xxx.col = myCol->getColumnNo();

  xxxr.pk_val = pk_val;

  return 0;
}
Пример #5
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;
}
Пример #6
0
static int
ndb_db_open( BackendDB *be, ConfigReply *cr )
{
	struct ndb_info *ni = (struct ndb_info *) be->be_private;
	char sqlbuf[BUFSIZ], *ptr;
	int rc, i;

	if ( be->be_suffix == NULL ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: need suffix" );
		Debug( LDAP_DEBUG_ANY, "%s\n",
			cr->msg, 0, 0 );
		return -1;
	}

	Debug( LDAP_DEBUG_ARGS,
		LDAP_XSTRING(ndb_db_open) ": \"%s\"\n",
		be->be_suffix[0].bv_val, 0, 0 );

	if ( ni->ni_nconns < 1 )
		ni->ni_nconns = 1;

	ni->ni_cluster = (Ndb_cluster_connection **)ch_calloc( ni->ni_nconns, sizeof( Ndb_cluster_connection *));
	for ( i=0; i<ni->ni_nconns; i++ ) {
		ni->ni_cluster[i] = new Ndb_cluster_connection( ni->ni_connectstr );
		rc = ni->ni_cluster[i]->connect( 20, 5, 1 );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ni_cluster[%d]->connect failed (%d)",
				i, rc );
			goto fail;
		}
	}
	for ( i=0; i<ni->ni_nconns; i++ ) {
		rc = ni->ni_cluster[i]->wait_until_ready( 30, 30 );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ni_cluster[%d]->wait failed (%d)",
				i, rc );
			goto fail;
		}
	}

	mysql_init( &ni->ni_sql );
	if ( !mysql_real_connect( &ni->ni_sql, ni->ni_hostname, ni->ni_username, ni->ni_password,
		"", ni->ni_port, ni->ni_socket, ni->ni_clflag )) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: mysql_real_connect failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		rc = -1;
		goto fail;
	}

	sprintf( sqlbuf, "CREATE DATABASE IF NOT EXISTS %s", ni->ni_dbname );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE DATABASE %s failed, %s (%d)",
			ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	sprintf( sqlbuf, "USE %s", ni->ni_dbname );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: USE DATABASE %s failed, %s (%d)",
			ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	ptr = sqlbuf;
	ptr += sprintf( ptr, "CREATE TABLE IF NOT EXISTS " DN2ID_TABLE " ("
		"eid bigint unsigned NOT NULL, "
		"object_classes VARCHAR(1024) NOT NULL, "
		"a0 VARCHAR(128) NOT NULL DEFAULT '', "
		"a1 VARCHAR(128) NOT NULL DEFAULT '', "
		"a2 VARCHAR(128) NOT NULL DEFAULT '', "
		"a3 VARCHAR(128) NOT NULL DEFAULT '', "
		"a4 VARCHAR(128) NOT NULL DEFAULT '', "
		"a5 VARCHAR(128) NOT NULL DEFAULT '', "
		"a6 VARCHAR(128) NOT NULL DEFAULT '', "
		"a7 VARCHAR(128) NOT NULL DEFAULT '', "
		"a8 VARCHAR(128) NOT NULL DEFAULT '', "
		"a9 VARCHAR(128) NOT NULL DEFAULT '', "
		"a10 VARCHAR(128) NOT NULL DEFAULT '', "
		"a11 VARCHAR(128) NOT NULL DEFAULT '', "
		"a12 VARCHAR(128) NOT NULL DEFAULT '', "
		"a13 VARCHAR(128) NOT NULL DEFAULT '', "
		"a14 VARCHAR(128) NOT NULL DEFAULT '', "
		"a15 VARCHAR(128) NOT NULL DEFAULT '', "
		"PRIMARY KEY (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), "
		"UNIQUE KEY eid (eid) USING HASH" );
	/* Create index columns */
	if ( ni->ni_attridxs ) {
		ListNode *ln;
		int newcol = 0;

		*ptr++ = ',';
		*ptr++ = ' ';
		for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
			NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
			ptr += sprintf( ptr, "`%s` VARCHAR(%d), ",
				ai->na_name.bv_val, ai->na_len );
		}
		ptr = lutil_strcopy(ptr, "KEY " INDEX_NAME " (" );

		for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
			NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
			if ( newcol ) *ptr++ = ',';
			*ptr++ = '`';
			ptr = lutil_strcopy( ptr, ai->na_name.bv_val );
			*ptr++ = '`';
			ai->na_ixcol = newcol + 18;
			newcol++;
		}
		*ptr++ = ')';
	}
	strcpy( ptr, ") ENGINE=ndb" );
	rc = mysql_query( &ni->ni_sql, sqlbuf );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE TABLE " DN2ID_TABLE " failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	rc = mysql_query( &ni->ni_sql, "CREATE TABLE IF NOT EXISTS " NEXTID_TABLE " ("
		"a bigint unsigned AUTO_INCREMENT PRIMARY KEY ) ENGINE=ndb" );
	if ( rc ) {
		snprintf( cr->msg, sizeof( cr->msg ),
			"ndb_db_open: CREATE TABLE " NEXTID_TABLE " failed, %s (%d)",
			mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		goto fail;
	}

	{
		NdbOcInfo *oci;

		rc = ndb_aset_get( ni, &ndb_optable, ndb_opattrs, &oci );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ndb_aset_get( %s ) failed (%d)",
				ndb_optable.bv_val, rc );
			goto fail;
		}
		for ( i=0; ndb_oplens[i] >= 0; i++ ) {
			if ( ndb_oplens[i] )
				oci->no_attrs[i]->na_len = ndb_oplens[i];
		}
		rc = ndb_aset_create( ni, oci );
		if ( rc ) {
			snprintf( cr->msg, sizeof( cr->msg ),
				"ndb_db_open: ndb_aset_create( %s ) failed (%d)",
				ndb_optable.bv_val, rc );
			goto fail;
		}
		ni->ni_opattrs = oci;
	}
	/* Create attribute sets */
	{
		ListNode *ln;

		for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
			NdbOcInfo *oci = (NdbOcInfo *)ln->ln_data;
			rc = ndb_aset_create( ni, oci );
			if ( rc ) {
				snprintf( cr->msg, sizeof( cr->msg ),
					"ndb_db_open: ndb_aset_create( %s ) failed (%d)",
					oci->no_name.bv_val, rc );
				goto fail;
			}
		}
	}
	/* Initialize any currently used objectClasses */
	{
		Ndb *ndb;
		const NdbDictionary::Dictionary *myDict;

		ndb = new Ndb( ni->ni_cluster[0], ni->ni_dbname );
		ndb->init(1024);

		myDict = ndb->getDictionary();
		ndb_oc_read( ni, myDict );
		delete ndb;
	}

#ifdef DO_MONITORING
	/* monitor setup */
	rc = ndb_monitor_db_open( be );
	if ( rc != 0 ) {
		goto fail;
	}
#endif

	return 0;

fail:
	Debug( LDAP_DEBUG_ANY, "%s\n",
		cr->msg, 0, 0 );
	ndb_db_close( be, NULL );
	return rc;
}
Пример #7
0
/* Ndb constructor.
   create_ndb(Ndb_cluster_connection, databaseName, callback)
   The constructor is wrapped in a call that also calls ndb->init().
*/
Ndb * async_create_ndb(Ndb_cluster_connection *conn, const char *db) {
  Ndb *ndb = new Ndb(conn, db);
  DEBUG_PRINT("Created Ndb %p", ndb);  
  if(ndb) ndb->init();
  return ndb;
}
Пример #8
0
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();
  }
}
Пример #9
0
int main(int argc, char ** argv)
{
  ndb_init();
  /**
   * define a connect string to the management server
   */
  

  memset( ndbconnectstring,0,255);
  memset( database,0,255);
  memset( tablename,0,255);
  strcpy(ndbconnectstring, "localhost:1186");
  strcpy(database, "");

  option(argc,argv);
  if(strcmp(tablename,"")==0)
    {
      g_analyze_all=true;
    }
  
  char * db;
  if(strcmp(database,"")==0)
    db=0;
  else
    db=database;

  char * table = tablename;

  /**
   * Create a Ndb_cluster_connection object using the connectstring
   */
  Ndb_cluster_connection * conn = new Ndb_cluster_connection(ndbconnectstring);


  /**
   * Connect to the management server
   * try 12 times, wait 5 seconds between each retry,
   * and be verbose (1), if connection attempt failes
   */
  if(conn->connect(12, 5, 1) != 0)
    {
      printf( "Unable to connect to management server." );
      return -1;
    }

  /**
   * Join the cluster
   * wait for 30 seconds for first node to be alive, and 0 seconds
   * for the rest.
   */
  if (conn->wait_until_ready(30,0) <0)
    {
      printf( "Cluster nodes not ready in 30 seconds." );
      return -1;
    }



  /**
   * The first thing we have to do is to instantiate an Ndb object.
   * The Ndb object represents a connection to a database.
   * It is important to note that the Ndb object is not thread safe!!
   * Thus, if it is a multi-threaded application, then typically each thread
   * uses its own Ndb object.
   *
   * Now we create an Ndb object that connects to the test database.
   */

  Ndb * ndb = new Ndb(conn);


  if (ndb->init() != 0)
    {
      /**
       * just exit if we can't initialize the Ndb object
       */
      return -1;
    }
  if(ftScan)
    {
      if(g_analyze_all)
	printf("Analyzing all tables. This may take a while.\n");
      else
	printf("Analyzing entire table. This may take a while.\n");
    }

  if (ignoreData) 
    {
       printf("record in database will be ignored.\n");
    }
 
  memset(g_all_tables,0,sizeof(g_all_tables));
  memset(g_all_dbs,0,sizeof(g_all_dbs));
  char filename[255];  
  if(g_analyze_all)
    {
      if(db!=0)
	sprintf(filename,"%s.csv",db); 
      else
	{
	  strcpy(filename,"all_databases.csv"); 
	  g_multi_db=true;
	}

      list_tables(ndb,db);
    }
  else
    {
      if(db==0)
	{
	  printf("You must specify the database when analyzing only one table\n");
	  exit(1);
	}
      g_count=1;
      sprintf(filename,"%s_%s.csv",db,table); 
      strcpy(g_all_tables[0], table);
    }
  FILE * fh =  fopen(filename,"w+");
  fclose(fh);
  for(int i=0;i<g_count;i++)
    {
      
      if(db!=0)
	{
	  if (supersizeme(ndb, db,  g_all_tables[i], ftScan,ignoreData ) <0)
	    return -1;
	}else
	{
	  if (supersizeme(ndb, g_all_dbs[i],  g_all_tables[i], ftScan,ignoreData) <0)
	    return -1;
	}
      printf("----------------------------------------------------\n");
    }

  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);
    }
}
Пример #11
0
int main(int argc, char** argv)
{
  if (argc != 3)
    {
    std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
    exit(-1);
  }
  char * mysqld_sock  = argv[1];
  const char *connectstring = argv[2];
  ndb_init();
  MYSQL mysql;

  /**************************************************************
   * Connect to mysql server and create table                   *
   **************************************************************/
  {
    if ( !mysql_init(&mysql) ) {
      std::cout << "mysql_init failed\n";
      exit(-1);
    }
    if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
			     0, mysqld_sock, 0) )
      MYSQLERROR(mysql);

    mysql_query(&mysql, "CREATE DATABASE ndb_examples_1");
    if (mysql_query(&mysql, "USE ndb_examples") != 0) MYSQLERROR(mysql);

    while (mysql_query(&mysql, 
		    "CREATE TABLE"
		    "  api_simple_index"
		    "    (ATTR1 INT UNSIGNED,"
		    "     ATTR2 INT UNSIGNED NOT NULL,"
		    "     PRIMARY KEY USING HASH (ATTR1),"
		    "     UNIQUE MYINDEXNAME USING HASH (ATTR2))"
		    "  ENGINE=NDB"))
    {
      if (mysql_errno(&mysql) == ER_TABLE_EXISTS_ERROR)
      {
        std::cout << "MySQL Cluster already has example table: api_scan. "
        << "Dropping it..." << std::endl; 
        mysql_query(&mysql, "DROP TABLE api_simple_index");
      }
      else MYSQLERROR(mysql);
    }
  }
 
  /**************************************************************
   * Connect to ndb cluster                                     *
   **************************************************************/

  Ndb_cluster_connection *cluster_connection=
    new Ndb_cluster_connection(connectstring); // Object representing the cluster

  if (cluster_connection->connect(5,3,1))
  {
    std::cout << "Connect to cluster management server failed.\n";
    exit(-1);
  }

  if (cluster_connection->wait_until_ready(30,30))
  {
    std::cout << "Cluster was not ready within 30 secs.\n";
    exit(-1);
  }

  Ndb* myNdb = new Ndb( cluster_connection,
			"ndb_examples" );  // Object representing the database
  if (myNdb->init() == -1) { 
    APIERROR(myNdb->getNdbError());
    exit(-1);
  }

  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("api_simple_index");
  if (myTable == NULL)
    APIERROR(myDict->getNdbError());
  const NdbDictionary::Index *myIndex= myDict->getIndex("MYINDEXNAME$unique","api_simple_index");
  if (myIndex == NULL)
    APIERROR(myDict->getNdbError());

  /**************************************************************************
   * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) *
   **************************************************************************/
  for (int i = 0; i < 5; i++) {
    NdbTransaction *myTransaction= myNdb->startTransaction();
    if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
    
    NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
    if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
    
    myOperation->insertTuple();
    myOperation->equal("ATTR1", i);
    myOperation->setValue("ATTR2", i);

    myOperation = myTransaction->getNdbOperation(myTable);	
    if (myOperation == NULL) APIERROR(myTransaction->getNdbError());

    myOperation->insertTuple();
    myOperation->equal("ATTR1", i+5);
    myOperation->setValue("ATTR2", i+5);
    
    if (myTransaction->execute( NdbTransaction::Commit ) == -1)
      APIERROR(myTransaction->getNdbError());
    
    myNdb->closeTransaction(myTransaction);
  }
  
  /*****************************************
   * Read and print all tuples using index *
   *****************************************/
  std::cout << "ATTR1 ATTR2" << std::endl;
  
  for (int i = 0; i < 10; i++) {
    NdbTransaction *myTransaction= myNdb->startTransaction();
    if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
    
    NdbIndexOperation *myIndexOperation=
      myTransaction->getNdbIndexOperation(myIndex);
    if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
    
    myIndexOperation->readTuple(NdbOperation::LM_Read);
    myIndexOperation->equal("ATTR2", i);
    
    NdbRecAttr *myRecAttr= myIndexOperation->getValue("ATTR1", NULL);
    if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());

    if(myTransaction->execute( NdbTransaction::Commit,
                               NdbOperation::AbortOnError ) != -1)
      printf(" %2d    %2d\n", myRecAttr->u_32_value(), i);

    myNdb->closeTransaction(myTransaction);
  }

  /*****************************************************************
   * Update the second attribute in half of the tuples (adding 10) *
   *****************************************************************/
  for (int i = 0; i < 10; i+=2) {
    NdbTransaction *myTransaction= myNdb->startTransaction();
    if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
    
    NdbIndexOperation *myIndexOperation=
      myTransaction->getNdbIndexOperation(myIndex);
    if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
    
    myIndexOperation->updateTuple();
    myIndexOperation->equal( "ATTR2", i );
    myIndexOperation->setValue( "ATTR2", i+10);
    
    if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) 
      APIERROR(myTransaction->getNdbError());
    
    myNdb->closeTransaction(myTransaction);
  }
  
  /*************************************************
   * Delete one tuple (the one with primary key 3) *
   *************************************************/
  {
    NdbTransaction *myTransaction= myNdb->startTransaction();
    if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
  
    NdbIndexOperation *myIndexOperation=
      myTransaction->getNdbIndexOperation(myIndex);
    if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
  
    myIndexOperation->deleteTuple();
    myIndexOperation->equal( "ATTR2", 3 );
  
    if (myTransaction->execute(NdbTransaction::Commit) == -1) 
      APIERROR(myTransaction->getNdbError());
  
    myNdb->closeTransaction(myTransaction);
  }

  /*****************************
   * Read and print all tuples *
   *****************************/
  {
    std::cout << "ATTR1 ATTR2" << std::endl;
  
    for (int i = 0; i < 10; i++) {
      NdbTransaction *myTransaction= myNdb->startTransaction();
      if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
      
      NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
      if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
    
      myOperation->readTuple(NdbOperation::LM_Read);
      myOperation->equal("ATTR1", i);
    
      NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL);
      if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());
    
      if(myTransaction->execute( NdbTransaction::Commit,
                                 NdbOperation::AbortOnError ) == -1)
	if (i == 3) {
	  std::cout << "Detected that deleted tuple doesn't exist!\n";
	} else {
	  APIERROR(myTransaction->getNdbError());
	}
    
      if (i != 3) {
	printf(" %2d    %2d\n", i, myRecAttr->u_32_value());
      }
      myNdb->closeTransaction(myTransaction);
    }
  }

  delete myNdb;
  delete cluster_connection;

  ndb_end(0);
  return 0;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #14
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;
}
int runPkReadMultiBasic(NDBT_Context* ctx, NDBT_Step* step){
  int loops = ctx->getNumLoops();
  int records = ctx->getNumRecords();
  const int MAX_NDBS = 200;
  Ndb* pNdb = GETNDB(step);
  Ndb_cluster_connection* conn = &pNdb->get_ndb_cluster_connection();

  int i = 0;
  HugoOperations hugoOps(*ctx->getTab());

  Ndb* ndbObjs[ MAX_NDBS ];
  NdbTransaction* transArray[ MAX_NDBS ];
  Ndb ** ready_ndbs;

  for (int j=0; j < MAX_NDBS; j++)
  {
    Ndb* ndb = new Ndb(conn);
    check(ndb->init() == 0, (*ndb));
    ndbObjs[ j ] = ndb;
  }

  while (i<loops) {
    ndbout << "Loop : " << i << ": ";
    int recordsLeft = records;

    do
    {
      /* Define and execute Pk read requests on
       * different Ndb objects
       */
      int ndbcnt = 0;
      int pollcnt = 0;
      int lumpsize = 1 + myRandom48(MIN(recordsLeft, MAX_NDBS));
      while(lumpsize &&
            recordsLeft &&
            ndbcnt < MAX_NDBS)
      {
        Ndb* ndb = ndbObjs[ ndbcnt ];
        NdbTransaction* trans = ndb->startTransaction();
        check(trans != NULL, (*ndb));
        NdbOperation* readOp = trans->getNdbOperation(ctx->getTab());
        check(readOp != NULL, (*trans));
        check(readOp->readTuple() == 0, (*readOp));
        check(hugoOps.equalForRow(readOp, recordsLeft) == 0, hugoOps);

        /* Read all other cols */
        for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++)
        {
          check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL,
                (*readOp));
        }

        /* Now send em off */
        trans->executeAsynchPrepare(NdbTransaction::Commit,
                                    NULL,
                                    NULL,
                                    NdbOperation::AbortOnError);
        ndb->sendPreparedTransactions();

        transArray[ndbcnt] = trans;
        global_poll_group->addNdb(ndb);

        ndbcnt++;
        pollcnt++;
        recordsLeft--;
        lumpsize--;
      };

      /* Ok, now wait for the Ndbs to complete */
      while (pollcnt)
      {
        /* Occasionally check with no timeout */
        Uint32 timeout_millis = myRandom48(2)?10000:0;
        int count = global_poll_group->wait(ready_ndbs, timeout_millis);

        if (count > 0)
        {
          for (int y=0; y < count; y++)
          {
            Ndb *ndb = ready_ndbs[y];
            check(ndb->pollNdb(0, 1) != 0, (*ndb));
          }
          pollcnt -= count;
        }
      }

      /* Ok, now close the transactions */
      for (int t=0; t < ndbcnt; t++)
      {
        transArray[t]->close();
      }
    } while (recordsLeft);

    i++;
  }

  for (int j=0; j < MAX_NDBS; j++)
  {
    delete ndbObjs[ j ];
  }

  return NDBT_OK;
}
Пример #16
0
int main(int argc, char** argv)
{
  if (argc != 3)
  {
    std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
    exit(-1);
  }
  char * mysqld_sock  = argv[1];
  const char *connectstring = argv[2];
  ndb_init();
  MYSQL mysql;

  /**************************************************************
   * Connect to mysql server and create table                   *
   **************************************************************/
  {
    if ( !mysql_init(&mysql) ) {
      std::cout << "mysql_init failed\n";
      exit(-1);
    }
    if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
			     0, mysqld_sock, 0) )
      MYSQLERROR(mysql);

    mysql_query(&mysql, "CREATE DATABASE ndb_examples");
    if (mysql_query(&mysql, "USE ndb_examples") != 0) MYSQLERROR(mysql);

    create_table(mysql);
  }

  /**************************************************************
   * Connect to ndb cluster                                     *
   **************************************************************/
  Ndb_cluster_connection cluster_connection(connectstring);
  if (cluster_connection.connect(4, 5, 1))
  {
    std::cout << "Unable to connect to cluster within 30 secs." << std::endl;
    exit(-1);
  }
  // Optionally connect and wait for the storage nodes (ndbd's)
  if (cluster_connection.wait_until_ready(30,0) < 0)
  {
    std::cout << "Cluster was not ready within 30 secs.\n";
    exit(-1);
  }

  Ndb* myNdb = new Ndb( &cluster_connection,
			"ndb_examples" );  // Object representing the database
  if (myNdb->init(1024) == -1) {      // Set max 1024 parallel transactions
    APIERROR(myNdb->getNdbError());
  }

  /**
   * Initialise transaction array
   */
  for(int i = 0 ; i < 10 ; i++) 
  {
    transaction[i].used = 0;
    transaction[i].conn = 0;
    
  }
  int i=0;
  /**
   * Do 10 insert transactions.
   */
  while(i < 10) 
  {
    while(populate(myNdb,i,0)<0)  // <0, no space on free list. Sleep and try again.
      milliSleep(10);
      
    i++;
  }
  std::cout << "Number of temporary errors: " << tempErrors << std::endl;
  delete myNdb; 
}
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;
}
Пример #18
0
int main(int argc, char** argv)
{
  if (argc != 3)
  {
    std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
    exit(-1);
  }
  char * mysqld_sock  = argv[1];
  const char *connectstring = argv[2];
  ndb_init();

  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,0) < 0)
  {
    std::cout << "Cluster was not ready within 30 secs." << std::endl;
    exit(-1);
  }
					   
  // connect to mysql server
  MYSQL mysql;
  if ( !mysql_init(&mysql) ) {
    std::cout << "mysql_init failed\n";
    exit(-1);
  }
  if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
			   0, mysqld_sock, 0) )
    MYSQLERROR(mysql);
  
  /********************************************
   * Connect to database via mysql-c          *
   ********************************************/
  mysql_query(&mysql, "CREATE DATABASE TEST_DB_1");
  if (mysql_query(&mysql, "USE TEST_DB_1") != 0) MYSQLERROR(mysql);
  create_table(mysql);

  Ndb* myNdb = new Ndb( cluster_connection,
			"TEST_DB_1" );  // Object representing the database

  NdbTransaction*  myNdbTransaction[2];   // For transactions
  NdbOperation*   myNdbOperation;       // For operations
  
  if (myNdb->init(2) == -1) {          // Want two parallel insert transactions
    APIERROR(myNdb->getNdbError());
    exit(-1);
  }

  /******************************************************
   * Insert (we do two insert transactions in parallel) *
   ******************************************************/
  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME");
  if (myTable == NULL)
    APIERROR(myDict->getNdbError());
  for (int i = 0; i < 2; i++) {
    myNdbTransaction[i] = myNdb->startTransaction();
    if (myNdbTransaction[i] == NULL) APIERROR(myNdb->getNdbError());
    
    myNdbOperation = myNdbTransaction[i]->getNdbOperation(myTable);
    if (myNdbOperation == NULL) APIERROR(myNdbTransaction[i]->getNdbError());
    
    myNdbOperation->insertTuple();
    myNdbOperation->equal("ATTR1", 20 + i);
    myNdbOperation->setValue("ATTR2", 20 + i);
    
    // Prepare transaction (the transaction is NOT yet sent to NDB)
    myNdbTransaction[i]->executeAsynchPrepare(NdbTransaction::Commit,
					      &callback, NULL);
  }

  // Send all transactions to NDB 
  myNdb->sendPreparedTransactions(0);
  
  // Poll all transactions
  myNdb->pollNdb(3000, 2);
  
  // Close all transactions
  for (int i = 0; i < 2; i++) 
    myNdb->closeTransaction(myNdbTransaction[i]);

  delete myNdb;
  delete cluster_connection;

  drop_table(mysql);

  ndb_end(0);
  return 0;
}
Пример #19
0
int main()
{
  ndb_init();

  Ndb_cluster_connection *cluster_connection=
    new Ndb_cluster_connection(); // Object representing the cluster

  if (cluster_connection->wait_until_ready(30,30))
  {
    std::cout << "Cluster was not ready within 30 secs." << std::endl;
    exit(-1);
  }

  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_2" );  // Object representing the database

  NdbTransaction*  myNdbTransaction[2];   // For transactions
  NdbOperation*   myNdbOperation;       // For operations
  
  if (myNdb->init(2) == -1) {          // Want two parallel insert transactions
    APIERROR(myNdb->getNdbError());
    exit(-1);
  }

  /******************************************************
   * Insert (we do two insert transactions in parallel) *
   ******************************************************/
  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME");
  if (myTable == NULL)
    APIERROR(myDict->getNdbError());
  for (int i = 0; i < 2; i++) {
    myNdbTransaction[i] = myNdb->startTransaction();
    if (myNdbTransaction[i] == NULL) APIERROR(myNdb->getNdbError());
    
    myNdbOperation = myNdbTransaction[i]->getNdbOperation(myTable);
    if (myNdbOperation == NULL) APIERROR(myNdbTransaction[i]->getNdbError());
    
    myNdbOperation->insertTuple();
    myNdbOperation->equal("ATTR1", 20 + i);
    myNdbOperation->setValue("ATTR2", 20 + i);
    
    // Prepare transaction (the transaction is NOT yet sent to NDB)
    myNdbTransaction[i]->executeAsynchPrepare(NdbTransaction::Commit,
					      &callback, NULL);
  }

  // Send all transactions to NDB 
  myNdb->sendPreparedTransactions(0);
  
  // Poll all transactions
  myNdb->pollNdb(3000, 2);
  
  // Close all transactions
  for (int i = 0; i < 2; i++) 
    myNdb->closeTransaction(myNdbTransaction[i]);

  delete myNdb;
  delete cluster_connection;

  ndb_end(0);
  return 0;
}