51 #include <ndb_global.h>
55 #include <NdbThread.h>
59 #include <NdbTimer.hpp>
61 #include <NdbTest.hpp>
62 #include <NDBT_Error.hpp>
63 #include <NdbSchemaCon.hpp>
71 #define NDB_MAXTHREADS 256
79 #define MAXATTRSIZE 100
81 #define MaxNoOfAttemptsC 10
100 StartType threadStart;
103 extern "C" void* flexHammerThread(
void*);
104 static int setAttrNames(
void);
105 static int setTableNames(
void);
106 static int readArguments(
int,
const char**);
107 static int createTables(
Ndb*);
108 static int dropTables(
Ndb*);
109 static void sleepBeforeStartingTest(
int seconds);
110 static int checkThreadResults(
ThreadNdb *threadArrayP,
const char* phase);
124 static int tNoOfThreads;
125 static int tNoOfAttributes;
126 static int tNoOfTables;
127 static int tNoOfBackups;
128 static int tAttributeSize;
129 static int tNoOfOperations;
130 static int tNoOfRecords;
131 static int tNoOfLoops;
132 static char tableName[MAXTABLES][MAXSTRLEN];
133 static char attrName[MAXATTR][MAXSTRLEN];
134 static int theSimpleFlag = 0;
135 static int theWriteFlag = 0;
136 static int theDirtyFlag = 0;
137 static int theTableCreateFlag = 0;
138 static int theStandardTableNameFlag = 0;
139 static unsigned int tSleepTime = 0;
141 #define START_TIMER { NdbTimer timer; timer.doStart();
142 #define STOP_TIMER timer.doStop();
143 #define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); };
150 for (
int i = 0;
i < tNoOfThreads ;
i++)
152 threadArrayP[
i].threadReady = 0;
153 threadArrayP[
i].threadResult = 0;
154 threadArrayP[
i].threadStart = stIdle;
164 NdbSleep_MilliSleep(100);
166 for (
int i = 0;
i < tNoOfThreads ;
i++) {
167 if (threadArrayP[
i].threadReady == 0) {
175 tellThreads(
ThreadNdb* threadArrayP,
const StartType what)
177 for (
int i = 0;
i < tNoOfThreads ;
i++)
179 threadArrayP[
i].threadStart = what;
185 NDB_COMMAND(flexHammer,
"flexHammer",
"flexHammer",
"flexHammer", 65535)
199 if (readArguments(argc, argv) != 0) {
200 ndbout <<
"Wrong arguments to flexHammer" << endl;
201 return NDBT_ProgramExit(NDBT_WRONGARGS);
207 check = setAttrNames();
209 ndbout <<
"Couldn't set attribute names" << endl;
210 return NDBT_ProgramExit(NDBT_FAILED);
212 check = setTableNames();
214 ndbout <<
"Couldn't set table names" << endl;
215 return NDBT_ProgramExit(NDBT_FAILED);
226 return NDBT_ProgramExit(NDBT_FAILED);
228 g_cluster_connection= &con;
229 pMyNdb =
new Ndb(g_cluster_connection,
"TEST_DB");
234 ndbout <<
"NDB is not ready" << endl <<
"Benchmark failed" << endl;
235 returnValue = NDBT_FAILED;
239 check = createTables(pMyNdb);
241 returnValue = NDBT_FAILED;
244 sleepBeforeStartingTest(tSleepTime);
247 resetThreads(pThreads);
248 for (
int i = 0;
i < tNoOfThreads ;
i++) {
249 pThreads[
i].threadNo =
i;
250 pThreads[
i].threadLife = NdbThread_Create(flexHammerThread,
251 (
void**)&pThreads[
i],
254 NDB_THREAD_PRIO_LOW);
258 waitForThreads(pThreads);
259 if (checkThreadResults(pThreads,
"init") != 0) {
260 returnValue = NDBT_FAILED;
264 if (returnValue == NDBT_OK) {
265 ndbout << endl <<
"All threads started" << endl << endl;
270 if((tNoOfLoops != 0) && (tNoOfLoops <= tLoops))
274 ndbout <<
"Hammering..." << endl;
276 resetThreads(pThreads);
279 tellThreads(pThreads, stHammer);
281 waitForThreads(pThreads);
282 ndbout <<
"Threads ready to continue..." << endl;
286 if (checkThreadResults(pThreads,
"hammer") != 0) {
287 ndbout <<
"Thread(s) failed." << endl;
288 returnValue = NDBT_FAILED;
291 PRINT_TIMER(
"hammer", tNoOfOperations*tNoOfThreads, tNoOfTables*6);
301 resetThreads(pThreads);
302 tellThreads(pThreads, stStop);
305 waitForThreads(pThreads);
307 ndbout <<
"----------------------------------------------" << endl << endl;
308 ndbout <<
"Benchmark completed" << endl;
317 for(
int i = 0;
i < tNoOfThreads;
i++){
318 NdbThread_WaitFor(pThreads[
i].threadLife, &tmp);
319 NdbThread_Destroy(&pThreads[
i].threadLife);
324 delete flexHammerErrorData;
329 return NDBT_ProgramExit(returnValue);
335 flexHammerThread(
void* pArg)
344 int loop_count_ops = 0;
345 int loop_count_tables = 0;
346 int loop_count_attributes = 0;
349 int count_tables = 0;
350 int count_attributes = 0;
352 int tThreadResult = 0;
353 MyOpType tMyOpType = otLast;
355 int readValue[MAXATTR][MAXATTRSIZE]; bzero(readValue,
sizeof(readValue));
356 int attrValue[MAXATTRSIZE];
358 int tNoOfAttempts = 0;
360 for (i = 0; i < MAXATTRSIZE; i++)
363 pMyNdb =
new Ndb(g_cluster_connection,
"TEST_DB" );
369 pThreadData->threadStart = stIdle;
373 pThreadData->threadResult = tThreadResult;
374 pThreadData->threadReady = 1;
377 while (pThreadData->threadStart == stIdle) {
378 NdbSleep_MilliSleep(100);
382 if (pThreadData->threadStart == stStop) {
383 pThreadData->threadReady = 1;
389 pThreadData->threadStart = stIdle;
392 loop_count_ops = tNoOfOperations;
393 loop_count_tables = tNoOfTables;
394 loop_count_attributes = tNoOfAttributes;
396 for (count=0 ; count < loop_count_ops ; count++) {
400 pkValue = count % tNoOfRecords;
402 for (count_round = 0; count_round < 5; ) {
403 switch (count_round) {
405 tMyOpType = otInsert;
407 for (i=0; i < MAXATTRSIZE; i ++) {
417 for(i=0; i < MAXATTRSIZE; i ++) {
420 tMyOpType = otUpdate;
423 tMyOpType = otDelete;
432 if (pMyTransaction == NULL) {
439 for (count_tables = 0; count_tables < loop_count_tables;
441 pMyOperation[count_tables] =
443 if (pMyOperation[count_tables] == NULL) {
452 if (theWriteFlag == 1 && theDirtyFlag == 1) {
453 check = pMyOperation[count_tables]->
dirtyWrite();
454 }
else if (theWriteFlag == 1) {
455 check = pMyOperation[count_tables]->
writeTuple();
461 if (theSimpleFlag == 1) {
462 check = pMyOperation[count_tables]->
simpleRead();
463 }
else if (theDirtyFlag == 1) {
464 check = pMyOperation[count_tables]->
dirtyRead();
466 check = pMyOperation[count_tables]->
readTuple();
470 if (theWriteFlag == 1 && theDirtyFlag == 1) {
471 check = pMyOperation[count_tables]->
dirtyWrite();
472 }
else if (theWriteFlag == 1) {
473 check = pMyOperation[count_tables]->
writeTuple();
474 }
else if (theDirtyFlag == 1) {
494 check = pMyOperation[count_tables]->
equal( (
char*)attrName[0],
500 ndbout <<
"pMyOperation equal failed" << endl;
510 for (count_attributes = 1; count_attributes < loop_count_attributes;
511 count_attributes++) {
513 pMyOperation[count_tables]->
setValue((
char*)attrName[count_attributes], (
char*)&attrValue[0]);
517 for (count_attributes = 1; count_attributes < loop_count_attributes;
518 count_attributes++) {
519 tTmp = pMyOperation[count_tables]->
520 getValue( (
char*)attrName[count_attributes],
521 (
char*)&readValue[count_attributes][0] );
530 if (check == -1 && tTmp == NULL && tMyOpType != otDelete) {
538 if (tThreadResult != 0) {
545 check = pMyTransaction->
execute(Commit);
551 int retCode = flexHammerErrorData->handleErrorCommon(pMyTransaction->
getNdbError());
559 }
else if (retCode == 2) {
560 ndbout <<
"4115 should not happen in flexHammer" << endl;
561 }
else if (retCode == 3) {
583 if (tNoOfAttempts <= MaxNoOfAttemptsC) {
636 readArguments (
int argc,
const char** argv)
641 tNoOfOperations = 500;
644 tNoOfAttributes = 25;
648 theTableCreateFlag = 0;
651 if (strcmp(argv[i],
"-t") == 0) {
652 tNoOfThreads = atoi(argv[i+1]);
653 if ((tNoOfThreads < 1) || (tNoOfThreads > NDB_MAXTHREADS))
656 else if (strcmp(argv[i],
"-o") == 0) {
657 tNoOfOperations = atoi(argv[i+1]);
658 if (tNoOfOperations < 1)
661 else if (strcmp(argv[i],
"-r") == 0) {
662 tNoOfRecords = atoi(argv[i+1]);
663 if (tNoOfRecords < 1)
666 else if (strcmp(argv[i],
"-a") == 0) {
667 tNoOfAttributes = atoi(argv[i+1]);
668 if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR))
671 else if (strcmp(argv[i],
"-c") == 0) {
672 tNoOfTables = atoi(argv[i+1]);
673 if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES))
676 else if (strcmp(argv[i],
"-l") == 0) {
677 tNoOfLoops = atoi(argv[i+1]);
678 if ((tNoOfLoops < 0) || (tNoOfLoops > 100000))
681 else if (strcmp(argv[i],
"-s") == 0) {
682 tAttributeSize = atoi(argv[i+1]);
683 if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE))
686 else if (strcmp(argv[i],
"-sleep") == 0) {
687 tSleepTime = atoi(argv[i+1]);
688 if ((tSleepTime < 1) || (tSleepTime > 3600))
691 else if (strcmp(argv[i],
"-simple") == 0) {
696 else if (strcmp(argv[i],
"-write") == 0) {
701 else if (strcmp(argv[i],
"-dirty") == 0) {
706 else if (strcmp(argv[i],
"-no_table_create") == 0) {
707 theTableCreateFlag = 1;
711 else if (strcmp(argv[i],
"-stdtables") == 0) {
712 theStandardTableNameFlag = 1;
724 ndbout << endl <<
"FLEXHAMMER - Starting normal mode" << endl;
725 ndbout <<
"Hammer ndb with read, insert, update and delete transactions"<< endl << endl;
727 ndbout <<
" " << tNoOfThreads <<
" thread(s) " << endl;
728 ndbout <<
" " << tNoOfLoops <<
" iterations " << endl;
729 ndbout <<
" " << tNoOfTables <<
" table(s) and " << 1 <<
" operation(s) per transaction " << endl;
730 ndbout <<
" " << tNoOfRecords <<
" records to hammer(limit this with the -r option)" << endl;
731 ndbout <<
" " << tNoOfAttributes <<
" attributes per table " << endl;
732 ndbout <<
" " << tNoOfOperations <<
" transaction(s) per thread and round " << endl;
733 ndbout <<
" " << tAttributeSize <<
" is the number of 32 bit words per attribute " << endl << endl;
738 void sleepBeforeStartingTest(
int seconds)
741 ndbout <<
"Sleeping(" << seconds <<
")...";
742 NdbSleep_SecSleep(seconds);
743 ndbout <<
" done!" << endl;
748 createTables(
Ndb* pMyNdb)
757 if (theTableCreateFlag == 0) {
759 for (i = 0; i < tNoOfTables; i++) {
761 ndbout <<
"Creating " << tableName[
i] <<
"...";
765 ndbout <<
" already exists." << endl;
771 MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pMyNdb);
772 if (MySchemaTransaction == NULL) {
777 if (MySchemaOp == NULL) {
779 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
791 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
798 1, UnSigned, MMBased,
802 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
807 for (j = 1; j < tNoOfAttributes ; j++) {
810 tAttributeSize, UnSigned, MMBased,
814 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
820 check = MySchemaTransaction->
execute();
823 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
827 NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
836 dropTables(
Ndb* pMyNdb)
840 if (theTableCreateFlag == 0)
842 for (i = 0; i < tNoOfTables; i++)
844 ndbout <<
"Dropping " << tableName[
i] <<
"...";
846 ndbout <<
"done" << endl;
855 static int setAttrNames()
860 for (i = 0; i < MAXATTR ; i++) {
871 static int setTableNames()
878 for (i = 0; i < MAXTABLES ; i++) {
879 if (theStandardTableNameFlag == 0) {
881 (Uint32)(NdbTick_CurrentMillisecond()/1000));
895 static int checkThreadResults(
ThreadNdb *threadArrayP,
const char* phase)
899 for (i = 0; i < tNoOfThreads; i++) {
900 if (threadArrayP[i].threadResult != 0) {
901 ndbout <<
"Thread " << i <<
" reported fatal error "
902 << threadArrayP[
i].threadResult <<
" during " << phase << endl;