//gcc bug41114.c -Wall -g -o bug41114 -L/export/home/sbester/mysql/mysql-5.1.30-solaris10-i386/lib -I/export/home/sbester/mysql/mysql-5.1.30-solaris10-i386/include -lmysqlclient_r -lz -lm -lnsl -lsocket -lpthread #include #include #include #include #include #include #include #define KILLCONN 1 #define KILLQUERY 2 #define TESTTIME (3600) #define NUMTHREADS (1) char host[]="127.0.0.1"; int port=3306; char username[]="root"; char password[]=""; char database[]="test"; 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); unsigned int pick_a_random_processlist_id(MYSQL *db); unsigned int kill_something(MYSQL *db,int query_or_conn); char* alocmem(size_t num); void *worker_thread(void *arg); 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)", mysql_error(dbc),mysql_errno(dbc)); mysql_close(dbc); dbc=NULL; } } unsigned int counter=0; unsigned int repcount=0; char shortquery[1024]; memset(shortquery,0,1024); char *longquery; longquery=NULL; char *c; c=NULL; while(0==threaddone && NULL!=dbc) { if(lrand48()%7==0) { c=shortquery; c+=sprintf(c,"%s","insert delayed into `qa00` set `c1`='"); c+=sprintf(c,"%ld",-32768 + lrand48()%65535lu); c+=sprintf(c,"%s","',`c2`='"); c+=sprintf(c,"%ld",-32768 + lrand48()%65535lu); c+=sprintf(c,"%s","',`c3`='"); c+=sprintf(c,"%ld",-32768 + lrand48()%65535lu); c+=sprintf(c,"%s","',`c4`='"); c+=sprintf(c,"%ld",-32768 + lrand48()%65535lu); c+=sprintf(c,"%s","'"); db_query(dbc,shortquery,1); } if(lrand48()%7==0) { repcount=2; for(counter=0;counter 0) { printf("query failed '%s' : %d (%s)\n",sql,mysql_errno(dbc),mysql_error(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\n",sql,mysql_errno(dbc),mysql_error(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)\n",moreresult,mysql_error(dbc),mysql_errno(dbc)); return 0; } } while (0==moreresult); return 1; } unsigned int pick_a_random_processlist_id(MYSQL *db) { MYSQL_RES *r=NULL; MYSQL_ROW w; int res=0; unsigned int ret=0; my_ulonglong numrows=0; res = mysql_query(db,"show processlist"); if(res)return 0; r = mysql_store_result(db); if(!r) return 0; numrows=mysql_num_rows(r); while (0!=(w = mysql_fetch_row(r))) { if(db->thread_id == (unsigned long)atoi(w[0])) continue; if(lrand48()%numrows == 0) { ret=atoi(w[0]); break; } } num_queries++; mysql_free_result(r); return ret; } unsigned int kill_something(MYSQL *db,int query_or_conn) { unsigned int thread_id=pick_a_random_processlist_id(db); char query[30]={0}; if(0 == thread_id) return 0; if(query_or_conn==KILLCONN)sprintf(query,"KILL %d",thread_id); else if(query_or_conn==KILLQUERY)sprintf(query,"KILL QUERY %d",thread_id); if(0 == db_query(db,query,0)) return 0; num_queries++; return thread_id; } char* alocmem(size_t num) { char *r=(char*)calloc(num,1); if(NULL == r) { printf("cannot calloc %I64u bytes of memory\n",num); exit(1); } return r; }