Commit 9b750dcb authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-23536 Race condition between KILL and transaction commit

Server part:
  kill_handlerton() was accessing thd->ha_data[] for some other thd,
  while it could be concurrently modified by its owner thd.

  protect thd->ha_data[] modifications with a mutex.
  require this mutex when accessing thd->ha_data[] from kill_handlerton.

InnoDB part:
  on close_connection, detach trx from thd before freeing the trx
parent 66f4900b
......@@ -838,6 +838,7 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
{
handlerton *hton= plugin_hton(plugin);
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
if (hton->state == SHOW_OPTION_YES && hton->kill_query &&
thd_get_ha_data(thd, hton))
hton->kill_query(hton, thd, *(enum thd_kill_levels *) level);
......
......@@ -444,6 +444,7 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
const void *ha_data)
{
plugin_ref *lock= &thd->ha_data[hton->slot].lock;
DBUG_ASSERT(thd == current_thd);
if (ha_data && !*lock)
*lock= ha_lock_engine(NULL, (handlerton*) hton);
else if (!ha_data && *lock)
......@@ -451,7 +452,9 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
plugin_unlock(NULL, *lock);
*lock= NULL;
}
mysql_mutex_lock(&thd->LOCK_thd_data);
*thd_ha_data(thd, hton)= (void*) ha_data;
mysql_mutex_unlock(&thd->LOCK_thd_data);
}
......
......@@ -5117,6 +5117,7 @@ innobase_close_connection(
if (trx) {
thd_set_ha_data(thd, hton, NULL);
if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) {
sql_print_error("Transaction not registered for MariaDB 2PC, "
......
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