From 56f1350347a6ae418c42feaf89ac9d175d11681d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 29 Apr 2024 04:48:36 +0000 Subject: [PATCH 1/5] Optimization on multiple_prepared_statements-t multiple_prepared_statements-t.cpp is now multi-threaded --- .../tests/multiple_prepared_statements-t.cpp | 287 ++++++++++++++---- 1 file changed, 220 insertions(+), 67 deletions(-) diff --git a/test/tap/tests/multiple_prepared_statements-t.cpp b/test/tap/tests/multiple_prepared_statements-t.cpp index ea3bed603..d88fad720 100644 --- a/test/tap/tests/multiple_prepared_statements-t.cpp +++ b/test/tap/tests/multiple_prepared_statements-t.cpp @@ -42,9 +42,12 @@ inline unsigned long long monotonic_time() { return (((unsigned long long) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000); } +#define NTHREADS 5 #define NCONNS 6 #define NPREP 15000 #define PROGRESS 2000 + +pthread_mutex_t mtx[NCONNS]; MYSQL* conns[NCONNS]; int ids[NCONNS*NPREP]; MYSQL_STMT * stmts[NCONNS*NPREP]; @@ -125,6 +128,163 @@ int execute_stmt(int idx) { return 0; } +void * prepare_thread(void *arg) { + int thread_id = *(int *)arg; + for (int i=0; i Date: Mon, 29 Apr 2024 06:48:33 +0000 Subject: [PATCH 2/5] Better randomize in set_testing-240-t --- test/tap/tests/set_testing-240-t.cpp | 5 +++-- test/tap/tests/set_testing-240.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/tap/tests/set_testing-240-t.cpp b/test/tap/tests/set_testing-240-t.cpp index cacf8c005..f5e157dfa 100644 --- a/test/tap/tests/set_testing-240-t.cpp +++ b/test/tap/tests/set_testing-240-t.cpp @@ -116,7 +116,8 @@ std::unordered_map vars_counters; */ void * my_conn_thread(void *arg) { - g_seed = time(NULL) ^ getpid() ^ pthread_self(); + g_seed = monotonic_time() * pthread_self() + monotonic_time(); + srand(g_seed); unsigned int select_OK=0; unsigned int select_ERR=0; int i, j; @@ -168,7 +169,7 @@ void * my_conn_thread(void *arg) { int fr = rand(); int r1=fr%count; //int r2=fastrand()%testCases.size(); - int r2=rand()%testCases.size(); + int r2=(fastrand() + (RAND_MAX * fastrand())) %testCases.size(); if (j%queries_per_connections==0) { mysql_idx=r1; diff --git a/test/tap/tests/set_testing-240.h b/test/tap/tests/set_testing-240.h index 60254da37..68b42f001 100644 --- a/test/tap/tests/set_testing-240.h +++ b/test/tap/tests/set_testing-240.h @@ -146,7 +146,7 @@ struct cpu_timer inline int fastrand() { - g_seed = (214014*g_seed+2531011); + g_seed = (214013*g_seed+2531011); return (g_seed>>16)&0x7FFF; } From 13c5ed3f968a40579e5c04a493c0ccf2f69ce8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 29 Apr 2024 07:15:28 +0000 Subject: [PATCH 3/5] Increase sleep time in kill_connection3-t --- test/tap/tests/kill_connection3-t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tap/tests/kill_connection3-t.cpp b/test/tap/tests/kill_connection3-t.cpp index ef28ac6cb..1c023ffb5 100644 --- a/test/tap/tests/kill_connection3-t.cpp +++ b/test/tap/tests/kill_connection3-t.cpp @@ -191,7 +191,7 @@ int main(int argc, char** argv) { rc = run_q(proxysql_admin, s.c_str()); ok(rc == 0 , "%s" , s.c_str()); } - sleep(1); + sleep(3); for (int i = 0; i < NUM_CONNS ; i++) { MYSQL * mysql = conns[i]; int rc = run_q(mysql, "DO 1"); From df0e36e854b5b6996be4c406f3a570409e3306d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 30 Apr 2024 21:03:51 +0700 Subject: [PATCH 4/5] Create MySQL_Connection.md --- doc/internal/MySQL_Connection.md | 70 ++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 doc/internal/MySQL_Connection.md diff --git a/doc/internal/MySQL_Connection.md b/doc/internal/MySQL_Connection.md new file mode 100644 index 000000000..50377d3c2 --- /dev/null +++ b/doc/internal/MySQL_Connection.md @@ -0,0 +1,70 @@ +### Flowchart of `MySQL_Connection::async_query()` + +This function asynchronously executes a query on the MySQL connection. +It handles various states of the asynchronous query execution process and returns appropriate status codes indicating the result of the execution. + +Returns an integer status code indicating the result of the query execution: +- 0: Query execution completed successfully. +- -1: Query execution failed. +- 1: Query execution in progress. +- 2: Processing a multi-statement query, control needs to be transferred to MySQL_Session. +- 3: In the middle of processing a multi-statement query. + + +```mermaid +--- +title: MySQL_Connection::async_query() +--- +flowchart TD +Assert["assert()"] +ValidConnection{Valid Connection} +ValidConnection -- no --> Assert +IsServerOffline{"IsServerOffline()"} +ValidConnection -- yes --> IsServerOffline +IsServerOffline -- yes --> ReturnMinus1 +asyncStateMachine1{async_state_machine} +asyncStateMachine2{async_state_machine} +IsServerOffline -- no --> asyncStateMachine1 +asyncStateMachine1 -- ASYNC_QUERY_END --> Return0 +handler["handler()"] +asyncStateMachine1 --> handler +handler --> asyncStateMachine2 +asyncStateMachine2 -- ASYNC_QUERY_END --> mysql_error{"mysql_error"} +asyncStateMachine2 -- ASYNC_STMT_EXECUTE_END --> mysql_error +asyncStateMachine2 -- ASYNC_STMT_PREPARE_FAILED --> ReturnMinus1 +asyncStateMachine2 -- ASYNC_STMT_PREPARE_SUCCESSFUL --> Return0 +mysql_error -- yes --> ReturnMinus1 +mysql_error -- no --> Return0 +asyncStateMachine2 -- ASYNC_NEXT_RESULT_START --> Return2 +processing_multi_statement{"processing_multi_statement"} +asyncStateMachine2 --> processing_multi_statement +processing_multi_statement -- yes --> Return3 +processing_multi_statement -- no --> Return1 +ReturnMinus1["return -1"] +Return0["return 0"] +Return1["return 1"] +Return2["return 2"] +Return3["return 3"] +``` + +### Flowchart of `MySQL_Connection::IsServerOffline()` + +```mermaid +--- +title: MySQL_Connection::IsServerOffline() +--- +flowchart TD +True[true] +False[false] +SS1{"server_status"} +SA{"shunned_automatic"} +SB{"shunned_and_kill_all_connections"} +SS1 -- OFFLINE_HARD --> True +SS1 -- REPLICATION_LAG --> True +SS1 -- SHUNNED --> SA +SA -- yes --> SB +SB -- yes --> True +SA -- no --> False +SB -- no --> False +SS1 --> False +``` From 6c7c0cc2b583ccfff64968d281a2e6fa5b7f5b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 30 Apr 2024 21:48:48 +0700 Subject: [PATCH 5/5] Create MySQL_Session.md --- doc/internal/MySQL_Session.md | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 doc/internal/MySQL_Session.md diff --git a/doc/internal/MySQL_Session.md b/doc/internal/MySQL_Session.md new file mode 100644 index 000000000..e56fc6c29 --- /dev/null +++ b/doc/internal/MySQL_Session.md @@ -0,0 +1,68 @@ +### Flowchart of `MySQL_Session::RunQuery()` + +This function mostly calls `MySQL_Connection::async_query()` with the right arguments. +Returns an integer status code indicating the result of the query execution: +- 0: Query execution completed successfully. +- -1: Query execution failed. +- 1: Query execution in progress. +- 2: Processing a multi-statement query, control needs to be transferred to MySQL_Session. +- 3: In the middle of processing a multi-statement query. + +```mermaid +--- +title: MySQL_Session::RunQuery() +--- +flowchart TD +RQ["MySQL_Connection::async_query()"] +BEGIN --> RQ +RQ --> END +``` + +### Flowchart of `MySQL_Session::handler()` + +WORK IN PROGRESS + +```mermaid +--- +title: MySQL_Session::handler() +--- +flowchart TD +RQ["rc = RunQuery()"] +RC{rc} +CBCS["rc1 = handler_ProcessingQueryError_CheckBackendConnectionStatus()"] +RC1{rc1} +RQ --> RC +RC -- 0 --> OK +RC -- -1 --> CBCS +CBCS --> RC1 +CS["CONNECTING_SERVER"] +ReturnMinus1["return -1"] +RC1 -- -1 --> ReturnMinus1 +RC1 -- 1 --> CS +HM1CLE1["handler_minus1_ClientLibraryError()"] +HM1CLE2["handler_minus1_ClientLibraryError()"] +myerr1{"myerr >= 2000 +&& +myerr < 3000"} +RC1 --> myerr1 +myerr1 -- yes --> HM1CLE1 +HM1CLE1 -- true --> CS +HM1CLE1 -- false --> ReturnMinus1 +HM1LEDQ1["handler_minus1_LogErrorDuringQuery()"] +myerr1 -- no --> HM1LEDQ1 +HM1HEC1["handler_minus1_HandleErrorCodes()"] +HM1LEDQ1 --> HM1HEC1 +HM1HEC1 -- true --> HR1{"handler_ret"} +HR1 -- 0 --> CS +HR1 --> RHR1["return handler_ret"] +HM1GEM1["handler_minus1_GenerateErrorMessage()"] +HM1HEC1 -- false --> HM1GEM1 +RE["RequestEnd()"] +HM1HBC1["handler_minus1_HandleBackendConnection()"] +HM1GEM1 --> RE +RE --> HM1HBC1 +``` + + +### Flowchart of `MySQL_Session::handler_ProcessingQueryError_CheckBackendConnectionStatus()` +TODO