diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 24976ff9f1a..e84750369f9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7366,13 +7366,23 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, if (!threads_to_kill.is_empty()) { List_iterator_fast it(threads_to_kill); - THD *ptr; - while ((ptr= it++)) + THD *next_ptr; + THD *ptr= it++; + do { ptr->awake(kill_signal); + /* + Careful here: The list nodes are allocated on the memroots of the + THDs to be awakened. + But those THDs may be terminated and deleted as soon as we release + LOCK_thd_data, which will make the list nodes invalid. + Since the operation "it++" dereferences the "next" pointer of the + previous list node, we need to do this while holding LOCK_thd_data. + */ + next_ptr= it++; pthread_mutex_unlock(&ptr->LOCK_thd_data); (*rows)++; - } + } while ((ptr= next_ptr)); } DBUG_RETURN(0); }