int runPkReadMultiWakeupT2(NDBT_Context* ctx, NDBT_Step* step) { ndbout << "Thread 2 : Waiting for phase 1 notification from Thread 1" << endl; ctx->getPropertyWait("PHASE", 1); /* Ok, now thread 1 has locked row 1, we'll attempt to read * it, using the multi_ndb_wait Api to block */ HugoOperations hugoOps(*ctx->getTab()); Ndb* ndb = GETNDB(step); ndbout << "Thread 2 : Starting async transaction to read row" << endl; check(hugoOps.startTransaction(ndb) == 0, hugoOps); check(hugoOps.pkReadRecord(ndb, 0, 1, NdbOperation::LM_Exclusive) == 0, hugoOps); /* Prepare, Send */ check(hugoOps.execute_async(ndb, NdbTransaction::Commit, NdbOperation::AbortOnError) == 0, hugoOps); global_poll_group->addNdb(ndb); Ndb ** ready_ndbs; int wait_rc = 0; int acknowledged = 0; do { ndbout << "Thread 2 : Calling NdbWaitGroup::wait()" << endl; wait_rc = global_poll_group->wait(ready_ndbs, 10000); ndbout << " Result : " << wait_rc << endl; if (wait_rc == 0) { if (!acknowledged) { ndbout << "Thread 2 : Woken up, moving to phase 2" << endl; ctx->incProperty("PHASE"); acknowledged = 1; } } else if (wait_rc > 0) { ndbout << "Thread 2 : Transaction completed" << endl; ndb->pollNdb(1,0); hugoOps.closeTransaction(ndb); } } while (wait_rc == 0); return (wait_rc == 1 ? NDBT_OK : NDBT_FAILED); }
/* Consumer */ int runV2MultiWait_WaitPop_Thread(NDBT_Context* ctx, NDBT_Step* step) { static int iter = 0; // keeps incrementing when test case is repeated int records = ctx->getNumRecords(); const char * d[5] = { " fast"," slow"," slow",""," slow" }; const int timeout[3] = { 100, 1, 0 }; const int pct_wait[9] = { 0,0,0,50,50,50,100,100,100 }; for (int loop = 0; loop < V2_NLOOPS; loop++, iter++) { ctx->incProperty("LOOP"); ndbout << "V2 test: " << d[loop&1] << d[loop&2] << d[loop&4]; ndbout << " " << timeout[iter%3] << "/" << pct_wait[iter%9] << endl; bool slow = loop & 4; int nrec = 0; while(nrec < records) { /* Occasionally check with no timeout */ global_poll_group->wait(timeout[iter%3], pct_wait[iter%9]); Ndb * ndb = global_poll_group->pop(); while(ndb) { check(ndb->pollNdb(0, 1) != 0, (*ndb)); nrec++; NdbTransaction *tx = (NdbTransaction *) ndb->getCustomData(); tx->close(); global_ndb_pool->recycleNdb(ndb); ndb = global_poll_group->pop(); } if(slow) { NdbSleep_MilliSleep(myRandom48(6)); } } } ctx->stopTest(); global_ndb_pool->closeAll(); return NDBT_OK; }
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; }
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; }
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; }