diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index ce6a91ad9..815b93be8 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -360,6 +360,7 @@ class MySQL_Threads_Handler int query_digests_max_query_length; int wait_timeout; int throttle_max_bytes_per_second_to_client; + int throttle_ratio_server_to_client; int max_connections; int max_stmts_per_connection; int max_stmts_cache; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 7438064b9..602de670a 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -593,6 +593,7 @@ __thread int mysql_thread___threshold_query_length; __thread int mysql_thread___threshold_resultset_size; __thread int mysql_thread___wait_timeout; __thread int mysql_thread___throttle_max_bytes_per_second_to_client; +__thread int mysql_thread___throttle_ratio_server_to_client; __thread int mysql_thread___max_connections; __thread int mysql_thread___max_stmts_per_connection; __thread int mysql_thread___max_stmts_cache; @@ -692,6 +693,7 @@ extern __thread int mysql_thread___threshold_query_length; extern __thread int mysql_thread___threshold_resultset_size; extern __thread int mysql_thread___wait_timeout; extern __thread int mysql_thread___throttle_max_bytes_per_second_to_client; +extern __thread int mysql_thread___throttle_ratio_server_to_client; extern __thread int mysql_thread___max_connections; extern __thread int mysql_thread___max_stmts_per_connection; extern __thread int mysql_thread___max_stmts_cache; diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 4392bed9f..a69efb29b 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -243,6 +243,7 @@ static char * mysql_thread_variables_names[]= { (char *)"query_digests_max_query_length", (char *)"wait_timeout", (char *)"throttle_max_bytes_per_second_to_client", + (char *)"throttle_ratio_server_to_client", (char *)"max_connections", (char *)"max_stmts_per_connection", (char *)"max_stmts_cache", @@ -347,6 +348,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.query_digests_max_query_length=65000; // legacy default variables.wait_timeout=8*3600*1000; variables.throttle_max_bytes_per_second_to_client=2147483647; + variables.throttle_ratio_server_to_client=0; variables.max_connections=10*1000; variables.max_stmts_per_connection=20; variables.max_stmts_cache=10000; @@ -598,6 +600,7 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { if (!strcasecmp(name,"query_digests_max_query_length")) return (int)variables.query_digests_max_query_length; if (!strcasecmp(name,"wait_timeout")) return (int)variables.wait_timeout; if (!strcasecmp(name,"throttle_max_bytes_per_second_to_client")) return (int)variables.throttle_max_bytes_per_second_to_client; + if (!strcasecmp(name,"throttle_ratio_server_to_client")) return (int)variables.throttle_ratio_server_to_client; if (!strcasecmp(name,"max_connections")) return (int)variables.max_connections; if (!strcasecmp(name,"max_stmts_per_connection")) return (int)variables.max_stmts_per_connection; if (!strcasecmp(name,"max_stmts_cache")) return (int)variables.max_stmts_cache; @@ -867,6 +870,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f sprintf(intbuf,"%d",variables.throttle_max_bytes_per_second_to_client); return strdup(intbuf); } + if (!strcasecmp(name,"throttle_ratio_server_to_client")) { + sprintf(intbuf,"%d",variables.throttle_ratio_server_to_client); + return strdup(intbuf); + } if (!strcasecmp(name,"max_connections")) { sprintf(intbuf,"%d",variables.max_connections); return strdup(intbuf); @@ -1285,6 +1292,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t return false; } } + if (!strcasecmp(name,"throttle_ratio_server_to_client")) { + int intv=atoi(value); + if (intv >= 0 && intv <= 100) { + variables.throttle_ratio_server_to_client=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"max_connections")) { int intv=atoi(value); if (intv >= 1 && intv <= 1000*1000) { @@ -2379,7 +2395,9 @@ __mysql_thread_exit_add_mirror: mypolls.myds[n]->remove_pollout(); } if (myds->myds_type==MYDS_BACKEND) { - mypolls.fds[n].events = 0; + if (mysql_thread___throttle_ratio_server_to_client) { + mypolls.fds[n].events = 0; + } } } @@ -2988,6 +3006,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___query_digests_max_query_length=GloMTH->get_variable_int((char *)"query_digests_max_query_length"); mysql_thread___wait_timeout=GloMTH->get_variable_int((char *)"wait_timeout"); mysql_thread___throttle_max_bytes_per_second_to_client=GloMTH->get_variable_int((char *)"throttle_max_bytes_per_second_to_client"); + mysql_thread___throttle_ratio_server_to_client=GloMTH->get_variable_int((char *)"throttle_ratio_server_to_client"); mysql_thread___max_connections=GloMTH->get_variable_int((char *)"max_connections"); mysql_thread___max_stmts_per_connection=GloMTH->get_variable_int((char *)"max_stmts_per_connection"); mysql_thread___max_stmts_cache=GloMTH->get_variable_int((char *)"max_stmts_cache"); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 2290eed7f..5341a8c6e 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -561,7 +561,7 @@ void MySQL_Connection::set_is_client() { #define NEXT_IMMEDIATE(new_st) do { async_state_machine = new_st; goto handler_again; } while (0) MDB_ASYNC_ST MySQL_Connection::handler(short event) { - unsigned int processed_bytes=0; // issue #527 : this variable will store the amount of bytes processed during this event + unsigned long long processed_bytes=0; // issue #527 : this variable will store the amount of bytes processed during this event if (mysql==NULL) { // it is the first time handler() is being called async_state_machine=ASYNC_CONNECT_START; @@ -922,7 +922,11 @@ handler_again: __sync_fetch_and_add(&parent->bytes_recv,br); myds->sess->thread->status_variables.queries_backends_bytes_recv+=br; processed_bytes+=br; // issue #527 : this variable will store the amount of bytes processed during this event - if ((processed_bytes > (unsigned int)mysql_thread___threshold_resultset_size*4) || (processed_bytes > (unsigned int)mysql_thread___throttle_max_bytes_per_second_to_client/10)) { + if ( + (processed_bytes > (unsigned int)mysql_thread___threshold_resultset_size*8) + || + ( mysql_thread___throttle_ratio_server_to_client && (processed_bytes > (unsigned long long)mysql_thread___throttle_max_bytes_per_second_to_client/10*(unsigned long long)mysql_thread___throttle_ratio_server_to_client) ) + ) { next_event(ASYNC_USE_RESULT_CONT); // we temporarily pause } else { NEXT_IMMEDIATE(ASYNC_USE_RESULT_CONT); // we continue looping