diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2020-09-18 17:35:08 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2021-04-20 23:45:19 +0200 |
commit | f867cca46b47f2ef9170ac9a7130bd3e493b8338 (patch) | |
tree | aba4d04bf4cfdd0792503ebc3c337515823fffc3 | |
parent | a3099a3b4a394da360b5c1e7ae6dc985ae2f7f2f (diff) | |
download | mariadb-git-bb-10.6-MDEV-23752-2.tar.gz |
MDEV-23752 SHOW EXPLAIN FOR thd waits for sleepbb-10.6-MDEV-23752-2
my_apc awake thread after request.
-rw-r--r-- | sql/event_scheduler.cc | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/my_apc.cc | 8 | ||||
-rw-r--r-- | sql/my_apc.h | 3 | ||||
-rw-r--r-- | sql/rpl_parallel.cc | 2 | ||||
-rw-r--r-- | sql/service_wsrep.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 7 | ||||
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 10 | ||||
-rw-r--r-- | sql/sql_parse.cc | 7 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 3 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 7 | ||||
-rw-r--r-- | unittest/sql/my_apc-t.cc | 2 |
14 files changed, 44 insertions, 29 deletions
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 78802a5e109..86075485865 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -668,7 +668,7 @@ Event_scheduler::stop() sql_print_information("Event Scheduler: Killing the scheduler thread, " "thread id %lu", (ulong) scheduler_thd->thread_id); - scheduler_thd->awake(KILL_CONNECTION); + scheduler_thd->kill_me_pls(KILL_CONNECTION); /* thd could be 0x0, when shutting down */ sql_print_information("Event Scheduler: " @@ -676,7 +676,7 @@ Event_scheduler::stop() /* Wait only 2 seconds, as there is a small chance the thread missed the - above awake() call and we may have to do it again + above kill_me_pls() call and we may have to do it again */ struct timespec top_time; set_timespec(top_time, 2); diff --git a/sql/item_func.cc b/sql/item_func.cc index a0ef4020aae..3878f948c7f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4014,7 +4014,7 @@ int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) timeout= m_abs_timeout; error= mysql_cond_timedwait(cond, mutex, &timeout); - if (m_thd->check_killed()) + if (m_thd->check_killed(FALSE)) break; if (error == ETIMEDOUT || error == ETIME) { diff --git a/sql/my_apc.cc b/sql/my_apc.cc index e0feabab8e2..dce488aedb5 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -123,7 +123,7 @@ void init_show_explain_psi_keys(void) timeout occurred) */ -bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, +bool Apc_target::make_apc_call(THD *thd, THD *caller_thd, Apc_call *call, int timeout_sec, bool *timed_out) { bool res= TRUE; @@ -139,7 +139,11 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, NULL); enqueue_request(&apc_request); apc_request.what="enqueued by make_apc_call"; - + +#ifndef MY_APC_STANDALONE + thd->abort_current_cond_wait(false); +#endif //MY_APC_STANDALONE + struct timespec abstime; const int timeout= timeout_sec; set_timespec(abstime, timeout); diff --git a/sql/my_apc.h b/sql/my_apc.h index cc98e36bbe4..34f507dcd01 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -96,7 +96,8 @@ public: }; /* Make a call in the target thread (see function definition for details) */ - bool make_apc_call(THD *caller_thd, Apc_call *call, int timeout_sec, bool *timed_out); + bool make_apc_call(THD *thd, THD *caller_thd, Apc_call *call, + int timeout_sec, bool *timed_out); #ifndef DBUG_OFF int n_calls_processed; /* Number of calls served by this target */ diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 8be1964b762..b38db877b5a 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -2277,7 +2277,7 @@ rpl_parallel_entry::choose_thread(rpl_group_info *rgi, bool *did_enter_cond, /* We need to do the debug_sync before ENTER_COND(). Because debug_sync changes the thd->mysys_var->current_mutex, - and this can cause THD::awake to use the wrong mutex. + and this can cause THD::kill_me_pls to use the wrong mutex. */ DBUG_EXECUTE_IF("rpl_parallel_wait_queue_max", { diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index d0a96a85a60..16bfbee8023 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -230,7 +230,7 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, } victim_thd->wsrep_aborter= bf_thd->thread_id; - victim_thd->awake_no_mutex(KILL_QUERY); + victim_thd->kill_me_pls_no_mutex(KILL_QUERY); mysql_mutex_unlock(&victim_thd->LOCK_thd_data); } else { WSREP_DEBUG("wsrep_thd_bf_abort skipped awake"); diff --git a/sql/slave.cc b/sql/slave.cc index 1bd2802858c..8a80a93778d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -504,7 +504,7 @@ static void bg_rpl_load_gtid_slave_state(void *) static void bg_slave_kill(void *victim) { THD *to_kill= (THD *)victim; - to_kill->awake(KILL_CONNECTION); + to_kill->kill_me_pls(KILL_CONNECTION); mysql_mutex_lock(&to_kill->LOCK_wakeup_ready); to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; mysql_cond_broadcast(&to_kill->COND_wakeup_ready); @@ -1082,7 +1082,8 @@ terminate_slave_thread(THD *thd, int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm); DBUG_ASSERT(err != EINVAL); #endif - thd->awake_no_mutex(NOT_KILLED); + thd->kill_me_pls_no_mutex(NOT_KILLED); + mysql_mutex_unlock(&thd->LOCK_thd_kill); mysql_mutex_unlock(&thd->LOCK_thd_data); @@ -4970,7 +4971,7 @@ err: { /* Here we need to clear the active VIO before closing the - connection with the master. The reason is that THD::awake() + connection with the master. The reason is that THD::kill_me_pls() might be called from terminate_slave_thread() because somebody issued a STOP SLAVE. If that happends, the close_active_vio() can be called in the middle of closing the VIO associated with diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2fd07cef649..e44ac8e9ced 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -634,7 +634,7 @@ extern "C" void thd_kill_timeout(THD* thd) { thd->status_var.max_statement_time_exceeded++; /* Kill queries that can't cause data corruptions */ - thd->awake(KILL_TIMEOUT); + thd->kill_me_pls(KILL_TIMEOUT); } THD::THD(my_thread_id id, bool is_wsrep_applier) @@ -1887,9 +1887,9 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, NOT_KILLED is used to awake a thread for a slave */ -void THD::awake_no_mutex(killed_state state_to_set) +void THD::kill_me_pls_no_mutex(killed_state state_to_set) { - DBUG_ENTER("THD::awake"); + DBUG_ENTER("THD::kill_me_pls_no_mutex"); DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d", this, current_thd, (int) state_to_set)); THD_CHECK_SENTRY(this); @@ -1936,9 +1936,12 @@ void THD::awake_no_mutex(killed_state state_to_set) /* Broadcast a condition to kick the target if it is waiting on it. */ void THD::abort_current_cond_wait(bool force) { + DBUG_ENTER("THD::abort_current_cond_wait"); mysql_mutex_assert_owner(&LOCK_thd_kill); if (mysys_var) { + DBUG_PRINT("enter", ("this: %p current_thd: %p mysys_var", + this, current_thd)); mysql_mutex_lock(&mysys_var->mutex); if (!system_thread || force) // Don't abort locks mysys_var->abort=1; @@ -1998,6 +2001,7 @@ void THD::abort_current_cond_wait(bool force) } mysql_mutex_unlock(&mysys_var->mutex); } + DBUG_VOID_RETURN; } @@ -2141,7 +2145,7 @@ void THD::reset_killed() { /* Resetting killed has to be done under a mutex to ensure - its not done during an awake() call. + its not done during an kill_me_pls() call. */ DBUG_ENTER("reset_killed"); if (killed != NOT_KILLED) @@ -5038,7 +5042,7 @@ extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen) { size_t len= 0; /* InnoDB invokes this function while holding internal mutexes. - THD::awake() will hold LOCK_thd_data while invoking an InnoDB + THD::kill_me_pls() will hold LOCK_thd_data while invoking an InnoDB function that would acquire the internal mutex. Because this function is a non-essential part of information_schema view output, we will break the deadlock by avoiding a mutex wait here diff --git a/sql/sql_class.h b/sql/sql_class.h index 0de1d74ec69..2f19d54fd19 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3419,7 +3419,7 @@ public: /* If checking this in conjunction with a wait condition, please include a check after enter_cond() if you want to avoid a race - condition. For details see the implementation of awake(), + condition. For details see the implementation of kill_me_pls(), especially the "broadcast" part. */ killed_state volatile killed; @@ -3684,12 +3684,12 @@ public: } void close_active_vio(); #endif - void awake_no_mutex(killed_state state_to_set); - void awake(killed_state state_to_set) + void kill_me_pls_no_mutex(killed_state state_to_set); + void kill_me_pls(killed_state state_to_set) { mysql_mutex_lock(&LOCK_thd_kill); mysql_mutex_lock(&LOCK_thd_data); - awake_no_mutex(state_to_set); + kill_me_pls_no_mutex(state_to_set); mysql_mutex_unlock(&LOCK_thd_data); mysql_mutex_unlock(&LOCK_thd_kill); } @@ -3750,7 +3750,7 @@ public: Putting the mutex unlock in thd->exit_cond() ensures that mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is locked (if that would not be the case, you'll get a deadlock if someone - does a THD::awake() on you). + does a THD::kill_me_pls() on you). */ mysql_mutex_unlock(mysys_var->current_mutex); mysql_mutex_lock(&mysys_var->mutex); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ddfc49c6d52..499c9432260 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7833,7 +7833,7 @@ static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, /* Convert all ER_QUERY_INTERRUPTED errors to ER_LOCK_DEADLOCK if the transaction was BF aborted. This can happen when the - transaction is being BF aborted via thd->awake() while it is + transaction is being BF aborted via thd->kill_me_pls() while it is still executing. Note that this must be done before wsrep_after_statement() call @@ -9219,6 +9219,7 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ #endif /* WITH_WSREP */ { #ifdef WITH_WSREP + // following is historic name, mean kill_me_pls_no_mutex now DEBUG_SYNC(thd, "before_awake_no_mutex"); if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id) { @@ -9232,7 +9233,7 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ { WSREP_DEBUG("kill_one_thread %llu, victim: %llu wsrep_aborter %llu by signal %d", thd->thread_id, id, tmp->wsrep_aborter, kill_signal); - tmp->awake_no_mutex(kill_signal); + tmp->kill_me_pls_no_mutex(kill_signal); WSREP_DEBUG("victim: %llu taken care of", id); error= 0; } @@ -9322,7 +9323,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, THD *ptr= it2++; do { - ptr->awake_no_mutex(kill_signal); + ptr->kill_me_pls_no_mutex(kill_signal); /* Careful here: The list nodes are allocated on the memroots of the THDs to be awakened. diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ce270351dc3..2a39a3723dd 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3495,7 +3495,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) it will be slow because it will iterate through the list again. We just to do kill the thread ourselves. */ - arg.thd->awake_no_mutex(KILL_SLAVE_SAME_ID); + arg.thd->kill_me_pls_no_mutex(KILL_SLAVE_SAME_ID); mysql_mutex_unlock(&arg.thd->LOCK_thd_kill); mysql_mutex_unlock(&arg.thd->LOCK_thd_data); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b1cc696e9fe..b40fbc91869 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3133,7 +3133,8 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) explain_req.failed_to_produce= FALSE; /* Ok, we have a lock on target->LOCK_thd_kill, can call: */ - bres= tmp->apc_target.make_apc_call(thd, &explain_req, timeout_sec, &timed_out); + bres= tmp->apc_target.make_apc_call(tmp, thd, &explain_req, + timeout_sec, &timed_out); if (bres || explain_req.failed_to_produce) { diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 018b9aab3a7..581faf5434a 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2999,8 +2999,11 @@ static my_bool kill_all_threads(THD *thd, THD *caller_thd) { /* replicated transactions must be skipped */ WSREP_DEBUG("closing connection %lld", (longlong) thd->thread_id); - /* instead of wsrep_close_thread() we do now soft kill by THD::awake */ - thd->awake(KILL_CONNECTION); + /* + instead of wsrep_close_thread() we do now soft kill by + THD::kill_me_pls + */ + thd->kill_me_pls(KILL_CONNECTION); } } return 0; diff --git a/unittest/sql/my_apc-t.cc b/unittest/sql/my_apc-t.cc index c08e7281c92..9bf26463668 100644 --- a/unittest/sql/my_apc-t.cc +++ b/unittest/sql/my_apc-t.cc @@ -151,7 +151,7 @@ void *test_apc_requestor_thread(void *ptr) bool timed_out; mysql_mutex_lock(&target_mutex); - bool res= apc_target.make_apc_call(&my_thd, &apc_order, 60, &timed_out); + bool res= apc_target.make_apc_call(NULL, &my_thd, &apc_order, 60, &timed_out); if (res) { if (timed_out) |