Commit 7241258c authored by Nirbhay Choubey's avatar Nirbhay Choubey

MDEV-9416: MariaDB galera got signal 11 when altering table add unique index

When a BF thread attempts to abort a victim thread's transaction,
the victim thread is not locked and thus its not safe to rely on
its data structures like htons registered for the trx.

So, instead of getting the registered htons from victim, innodb's
hton can be looked up directly from installed_htons[] and used to
abort the transaction. (Same technique is used in older versions)
parent 6bb6f30f
...@@ -6103,6 +6103,13 @@ void handler::set_lock_type(enum thr_lock_type lock) ...@@ -6103,6 +6103,13 @@ void handler::set_lock_type(enum thr_lock_type lock)
@note Aborting the transaction does NOT end it, it still has to @note Aborting the transaction does NOT end it, it still has to
be rolled back with hton->rollback(). be rolled back with hton->rollback().
@note It is safe to abort from one thread (bf_thd) the transaction,
running in another thread (victim_thd), because InnoDB's lock_sys and
trx_mutex guarantee the necessary protection. However, its not safe
to access victim_thd->transaction, because it's not protected from
concurrent accesses. And it's an overkill to take LOCK_plugin and
iterate the whole installed_htons[] array every time.
@param bf_thd brute force THD asking for the abort @param bf_thd brute force THD asking for the abort
@param victim_thd victim THD to be aborted @param victim_thd victim THD to be aborted
...@@ -6119,29 +6126,16 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal) ...@@ -6119,29 +6126,16 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* Try statement transaction if standard one is not set. */ handlerton *hton= installed_htons[DB_TYPE_INNODB];
THD_TRANS *trans= (victim_thd->transaction.all.ha_list) ? if (hton && hton->abort_transaction)
&victim_thd->transaction.all : &victim_thd->transaction.stmt;
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
for (; ha_info; ha_info= ha_info_next)
{ {
handlerton *hton= ha_info->ht(); hton->abort_transaction(hton, bf_thd, victim_thd, signal);
if (!hton->abort_transaction)
{
/* Skip warning for binlog & wsrep. */
if (hton->db_type != DB_TYPE_BINLOG && hton != wsrep_hton)
{
WSREP_WARN("Cannot abort transaction.");
}
}
else
{
hton->abort_transaction(hton, bf_thd, victim_thd, signal);
}
ha_info_next= ha_info->next();
} }
else
{
WSREP_WARN("Cannot abort InnoDB transaction");
}
DBUG_RETURN(0); DBUG_RETURN(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