/* In the source tree: =================== Server: ------- $ BUILD/compile-pentium-debug-max-no-ndb $ cd mysql-test/ $ ./mtr 1st # just run any test suite to create initial var/ dir $ ../sql/mysqld --defaults-group-suffix=.1 --defaults-file=var/my.cnf --log-output=file --gdb --plugin-dir=../storage/example/.libs --plugin_load=EXAMPLE=ha_example.so --loose-plugin-example-enum-var=e2 --core-file --loose-debug-sync-timeout=300 --skip-grant-tables --binlog-format=mixed --log-bin --innodb_locks_unsafe_for_binlog --innodb_flush_log_at_trx_commit=0 -P3306 This client program: -------------------- $ cd mysql-test/ $ gcc bug53627.c -g -o bug53627 -I../include ../libmysql_r/.libs/libmysqlclient_r.a -lz -lpthread -lm $ ./bug53627 */ #include #include #include #include #include #include #include #define TESTTIME (10000) #define NUMTHREADS (2) 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); char* alocmem(size_t num); int rand2(int maximum) { return (int) ((double)(random()) / RAND_MAX * maximum); } 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 { mysql_options(dbc,MYSQL_OPT_RECONNECT,(char*)&auto_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)); dbc=NULL; } } char shortquery[1024]; memset(shortquery,0,1024); char *longquery; longquery=NULL; char *c; c=NULL; while(0==threaddone && NULL!=dbc) { if(rand2(2)) { sprintf(shortquery, "replace into t2 values (%d)", rand2(200)); db_query(dbc,shortquery,1); } if(rand2(2)) { sprintf(shortquery, "replace into t1(a,b) values (%d,%d)", rand2(200), rand2(200)); db_query(dbc,shortquery,1); } if(rand2(2)) db_query(dbc,"start transaction",1); if(rand2(2)) db_query(dbc,"select * from t2 for update",1); if(rand2(2)) db_query(dbc,"select * from t2,t1 where t2.d=t1.a or d in(select a from t1 where t2.d > a)",1); if(rand2(2)) db_query(dbc,"commit",1); } threadexit: mysql_close(dbc); mysql_thread_end(); pthread_exit(0); } void *worker_thread1(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 { mysql_options(dbc,MYSQL_OPT_RECONNECT,(char*)&auto_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)); dbc=NULL; } } char shortquery[1024]; memset(shortquery,0,1024); char *longquery; longquery=NULL; char *c; c=NULL; while(0==threaddone && NULL!=dbc) { int m = 3; int t = 0; if(!t) { sprintf(shortquery, "replace into t2 values (%d)", rand2(m)); db_query(dbc,shortquery,1); sprintf(shortquery, "replace into t1(a,b) values (%d,%d)", rand2(m), rand2(m)); db_query(dbc,shortquery,1); } if(!t && rand2(2)) { t = 1; db_query(dbc,"start transaction",1); } if(t && rand2(2)) { t = 0; db_query(dbc,"commit",1); } } threadexit: mysql_close(dbc); mysql_thread_end(); pthread_exit(0); } void *worker_thread2(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 { mysql_options(dbc,MYSQL_OPT_RECONNECT,(char*)&auto_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)); dbc=NULL; } } char shortquery[1024]; memset(shortquery,0,1024); char *longquery; longquery=NULL; char *c; c=NULL; while(0==threaddone && NULL!=dbc) { db_query(dbc,"select * from t2,t1 where t2.d=t1.a or d in(select a from t1 where t2.d > a)",1); } 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; srand48((unsigned long)time(NULL)); time_t timestart=0,timenow=0; unsigned int counter=0; counter=0; char *longquery=NULL; longquery=NULL; my_init(); if (!(dbc = mysql_init(NULL))) { printf("mysql_init\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)", mysql_error(dbc),mysql_errno(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("incompatible 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"); } char *c=NULL; char shortquery[1024]; memset(shortquery,0,1024); db_query(dbc, "set global innodb_flush_log_at_trx_commit=0", 1); db_query(dbc, "set global sql_mode='';", 1); db_query(dbc, "create table t1(a tinyint not null,b tinyint,primary key(b),key(a))engine=innodb;", 1); db_query(dbc, "create table t2(d tinyint not null,unique key(d))engine=innodb;", 1); mysql_close(dbc); printf("about to spawn %d threads\n",NUMTHREADS); // for (i=0;i 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; } 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; }