/* compile: gcc bug59354.c -Wall -g -o bug59354 `mysql_config --libs_r` `mysql_config --include` debug server was run with these options: --no-defaults --skip-gr --skip-na --innodb-flush-log-at-trx-commit=0 --innodb-doublewrite=0 --innodb-support-xa=0 --innodb-buffer-pool-size=128M --console --innodb-commit-concurrency=99 --innodb-thread-concurrency=200 --innodb-concurrency-tickets=50000 --innodb_spin_wait_delay=0 --innodb_sync_spin_loops=0 --innodb_thread_sleep_delay=0 --skip-slave-start --innodb-log-file-size=50M --innodb-lock-wait-timeout=1 --lock-wait-timeout=1 --innodb-file-format=barracuda --innodb-file-per-table */ #define TESTTIME (9000) #define NUMTHREADS (25) char host[]="192.168.1.2"; int port=3306; char username[]="root"; char password[]=""; char database[]="test"; #include #include #include #include #include #include #include pthread_t pthreads[NUMTHREADS]; unsigned long client_version=0; unsigned long server_version=0; unsigned long num_queries=0; int threaddone=0; int db_query(MYSQL *dbc,char *sql,int showresults); char* alocmem(size_t num); void *worker_thread(void *arg) { MYSQL *dbc=NULL; my_bool auto_reconnect=1; int cancelstate=0; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&cancelstate); dbc = mysql_init(NULL); if(NULL == dbc) { printf("mysql_init failed\n"); goto threadexit; } else { if(0!=mysql_options(dbc,MYSQL_OPT_RECONNECT,(char*)&auto_reconnect)) { printf("mysql_options() failed to set MYSQL_OPT_RECONNECT"); } 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) (%s)", mysql_error(dbc),mysql_errno(dbc),mysql_sqlstate(dbc)); mysql_close(dbc); dbc=NULL; } } char shortquery[1024]; memset(shortquery,0,1024); char *longquery; longquery=NULL; char *c; c=NULL; while(0==threaddone && NULL!=dbc) { if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","start transaction"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","commit"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","rollback"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","insert ignore into t1 select d,e,f from t2 where d > '"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","' limit 10"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","insert ignore into t1 values ("); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","%5,'"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","','"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","')"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","insert ignore into t2 values ("); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","%5,'"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","','"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","')"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","insert ignore into t3 values ('"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","','"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","','"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","')"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","insert ignore into t3 select a,b,c from t1 where c > '"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","' limit 10"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t1 where a<"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","%5 limit 4"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t2 where d<"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","%5 limit 4"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t3 where h<'"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","' limit 4"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","update t2 set e='"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","',f='"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","' where d="); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","%5 limit 10"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","select count(*) from t1,t2 where a=d and b>'"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","'"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","select count(*) from t1,t2 where a=d and b>'"); c+=sprintf(c,"%ld",-128 + lrand48()%255lu); c+=sprintf(c,"%s","' lock in share mode"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","update ignore t1 set a=a+1 limit 2"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","update ignore t2 set d=d+1 limit 2"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","update ignore t3 set g=g+1 limit 2"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t1 limit 5"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t2 limit 5"); db_query(dbc,shortquery,0); } if(lrand48()%10==0) { c=shortquery; c+=sprintf(c,"%s","delete from t3 limit 5"); db_query(dbc,shortquery,0); } } threadexit: mysql_close(dbc); mysql_thread_end(); pthread_exit(0); } int main(int argc, const char *argv[]) { MYSQL *dbc=NULL; int i=0,err=0; int counter=0; srand48((unsigned long)1335782817); time_t timestart=0,timenow=0; //unsigned int counter=0; counter=0; char shortquery[1024]={0}; int repcount=0; char *longquery=NULL; longquery=NULL; char *c=NULL; my_init(); 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) (%s)", mysql_error(dbc),mysql_errno(dbc),mysql_sqlstate(dbc)); mysql_close(dbc); dbc=NULL; goto threadexit; } } printf("running initializations..\n"); client_version=mysql_get_client_version(); server_version=mysql_get_server_version(dbc); printf("client version=%lu\n",client_version); printf("server version=%lu\n",server_version); if((client_version/10000) < (server_version/10000)) { printf("different client and server version! please upgrade client library!\n"); //goto threadexit; } if (!mysql_thread_safe()) { printf("non-threadsafe client detected! please rebuild and link with libmysql_r!\n"); } c=shortquery; c+=sprintf(c,"%s","set global innodb_flush_log_at_trx_commit=0"); db_query(dbc,shortquery,1); c=shortquery; c+=sprintf(c,"%s","drop table if exists t1,t2,t3"); db_query(dbc,shortquery,1); c=shortquery; c+=sprintf(c,"%s","create table t1(a tinyint,b varchar(10),c varchar(10),primary key (a),key(b,c))engine=innodb row_format=compressed"); db_query(dbc,shortquery,1); c=shortquery; c+=sprintf(c,"%s","create table t2(d tinyint,e varchar(10),f varchar(10),primary key(d),key(d,e,f))engine=innodb row_format=compressed"); db_query(dbc,shortquery,1); c=shortquery; c+=sprintf(c,"%s","create table t3(g varchar(10),h varchar(10),i varchar(10),unique(g,h,i))engine=innodb row_format=compressed"); db_query(dbc,shortquery,1); repcount=100; for(counter=0;counter 0) { myerrno=mysql_errno(dbc); printf("query failed '%s' : %d (%s) (%s)\n",sql,myerrno,mysql_error(dbc),mysql_sqlstate(dbc)); return 0; } num_queries++; do { r = mysql_use_result(dbc); if(r) { unsigned int numfields = mysql_num_fields(r); //unsigned int numrows=mysql_num_rows(r); while(0!=(field = mysql_fetch_field(r))) { //print metadata information about each field if(showresults > 1) { printf("%s ",field->name); } } if(showresults > 1) { printf("\n------------------------------------\n"); } while (0!=(w = mysql_fetch_row(r))) { for(i = 0; i < numfields; i++) { //print each field here if(showresults > 1) { printf("%s\t",w[i]); } } if(showresults > 1) { printf("\n"); } } if(showresults > 1) { printf("\n"); } mysql_free_result(r); } else //no rows returned. was it a select? { if(mysql_field_count(dbc) > 0 && showresults > 0) { printf("No results for '%s'. (%d) - %s (%s)\n",sql,mysql_errno(dbc),mysql_error(dbc),mysql_sqlstate(dbc)); return 0; } else //it could have been some insert/update/delete { //this is successful query } } moreresult=mysql_next_result(dbc); if(moreresult > 0 && showresults > 0) { printf("mysql_next_result returned %d, mysql error %s, (%d) (%s)\n",moreresult,mysql_error(dbc),mysql_errno(dbc),mysql_sqlstate(dbc)); return 0; } } while (0==moreresult); return 1; } char* alocmem(size_t num) { char *r=(char*)calloc(num,1); if(NULL == r) { printf("cannot calloc %lu bytes of memory\n",num); exit(1); } return r; }