Merge pull request #3071 from sysown/v2.1.0-KillTrx

Implementation of max_transaction_idle_time
pull/3072/head
René Cannaò 6 years ago committed by GitHub
commit 22b0c9065b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -149,6 +149,7 @@ class MySQL_Session
unsigned long long pause_until;
unsigned long long idle_since;
unsigned long long transaction_started_at;
// pointers
MySQL_Thread *thread;
@ -176,7 +177,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;

@ -448,6 +448,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;
@ -843,6 +844,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;

@ -463,6 +463,9 @@ MySQL_Session::MySQL_Session() {
mirrorPkt.size=0;
set_status(session_status___NONE);
idle_since = 0;
transaction_started_at = 0;
CurrentQuery.sess=this;
current_hostgroup=-1;
@ -3468,8 +3471,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) {

@ -464,6 +464,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",
@ -1034,6 +1035,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;
@ -1456,6 +1458,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;
}
@ -1865,6 +1868,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);
@ -2419,6 +2426,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) {
@ -4707,17 +4723,54 @@ void MySQL_Thread::process_all_sessions() {
#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
@ -4747,7 +4800,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];
@ -4813,6 +4868,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