From 5169ad449f6f91b3303fac32faaec80d30cd0b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 10 May 2016 22:33:58 +0000 Subject: [PATCH] Testing on Prepared Statements Adding some code for the evaluation of prepared statements --- test/PrepStmt/Makefile | 5 +- test/PrepStmt/client2.cpp | 85 ++++++++++++--- test/PrepStmt/client3.cpp | 211 ++++++++++++++++++++++++++++++++++++++ test/PrepStmt/client4.cpp | 190 ++++++++++++++++++++++++++++++++++ 4 files changed, 478 insertions(+), 13 deletions(-) create mode 100644 test/PrepStmt/client3.cpp create mode 100644 test/PrepStmt/client4.cpp diff --git a/test/PrepStmt/Makefile b/test/PrepStmt/Makefile index 012fa1fe8..05b2f4066 100644 --- a/test/PrepStmt/Makefile +++ b/test/PrepStmt/Makefile @@ -36,7 +36,7 @@ IDIRS=-I$(IDIR) -I$(JEMALLOC_IDIR) -I$(MARIADB_IDIR) $(LIBCONFIG_IDIR) -I$(DAEMO LDIRS=-L$(LDIR) -L$(JEMALLOC_LDIR) $(LIBCONFIG_LDIR) -L$(RE2_PATH)/obj -L$(LIBEVENT_LDIR) -L$(MARIADB_LDIR) -L$(DAEMONPATH_LDIR) -MYCPPFLAGS=-std=c++11 $(IDIRS) $(OPTZ) $(DEBUG) +MYCPPFLAGS=-std=c++11 $(IDIRS) $(OPTZ) $(DEBUG) -ggdb LDFLAGS+= MYLIBS=-Wl,--export-dynamic -Wl,-Bstatic -lconfig -lproxysql -ldaemon -ljemalloc -lconfig++ -lre2 -levent -lmariadbclient -Wl,-Bdynamic -lpthread -lm -lz -lrt -lcrypto -lssl $(EXTRALINK) @@ -59,6 +59,9 @@ client1: client1.cpp client2: client2.cpp $(CXX) -o $@ $@.cpp $(LIBPROXYSQLAR) $(MYCPPFLAGS) $(CPPFLAGS) $(LDIRS) $(LIBS) $(LDFLAGS) $(MYLIBS) +client3: client3.cpp + $(CXX) -o $@ $@.cpp $(LIBPROXYSQLAR) $(MYCPPFLAGS) $(CPPFLAGS) $(LDIRS) $(LIBS) $(LDFLAGS) $(MYLIBS) + default: $(EXECUTABLE) diff --git a/test/PrepStmt/client2.cpp b/test/PrepStmt/client2.cpp index 4df194213..c43187ae8 100644 --- a/test/PrepStmt/client2.cpp +++ b/test/PrepStmt/client2.cpp @@ -4,8 +4,8 @@ #include #define QUERY1 "SELECT ?" -#define NUMPREP 1000000 -#define NUMPRO 10000 +#define NUMPREP 100000 +#define NUMPRO 1000 //#define NUMPREP 160 //#define NUMPRO 4 #define LOOPS 10 @@ -32,6 +32,35 @@ struct cpu_timer }; +int run_stmt(MYSQL_STMT *stmt, int int_data) { + MYSQL_BIND bind[1]; + MYSQL_RES *prepare_meta_result; + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= (char *)&int_data; + bind[0].is_null= 0; + bind[0].length= 0; + if (mysql_stmt_bind_param(stmt, bind)) { + fprintf(stderr, " mysql_stmt_bind_param() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + prepare_meta_result = mysql_stmt_result_metadata(stmt); // FIXME: no error check + if (mysql_stmt_execute(stmt)) { + fprintf(stderr, " mysql_stmt_execute(), 1 failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } +// memset(bind, 0, sizeof(bind)); + if (mysql_stmt_store_result(stmt)) { + fprintf(stderr, " mysql_stmt_store_result() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + mysql_free_result(prepare_meta_result); + return 0; +} + + int main() { std::mt19937 mt_rand(time(0)); GloMyStmt=new MySQL_STMT_Manager(); @@ -62,9 +91,10 @@ int main() { fprintf(stderr, " mysql_stmt_prepare(), failed: %s\n" , mysql_stmt_error(stmt[i])); exit(EXIT_FAILURE); } - uint32_t a=GloMyStmt->add_prepared_statement(0,(char *)USER,(char *)SCHEMA,buff,bl,stmt[i]); + uint32_t stmid=GloMyStmt->add_prepared_statement(0,(char *)USER,(char *)SCHEMA,buff,bl,stmt[i]); if (NUMPRO < 32) - fprintf(stdout, "SERVER_statement_id=%lu , PROXY_statement_id=%u\n", stmt[i]->stmt_id, a); + fprintf(stdout, "SERVER_statement_id=%lu , PROXY_statement_id=%u\n", stmt[i]->stmt_id, stmid); + local_stmts->insert(stmid,stmt[i]); } } fprintf(stdout, "Prepared statements: %u client, %u proxy/server. ", NUMPREP, GloMyStmt->total_prepared_statements()); @@ -104,14 +134,45 @@ int main() { MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); if (a) founds++; } - fprintf(stdout, "Found %u prepared statements searching by hash in: ", founds); + fprintf(stdout, "Found %u prepared statements searching by hash in: ", founds); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a) { + // we have a prepared statement, we can run it + founds++; + MYSQL_STMT *stm=local_stmts->find(a->statement_id); + run_stmt(stm,(uint32_t)mt_rand()); + } + } + fprintf(stdout, "Executed %u prepared statements in: ", founds); + } + + { + // for comparison, we run also queries in TEXT protocol + cpu_timer t; + for (i=0; istmt_id; -// num_params=stmt->param_count; -// num_columns=stmt->field_count; -// warning_count=stmt->upsert_status.warning_count; -// fprintf(stdout, "statement_id=%d , columns=%d , params=%d , warnings=%d\n", statement_id, num_columns, num_params, warning_count); return 0; } diff --git a/test/PrepStmt/client3.cpp b/test/PrepStmt/client3.cpp new file mode 100644 index 000000000..d6f8fe34e --- /dev/null +++ b/test/PrepStmt/client3.cpp @@ -0,0 +1,211 @@ +#include "proxysql.h" +#include "cpp.h" + +#include +#include + +#define QUERY1 "SELECT ?" +#define NUMPREP 100000 +#define NUMPRO 10000 +//#define NUMPREP 160 +//#define NUMPRO 4 +#define LOOPS 1 +#define USER "root" +#define SCHEMA "test" + +#define NTHREADS 4 + +MySQL_STMT_Manager *GloMyStmt; + +typedef struct _thread_data_t { + std::thread *thread; + MYSQL *mysql; + MYSQL_STMT **stmt; +} thread_data_t; + + +thread_data_t **GloThrData; + +struct cpu_timer +{ + ~cpu_timer() + { + auto end = std::clock() ; + std::cout << double( end - begin ) / CLOCKS_PER_SEC << " secs.\n" ; + }; + + const std::clock_t begin = std::clock() ; +}; + + +int run_stmt(MYSQL_STMT *stmt, int int_data) { + MYSQL_BIND bind[1]; + MYSQL_RES *prepare_meta_result; + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= (char *)&int_data; + bind[0].is_null= 0; + bind[0].length= 0; + if (mysql_stmt_bind_param(stmt, bind)) { + fprintf(stderr, " mysql_stmt_bind_param() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + prepare_meta_result = mysql_stmt_result_metadata(stmt); // FIXME: no error check + if (mysql_stmt_execute(stmt)) { + fprintf(stderr, " mysql_stmt_execute(), 1 failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } +// memset(bind, 0, sizeof(bind)); + if (mysql_stmt_store_result(stmt)) { + fprintf(stderr, " mysql_stmt_store_result() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + mysql_free_result(prepare_meta_result); + return 0; +} + + +void * mysql_thread(int tid) { + std::mt19937 mt_rand(time(0)); + + thread_data_t *THD; + THD=GloThrData[tid]; + + MYSQL *mysql; + MYSQL_STMT **stmt; + + MySQL_STMTs_local *local_stmts=new MySQL_STMTs_local(); + THD->mysql = mysql_init(NULL); + mysql=THD->mysql; + + char buff[128]; + unsigned int bl=0; + if (!mysql_real_connect(mysql,"127.0.0.1",USER,"",SCHEMA,3306,NULL,0)) { + fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(mysql)); + exit(EXIT_FAILURE); + } + int i; + stmt=(MYSQL_STMT **)malloc(sizeof(MYSQL_STMT*)*NUMPREP); + + { + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a==NULL) { + if (mysql_stmt_prepare(stmt[i], buff, bl)) { + fprintf(stderr, " mysql_stmt_prepare(), failed: %s\n" , mysql_stmt_error(stmt[i])); + exit(EXIT_FAILURE); + } + uint32_t stmid=GloMyStmt->add_prepared_statement(0,(char *)USER,(char *)SCHEMA,buff,bl,stmt[i]); + if (NUMPRO < 32) + fprintf(stdout, "SERVER_statement_id=%lu , PROXY_statement_id=%u\n", stmt[i]->stmt_id, stmid); + local_stmts->insert(stmid,stmt[i]); + } + } + fprintf(stdout, "Prepared statements: %u client, %u proxy/server. ", NUMPREP, GloMyStmt->total_prepared_statements()); + fprintf(stdout, "Created in: "); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + //MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + //if (a) founds++; + } + fprintf(stdout, "Computed %u random strings in: ", i); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + //MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + //if (a) founds++; + } + fprintf(stdout, "Computed %u hashes in: ", i); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a) founds++; + } + fprintf(stdout, "Found %u prepared statements searching by hash in: ", founds); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a) { + // we have a prepared statement, we can run it + MYSQL_STMT *stm=local_stmts->find(a->statement_id); + if (stm) { + run_stmt(stm,(uint32_t)mt_rand()); + founds++; + } + } + } + fprintf(stdout, "Executed %u prepared statements in: ", founds); + } + + { + // for comparison, we run also queries in TEXT protocol + cpu_timer t; + for (i=0; ithread = new std::thread(&mysql_thread,i); + } + for (i=0; ithread->join(); + } + return 0; +} diff --git a/test/PrepStmt/client4.cpp b/test/PrepStmt/client4.cpp new file mode 100644 index 000000000..a272656b5 --- /dev/null +++ b/test/PrepStmt/client4.cpp @@ -0,0 +1,190 @@ +#include "proxysql.h" +#include "cpp.h" + +#include + +#define QUERY1 "SELECT ?" +#define NUMPREP 100000 +#define NUMPRO 1000 +//#define NUMPREP 160 +//#define NUMPRO 4 +#define LOOPS 10 +#define USER "root" +#define SCHEMA "test" + +#define NTHREADS 4 + + +typedef struct _thread_data_t { + MYSQL *mysql; + MYSQL_STMT **stmt; +} thread_data_t; + +uint32_t statement_id; +uint16_t num_params; +uint16_t num_columns; +uint16_t warning_count; + +MySQL_STMT_Manager *GloMyStmt; + +struct cpu_timer +{ + ~cpu_timer() + { + auto end = std::clock() ; + std::cout << double( end - begin ) / CLOCKS_PER_SEC << " secs.\n" ; + }; + + const std::clock_t begin = std::clock() ; +}; + + +int run_stmt(MYSQL_STMT *stmt, int int_data) { + MYSQL_BIND bind[1]; + MYSQL_RES *prepare_meta_result; + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= (char *)&int_data; + bind[0].is_null= 0; + bind[0].length= 0; + if (mysql_stmt_bind_param(stmt, bind)) { + fprintf(stderr, " mysql_stmt_bind_param() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + prepare_meta_result = mysql_stmt_result_metadata(stmt); // FIXME: no error check + if (mysql_stmt_execute(stmt)) { + fprintf(stderr, " mysql_stmt_execute(), 1 failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } +// memset(bind, 0, sizeof(bind)); + if (mysql_stmt_store_result(stmt)) { + fprintf(stderr, " mysql_stmt_store_result() failed\n"); + fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); + exit(EXIT_FAILURE); + } + mysql_free_result(prepare_meta_result); + return 0; +} + + +void * mysql_thread() { + std::mt19937 mt_rand(time(0)); + + + MySQL_STMTs_local *local_stmts=new MySQL_STMTs_local(); + mysql = mysql_init(NULL); + char buff[128]; + unsigned int bl=0; + if (!mysql_real_connect(mysql,"127.0.0.1",USER,"",SCHEMA,3306,NULL,0)) { + fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(mysql)); + exit(EXIT_FAILURE); + } + int i; + stmt=(MYSQL_STMT **)malloc(sizeof(MYSQL_STMT*)*NUMPREP); + { + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a==NULL) { + if (mysql_stmt_prepare(stmt[i], buff, bl)) { + fprintf(stderr, " mysql_stmt_prepare(), failed: %s\n" , mysql_stmt_error(stmt[i])); + exit(EXIT_FAILURE); + } + uint32_t stmid=GloMyStmt->add_prepared_statement(0,(char *)USER,(char *)SCHEMA,buff,bl,stmt[i]); + if (NUMPRO < 32) + fprintf(stdout, "SERVER_statement_id=%lu , PROXY_statement_id=%u\n", stmt[i]->stmt_id, stmid); + local_stmts->insert(stmid,stmt[i]); + } + } + fprintf(stdout, "Prepared statements: %u client, %u proxy/server. ", NUMPREP, GloMyStmt->total_prepared_statements()); + fprintf(stdout, "Created in: "); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + //MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + //if (a) founds++; + } + fprintf(stdout, "Computed %u random strings in: ", i); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + //MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + //if (a) founds++; + } + fprintf(stdout, "Computed %u hashes in: ", i); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a) founds++; + } + fprintf(stdout, "Found %u prepared statements searching by hash in: ", founds); + } + { + unsigned int founds=0; + cpu_timer t; + for (i=0; icompute_hash(0,(char *)USER,(char *)SCHEMA,buff,bl); + MySQL_STMT_Global_info *a=GloMyStmt->find_prepared_statement_by_hash(hash); + if (a) { + // we have a prepared statement, we can run it + founds++; + MYSQL_STMT *stm=local_stmts->find(a->statement_id); + run_stmt(stm,(uint32_t)mt_rand()); + } + } + fprintf(stdout, "Executed %u prepared statements in: ", founds); + } + + { + // for comparison, we run also queries in TEXT protocol + cpu_timer t; + for (i=0; i