Commit dc116541 authored by Monty's avatar Monty

Do not use MEM_ROOT in set_killed_no_mutex()

The reason for this change are the following:
- If we call set_killed() from one thread to kill another thread with
  a message, there may be concurrent usage of the MEM_ROOT which is
  not supported (this could cause memory corruption).
  We do not currently have code that does this, but the API allows this
  and it is better to be fix the issue before it happens.
- The per thread memory tracking does not work if one thread uses
  another threads MEM_ROOT.
- set_killed() can be called if a MEM_ROOT allocation fails.  In this case
  it is not good to try to allocate more memory from potentially the same
  MEM_ROOT.

Fix is to use my_malloc() instead of mem_root for killed messages.
parent 9e424b62
......@@ -1649,6 +1649,7 @@ void THD::reset_for_reuse()
wsrep_cs().reset_error();
wsrep_aborter= 0;
wsrep_abort_by_kill= NOT_KILLED;
my_free(wsrep_abort_by_kill_err);
wsrep_abort_by_kill_err= 0;
#ifndef DBUG_OFF
wsrep_killed_state= 0;
......@@ -1689,6 +1690,8 @@ THD::~THD()
#ifdef WITH_WSREP
mysql_cond_destroy(&COND_wsrep_thd);
my_free(wsrep_abort_by_kill_err);
wsrep_abort_by_kill_err= 0;
#endif
mdl_context.destroy();
......@@ -1708,6 +1711,7 @@ THD::~THD()
main_lex.free_set_stmt_mem_root();
free_root(&main_mem_root, MYF(0));
my_free(m_token_array);
my_free(killed_err);
main_da.free_memory();
if (tdc_hash_pins)
lf_hash_put_pins(tdc_hash_pins);
......@@ -2131,7 +2135,11 @@ void THD::reset_killed()
mysql_mutex_assert_not_owner(&LOCK_thd_kill);
mysql_mutex_lock(&LOCK_thd_kill);
killed= NOT_KILLED;
killed_err= 0;
if (unlikely(killed_err))
{
my_free(killed_err);
killed_err= 0;
}
mysql_mutex_unlock(&LOCK_thd_kill);
}
#ifdef WITH_WSREP
......@@ -2142,6 +2150,7 @@ void THD::reset_killed()
mysql_mutex_assert_not_owner(&LOCK_thd_kill);
mysql_mutex_lock(&LOCK_thd_kill);
wsrep_abort_by_kill= NOT_KILLED;
my_free(wsrep_abort_by_kill_err);
wsrep_abort_by_kill_err= 0;
mysql_mutex_unlock(&LOCK_thd_kill);
}
......
......@@ -4182,7 +4182,8 @@ class THD: public THD_count, /* this must be first */
The worst things that can happen is that we get
a suboptimal error message.
*/
killed_err= (err_info*) alloc_root(&main_mem_root, sizeof(*killed_err));
if (!killed_err)
killed_err= (err_info*) my_malloc(sizeof(*killed_err), MYF(MY_WME));
if (likely(killed_err))
{
killed_err->no= killed_errno_arg;
......
......@@ -485,6 +485,7 @@ void wsrep_backup_kill_for_commit(THD *thd)
thd->wsrep_trx().state() != wsrep::transaction::s_must_replay)
{
thd->wsrep_abort_by_kill= thd->killed;
my_free(thd->wsrep_abort_by_kill_err);
thd->wsrep_abort_by_kill_err= thd->killed_err;
thd->killed= NOT_KILLED;
thd->killed_err= 0;
......@@ -497,6 +498,7 @@ void wsrep_restore_kill_after_commit(THD *thd)
DBUG_ASSERT(WSREP(thd));
mysql_mutex_assert_owner(&thd->LOCK_thd_kill);
thd->killed= thd->wsrep_abort_by_kill;
my_free(thd->killed_err);
thd->killed_err= thd->wsrep_abort_by_kill_err;
thd->wsrep_abort_by_kill= NOT_KILLED;
thd->wsrep_abort_by_kill_err= 0;
......
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