Implementation of max_transaction_idle_time

Former max_transaction_time is now renamed to max_transaction_idle_time.
mysql-max_transaction_idle_time defines the maximum time a transaction can stay idle.
mysql-max_transaction_time defines the maximum time of a transaction since its start.
v2.0.15-KillTrx
René Cannaò 6 years ago
parent 31377865ca
commit 0bc209cf41

@ -0,0 +1 @@
libmicrohttpd-0.9.68

@ -144,6 +144,7 @@ class MySQL_Session
unsigned long long pause_until;
unsigned long long idle_since;
unsigned long long transaction_started_at;
// pointers
MySQL_Thread *thread;
@ -171,7 +172,7 @@ class MySQL_Session
int next_query_flagIN;
int mirror_hostgroup;
int mirror_flagOUT;
int active_transactions;
unsigned int active_transactions;
int autocommit_on_hostgroup;
int transaction_persistent_hostgroup;
int to_process;

@ -337,6 +337,7 @@ class MySQL_Threads_Handler
bool use_tcp_keepalive;
int tcp_keepalive_time;
int throttle_connections_per_sec_to_hostgroup;
int max_transaction_idle_time;
int max_transaction_time;
int threshold_query_length;
int threshold_resultset_size;

@ -695,6 +695,7 @@ __thread bool mysql_thread___firewall_whitelist_enabled;
__thread bool mysql_thread___use_tcp_keepalive;
__thread int mysql_thread___tcp_keepalive_time;
__thread int mysql_thread___throttle_connections_per_sec_to_hostgroup;
__thread int mysql_thread___max_transaction_idle_time;
__thread int mysql_thread___max_transaction_time;
__thread int mysql_thread___threshold_query_length;
__thread int mysql_thread___threshold_resultset_size;
@ -842,6 +843,7 @@ extern __thread bool mysql_thread___firewall_whitelist_enabled;
extern __thread bool mysql_thread___use_tcp_keepalive;
extern __thread int mysql_thread___tcp_keepalive_time;
extern __thread int mysql_thread___throttle_connections_per_sec_to_hostgroup;
extern __thread int mysql_thread___max_transaction_idle_time;
extern __thread int mysql_thread___max_transaction_time;
extern __thread int mysql_thread___threshold_query_length;
extern __thread int mysql_thread___threshold_resultset_size;

@ -457,6 +457,8 @@ MySQL_Session::MySQL_Session() {
mirrorPkt.ptr=NULL;
mirrorPkt.size=0;
set_status(NONE);
idle_since = 0;
transaction_started_at = 0;
CurrentQuery.sess=this;
@ -2785,8 +2787,11 @@ int MySQL_Session::handler() {
unsigned int j;
unsigned char c;
if (active_transactions <= 0) {
if (active_transactions == 0) {
active_transactions=NumActiveTransactions();
if (active_transactions > 0) {
transaction_started_at = thread->curtime;
}
}
// FIXME: Sessions without frontend are an ugly hack
if (session_fast_forward==false) {

@ -414,6 +414,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"firewall_whitelist_enabled",
(char *)"firewall_whitelist_errormsg",
(char *)"throttle_connections_per_sec_to_hostgroup",
(char *)"max_transaction_idle_time",
(char *)"max_transaction_time",
(char *)"multiplexing",
(char *)"log_unhealthy_connections",
@ -561,6 +562,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.use_tcp_keepalive=false;
variables.tcp_keepalive_time=0;
variables.throttle_connections_per_sec_to_hostgroup=1000000;
variables.max_transaction_idle_time=4*3600*1000;
variables.max_transaction_time=4*3600*1000;
variables.hostgroup_manager_verbose=1;
variables.binlog_reader_connect_retry_msec=3000;
@ -978,6 +980,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
if (!strcmp(name,"max_connections")) return (int)variables.max_connections;
if (!strcmp(name,"max_stmts_cache")) return (int)variables.max_stmts_cache;
if (!strcmp(name,"max_stmts_per_connection")) return (int)variables.max_stmts_per_connection;
if (!strcmp(name,"max_transaction_idle_time")) return (int)variables.max_transaction_idle_time;
if (!strcmp(name,"max_transaction_time")) return (int)variables.max_transaction_time;
if (!strcmp(name,"min_num_servers_lantency_awareness")) return (int)variables.min_num_servers_lantency_awareness;
}
@ -1386,6 +1389,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
sprintf(intbuf,"%d",variables.throttle_connections_per_sec_to_hostgroup);
return strdup(intbuf);
}
if (!strcasecmp(name,"max_transaction_idle_time")) {
sprintf(intbuf,"%d",variables.max_transaction_idle_time);
return strdup(intbuf);
}
if (!strcasecmp(name,"max_transaction_time")) {
sprintf(intbuf,"%d",variables.max_transaction_time);
return strdup(intbuf);
@ -1936,6 +1943,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi
return false;
}
}
if (!strcasecmp(name,"max_transaction_idle_time")) {
int intv=atoi(value);
if (intv >= 1000 && intv <= 20*24*3600*1000) {
variables.max_transaction_idle_time=intv;
return true;
} else {
return false;
}
}
if (!strcasecmp(name,"max_transaction_time")) {
int intv=atoi(value);
if (intv >= 1000 && intv <= 20*24*3600*1000) {
@ -4335,18 +4351,54 @@ void MySQL_Thread::process_all_sessions() {
if (idle_maintenance_thread==false)
#endif // IDLE_THREADS
{
sess->active_transactions=sess->NumActiveTransactions();
{
unsigned long long sess_active_transactions = sess->active_transactions;
sess->active_transactions=sess->NumActiveTransactions();
// in case we detected a new transaction just now
if (sess->active_transactions == 0) {
sess->transaction_started_at = 0;
} else {
if (sess_active_transactions == 0) {
sess->transaction_started_at = curtime;
}
}
}
total_active_transactions_ += sess->active_transactions;
sess->to_process=1;
if ( (sess_time/1000 > (unsigned long long)mysql_thread___max_transaction_time) || (sess_time/1000 > (unsigned long long)mysql_thread___wait_timeout) ) {
if ( (sess_time/1000 > (unsigned long long)mysql_thread___max_transaction_idle_time) || (sess_time/1000 > (unsigned long long)mysql_thread___wait_timeout) ) {
//numTrx = sess->NumActiveTransactions();
numTrx = sess->active_transactions;
if (numTrx) {
// the session has idle transactions, kill it
if (sess_time/1000 > (unsigned long long)mysql_thread___max_transaction_time) sess->killed=true;
if (sess_time/1000 > (unsigned long long)mysql_thread___max_transaction_idle_time) {
sess->killed=true;
if (sess->client_myds) {
proxy_warning("Killing client connection %s:%d because of (possible) transaction idle for %llums\n",sess->client_myds->addr.addr,sess->client_myds->addr.port, sess_time/1000);
}
}
} else {
// the session is idle, kill it
if (sess_time/1000 > (unsigned long long)mysql_thread___wait_timeout) sess->killed=true;
if (sess_time/1000 > (unsigned long long)mysql_thread___wait_timeout) {
sess->killed=true;
if (sess->client_myds) {
proxy_warning("Killing client connection %s:%d because inactive for %llums\n",sess->client_myds->addr.addr,sess->client_myds->addr.port, sess_time/1000);
}
}
}
} else {
if (sess->active_transactions > 0) {
// here is all the logic related to max_transaction_time
unsigned long long trx_started = sess->transaction_started_at;
if (trx_started > 0 && curtime > trx_started) {
unsigned long long trx_time = curtime - trx_started;
unsigned long long trx_time_ms = trx_time/1000;
if (trx_time_ms > (unsigned long long)mysql_thread___max_transaction_time) {
sess->killed=true;
if (sess->client_myds) {
proxy_warning("Killing client connection %s:%d because of (possible) transaction running for %llums\n",sess->client_myds->addr.addr,sess->client_myds->addr.port, trx_time_ms);
}
}
}
}
}
if (servers_table_version_current != servers_table_version_previous) { // bug fix for #1085
@ -4376,7 +4428,9 @@ void MySQL_Thread::process_all_sessions() {
}
#endif // IDLE_THREADS
} else {
sess->active_transactions = -1;
// NOTE: we used the special value -1 to inform MySQL_Session::handler() to recompute it
// removing this logic in 2.0.15
//sess->active_transactions = -1;
}
if (sess->healthy==0) {
char _buf[1024];
@ -4442,6 +4496,7 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___use_tcp_keepalive=(bool)GloMTH->get_variable_int((char *)"use_tcp_keepalive");
mysql_thread___tcp_keepalive_time=GloMTH->get_variable_int((char *)"tcp_keepalive_time");
mysql_thread___throttle_connections_per_sec_to_hostgroup=GloMTH->get_variable_int((char *)"throttle_connections_per_sec_to_hostgroup");
mysql_thread___max_transaction_idle_time=GloMTH->get_variable_int((char *)"max_transaction_idle_time");
mysql_thread___max_transaction_time=GloMTH->get_variable_int((char *)"max_transaction_time");
mysql_thread___threshold_query_length=GloMTH->get_variable_int((char *)"threshold_query_length");
mysql_thread___threshold_resultset_size=GloMTH->get_variable_int((char *)"threshold_resultset_size");

Loading…
Cancel
Save