From a54abf01753a69c2186d60c155212149be59a7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Mar 2018 14:00:45 +0200 Subject: [PATCH] innobase_kill_query(): Use lock_trx_handle_wait() The caller of THD::awake() should never hold any InnoDB mutexes, so we can always acquire lock_sys->mutex and trx->mutex. --- storage/innobase/handler/ha_innodb.cc | 70 ++++------------------- storage/xtradb/handler/ha_innodb.cc | 82 +++++---------------------- 2 files changed, 24 insertions(+), 128 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4f76c568f17..521ac005437 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1199,7 +1199,9 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ -static void innobase_kill_query(handlerton *hton, THD* thd, enum thd_kill_levels level); +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); /*****************************************************************//** @@ -4891,21 +4893,11 @@ innobase_close_thd( UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock); -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_query( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: MySQL thread being killed */ - enum thd_kill_levels level) /*!< in: kill level */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - DBUG_ENTER("innobase_kill_query"); - DBUG_ASSERT(hton == innodb_hton_ptr); - #ifdef WITH_WSREP wsrep_thd_LOCK(thd); if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) { @@ -4920,51 +4912,11 @@ innobase_kill_query( } wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); - if (trx && trx->lock.wait_lock) { - /* In wsrep BF we have already took lock_sys and trx - mutex either on wsrep_abort_transaction() or - before wsrep_kill_victim(). In replication we - could own lock_sys mutex taken in - lock_deadlock_check_and_resolve(). */ - - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " TRX_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d wait_lock_modes: %s\n", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE), - lock_get_info(trx->lock.wait_lock).c_str()); - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && trx->abort_type == TRX_SERVER_ABORT) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_enter(trx); - } - - ut_ad(lock_mutex_own()); - ut_ad(trx_mutex_own(trx)); - - /* Cancel a pending lock request. */ - if (trx->lock.wait_lock) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_exit(trx); - } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { - lock_mutex_exit(); - } + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); + /* Cancel a pending lock request if there are any */ + lock_trx_handle_wait(trx); } DBUG_VOID_RETURN; @@ -18759,7 +18711,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 9749bcecfe9..d0a98eda0de 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1423,19 +1423,12 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); static void innobase_checkpoint_request(handlerton *hton, void *cookie); -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels); - /*****************************************************************//** Commits a transaction in an InnoDB database or marks an SQL statement ended. @@ -3886,7 +3879,7 @@ innobase_init( innobase_hton->release_temporary_latches = innobase_release_temporary_latches; - innobase_hton->kill_query = innobase_kill_connection; + innobase_hton->kill_query = innobase_kill_query; if (srv_file_per_table) innobase_hton->tablefile_extensions = ha_innobase_exts; @@ -5496,20 +5489,11 @@ ha_innobase::get_row_type() const return(ROW_TYPE_NOT_USED); } -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels) +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - - DBUG_ENTER("innobase_kill_connection"); - DBUG_ASSERT(hton == innodb_hton_ptr); + DBUG_ENTER("innobase_kill_query"); #ifdef WITH_WSREP wsrep_thd_LOCK(thd); @@ -5525,50 +5509,10 @@ innobase_kill_connection( } wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); - - if (trx && trx->lock.wait_lock) { - /* In wsrep BF we have already took lock_sys and trx - mutex either on wsrep_abort_transaction() or - before wsrep_kill_victim(). In replication we - could own lock_sys mutex taken in - lock_deadlock_check_and_resolve().*/ - - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " TRX_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d wait_lock_modes: %s\n", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE), - lock_get_info(trx->lock.wait_lock).c_str()); - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && trx->abort_type == TRX_SERVER_ABORT) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_enter(trx); - } - - ut_ad(lock_mutex_own()); - ut_ad(trx_mutex_own(trx)); - - if (trx->lock.wait_lock) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_exit(trx); - } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { - lock_mutex_exit(); - } + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); + /* Cancel a pending lock request if there are any */ + lock_trx_handle_wait(trx); } DBUG_VOID_RETURN; @@ -19802,7 +19746,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal);