Fix for bug #25966 "2MB per second endless memory consumption after LOCK

TABLE ... WRITE".

Memory and CPU hogging occured when connection which had to wait for table
lock was serviced by thread which previously serviced connection that was
killed (note that connections can reuse threads if thread cache is enabled).
One possible scenario which exposed this problem was when thread which
provided binlog dump to replication slave was implicitly/automatically
killed when the same slave reconnected and started pulling data through
different thread/connection.
The problem also occured when one killed particular query in connection
(using KILL QUERY) and later this connection had to wait for some table
lock.

This problem was caused by the fact that thread-specific mysys_var::abort
variable, which indicates that waiting operations on mysys layer should
be aborted (this includes waiting for table locks), was set by kill
operation but was never reset back. So this value was "inherited" by the
following statements or even other connections (which reused the same
physical thread). Such discrepancy between this variable and THD::killed
flag broke logic on SQL-layer and caused CPU and memory hogging.

This patch tries to fix this problem by properly resetting this member.

There is no test-case associated with this patch since it is hard to test
for memory/CPU hogging conditions in our test-suite.
parent d7311aab
...@@ -1681,6 +1681,12 @@ void end_thread(THD *thd, bool put_in_cache) ...@@ -1681,6 +1681,12 @@ void end_thread(THD *thd, bool put_in_cache)
thd->real_id=pthread_self(); thd->real_id=pthread_self();
thd->thread_stack= (char*) &thd; // For store_globals thd->thread_stack= (char*) &thd; // For store_globals
(void) thd->store_globals(); (void) thd->store_globals();
/*
THD::mysys_var::abort is associated with physical thread rather
than with THD object. So we need to reset this flag before using
this thread for handling of new THD object/connection.
*/
thd->mysys_var->abort= 0;
thd->thr_create_time= time(NULL); thd->thr_create_time= time(NULL);
threads.append(thd); threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
......
...@@ -1087,6 +1087,7 @@ sp_head::execute(THD *thd) ...@@ -1087,6 +1087,7 @@ sp_head::execute(THD *thd)
ctx->enter_handler(hip); ctx->enter_handler(hip);
thd->clear_error(); thd->clear_error();
thd->killed= THD::NOT_KILLED; thd->killed= THD::NOT_KILLED;
thd->mysys_var->abort= 0;
continue; continue;
} }
} }
......
...@@ -1604,7 +1604,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1604,7 +1604,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_ENTER("dispatch_command"); DBUG_ENTER("dispatch_command");
if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA) if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
{
thd->killed= THD::NOT_KILLED; thd->killed= THD::NOT_KILLED;
thd->mysys_var->abort= 0;
}
thd->command=command; thd->command=command;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment