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 +``` 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 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"); 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 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; }