/* This was generated code! Reworked by Hakan Kuecuekyilmaz to get more predictable run time behaviour. 2006-03-23. */ #include #include #include #include #include #include #include #define TESTTIME (560) #define NUMTHREADS (3) #define DATASIZE (16 * 1024 * 1024) /* Seed of 303 and 2 threads fails on Linux 32-bit within 1 minute */ /* Seed of 808 and 3 threads fails on Linux 64-bit within 3 minute */ #define SEED 808 char host[]= "127.0.0.1"; char username[]= "root"; char password[]= ""; char database[]= "test"; int port= 3306; pthread_t pthreads[NUMTHREADS]; int threaddone= 0; char *databucket= NULL; int db_query(MYSQL *dbc, char *sql, int show_results); char *alocmem(const int num); int write_string(char *buf, const int minlen, const int maxlen, const long int random_number, const int flag); void *worker_thread(void *arg); int db_query(MYSQL *dbc, char *sql, int show_results) { MYSQL_RES *r= NULL; MYSQL_ROW w; MYSQL_FIELD *field= NULL; int i= 0; int more_result= 0; int res= 0; res= mysql_query(dbc,sql); if (res != 0 && show_results > 0) { /* Ignore 1020 "Record has changed since last read". */ if (mysql_errno(dbc) != 1020) { printf("Query failed: %d (%s)\n", mysql_errno(dbc), mysql_error(dbc)); } return 0; } do { r= mysql_store_result(dbc); if (r) { unsigned int numfields= mysql_num_fields(r); while ((field= mysql_fetch_field(r))) { //print metadata information about each field if (show_results > 1) { printf("%s ", field->name); } } if (show_results > 1) { printf("\n------------------------------------\n"); } while ((w = mysql_fetch_row(r))) { for (i = 0; i < numfields; i++) { // Print each field here. if (show_results > 1) { printf("%s\t", w[i]); } } if (show_results > 1) { printf("\n"); } } if (show_results > 1) { printf("\n"); } mysql_free_result(r); } else // No rows returned. Was it a SELECT? { if (mysql_field_count(dbc) > 0 && show_results > 0) { printf("No results for '%s'. (%d) - %s\n", sql, mysql_errno(dbc), mysql_error(dbc)); } else // It could have been some INSERT/UPDATE/DELETE. { // This is successful query. } } more_result= mysql_next_result(dbc); if (more_result > 0 && show_results > 0) { printf("mysql_next_result returned %d, mysql error %s, (%d)\n", more_result, mysql_error(dbc), mysql_errno(dbc)); break; } } while (more_result == 0); return 0; } char* alocmem(const int num) { char *r= calloc(num, 1); if (NULL == r) { printf("Cannot calloc %d bytes of memory.\n", num); exit(1); } return r; } int write_string(char *buf, const int minlen, const int maxlen, const long int random_number, const int flag) { if (!buf || maxlen==0) return 0; int length= minlen + random_number % (maxlen-minlen) - 1; int start_length= random_number % (DATASIZE - length - 1); if (length < 0) length= 0; if (start_length < 0) start_length= 0; memcpy(buf, databucket + start_length, length); buf[length]= 0; return length; } void *worker_thread(void *arg) { /* Every thread should have different seed. */ int i= (int) arg; int local_seed = SEED + i; MYSQL *dbc= NULL; int cancelstate= 0; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate); if (!(dbc= mysql_init(NULL))) { printf("mysql_init\n"); dbc= NULL; goto threadexit; } if (!mysql_real_connect(dbc, host, username, password, database, port, NULL, CLIENT_FOUND_ROWS|CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)) { printf("mysql_real_connect failed: %s (%d)\n", mysql_error(dbc), mysql_errno(dbc)); dbc= NULL; } unsigned int counter= 0; long int random_number= 0; char shortquery[1024]= {0}; char *longquery= NULL; char *c= NULL; struct drand48_data buffer; srand48_r(local_seed, &buffer); while (!threaddone && dbc != NULL) { /* Printing 9 SQL statements. */ lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { c= shortquery; c+= sprintf(c, "%s", "START TRANSACTION"); db_query(dbc, shortquery, 1); } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { longquery= alocmem(66111); lrand48_r(&buffer, &random_number); for (counter= 0; counter < 5; counter++) { c= longquery; c+= sprintf(c, "%s", "INSERT IGNORE INTO t1 (c1, c2, c3) VALUES ("); c+= sprintf(c, "%ld", -8388608 + random_number % 16777215); c+= sprintf(c, "%s", ",'"); c+= write_string(c, 0, 255, random_number, 0); c+= sprintf(c, "%s", "','"); c+= write_string(c, 0, 65535, random_number, 0); c+= sprintf(c, "%s", "')"); db_query(dbc, longquery, 1); } free(longquery); } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { for (counter= 0; counter < 5; counter++) { lrand48_r(&buffer, &random_number); c= shortquery; c+= sprintf(c, "%s", "SELECT c1 FROM t1 WHERE c2 = '"); c+= write_string(c, 0, 255, random_number, 0); c+= sprintf(c, "%s", "'"); db_query(dbc, shortquery, 1); } } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { c= shortquery; c+= sprintf(c, "%s", "UPDATE t1 SET c2 = md5(c2)"); db_query(dbc, shortquery, 1); } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { c= shortquery; c+= sprintf(c, "%s", "UPDATE t1 SET c3 = md5(c3)"); db_query(dbc, shortquery, 1); } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { for (counter= 0; counter < 3; counter++) { c= shortquery; c+= sprintf(c, "%s", "ROLLBACK"); db_query(dbc, shortquery, 1); } } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { c= shortquery; c+= sprintf(c, "%s", "DELETE FROM t1 ORDER BY c1 * rand("); c+= sprintf(c, "%d", local_seed); c+= sprintf(c, "%s", ") LIMIT 10"); db_query(dbc, shortquery, 1); } lrand48_r(&buffer, &random_number); if (random_number % 5 == 0) { c= shortquery; c+= sprintf(c, "%s", "COMMIT"); db_query(dbc, shortquery, 1); } } threadexit: mysql_close(dbc); mysql_thread_end(); pthread_exit(0); } int main(int argc, const char *argv[]) { MYSQL *dbc= NULL; int i= 0; int err= 0; time_t timestart= 0,timenow= 0; char shortquery[1024]= {0}; char *c= NULL; if (!(dbc = mysql_init(NULL))) { printf("mysql_init failed.\n"); dbc= NULL; goto threadexit; } else { if (!mysql_real_connect(dbc,host,username,password,database,port, NULL, CLIENT_FOUND_ROWS|CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)) { printf("mysql_real_connect failed: %s (%d)\n", mysql_error(dbc), mysql_errno(dbc)); dbc= NULL; goto threadexit; } } printf("Running initializations ...\n"); printf("Pre-generating %d bytes of random data.\n", DATASIZE); databucket= calloc(DATASIZE, sizeof(char*)); if (databucket == NULL) { printf("Error: cannot calloc data buffer.\n"); exit(1); } srand48(SEED); for (i= 0; i < DATASIZE - 1; i++) { databucket[i]= 0x61 + (lrand48() % 26); } c= shortquery; c+= sprintf(c, "%s", "DROP TABLE IF EXISTS t1"); db_query(dbc, shortquery, 1); c= shortquery; c+= sprintf(c, "%s", "CREATE TABLE t1(c1 mediumint, c2 mediumblob, c3 mediumtext, key(c1)) Engine Falcon"); db_query(dbc, shortquery, 1); c= shortquery; c+= sprintf(c, "%s", "SET GLOBAL max_allowed_packet = 1024*1024*1024"); db_query(dbc, shortquery, 1); mysql_close(dbc); printf("About to spawn %d threads\n", NUMTHREADS); for (i= 0; i < NUMTHREADS; i++) { err= pthread_create(&pthreads[i], NULL, worker_thread, (void *) i); if (err != 0) { printf("Error spawning thread %d, pthread_create returned %d\n", i, err); } printf("%d ", i); sleep(1); } printf("\n"); printf("Completed spawning new database worker threads.\n"); printf("Testcase is now running, so watch for error output.\n"); timestart= time(NULL); timenow= time(NULL); for (i = 0; (timenow - timestart) < TESTTIME; timenow = time(NULL)) { sleep(1); } threaddone= 1; printf("Waiting for worker threads to finish ...\n"); for (i= 0; i < NUMTHREADS; i++) { pthread_join(pthreads[i], NULL); } exit(0); threadexit: exit(-1); }