summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-09-18 17:35:08 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2021-04-20 23:45:19 +0200
commitf867cca46b47f2ef9170ac9a7130bd3e493b8338 (patch)
treeaba4d04bf4cfdd0792503ebc3c337515823fffc3
parenta3099a3b4a394da360b5c1e7ae6dc985ae2f7f2f (diff)
downloadmariadb-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.cc4
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/my_apc.cc8
-rw-r--r--sql/my_apc.h3
-rw-r--r--sql/rpl_parallel.cc2
-rw-r--r--sql/service_wsrep.cc2
-rw-r--r--sql/slave.cc7
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_repl.cc2
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/wsrep_mysqld.cc7
-rw-r--r--unittest/sql/my_apc-t.cc2
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)