Commit ee5fa178 authored by Julius Goryavsky's avatar Julius Goryavsky

galera: handling mutexes carefully when aborting thread or transaction

Fixed bugs related to repeated release of mutexes
when handling MDL locks - which led to the crash
of various tests in some runs.
parent 9f0b1066
...@@ -8115,6 +8115,10 @@ Compare_keys handler::compare_key_parts(const Field &old_field, ...@@ -8115,6 +8115,10 @@ Compare_keys handler::compare_key_parts(const Field &old_field,
int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal) int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
{ {
DBUG_ENTER("ha_abort_transaction"); DBUG_ENTER("ha_abort_transaction");
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_kill);
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
if (!WSREP(bf_thd) && if (!WSREP(bf_thd) &&
!(bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU && !(bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU &&
wsrep_thd_is_toi(bf_thd))) { wsrep_thd_is_toi(bf_thd))) {
...@@ -8135,6 +8139,9 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal) ...@@ -8135,6 +8139,9 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill); mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
} }
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_kill);
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
......
...@@ -3130,6 +3130,10 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3130,6 +3130,10 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
THD::LOCK_thd_data to protect victim from concurrent usage THD::LOCK_thd_data to protect victim from concurrent usage
and THD::LOCK_thd_kill to protect from disconnect or delete. and THD::LOCK_thd_kill to protect from disconnect or delete.
Note that all calls to wsrep_abort_thd() and ha_abort_transaction()
unlock LOCK_thd_kill for granted_thd, so granted_thd must not be
accessed after any of those calls. Moreover all other if branches
must release those locks.
*/ */
mysql_mutex_lock(&granted_thd->LOCK_thd_kill); mysql_mutex_lock(&granted_thd->LOCK_thd_kill);
mysql_mutex_lock(&granted_thd->LOCK_thd_data); mysql_mutex_lock(&granted_thd->LOCK_thd_data);
...@@ -3138,6 +3142,8 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3138,6 +3142,8 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
{ {
DBUG_ASSERT(granted_thd->wsrep_aborter == request_thd->thread_id); DBUG_ASSERT(granted_thd->wsrep_aborter == request_thd->thread_id);
WSREP_DEBUG("BF thread waiting for a victim to release locks"); WSREP_DEBUG("BF thread waiting for a victim to release locks");
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
mysql_mutex_unlock(&granted_thd->LOCK_thd_kill);
} }
else if (wsrep_thd_is_toi(granted_thd) || else if (wsrep_thd_is_toi(granted_thd) ||
wsrep_thd_is_applying(granted_thd)) wsrep_thd_is_applying(granted_thd))
...@@ -3146,6 +3152,8 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3146,6 +3152,8 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
{ {
WSREP_DEBUG("BF thread waiting for SR in aborting state"); WSREP_DEBUG("BF thread waiting for SR in aborting state");
ticket->wsrep_report(wsrep_debug); ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
mysql_mutex_unlock(&granted_thd->LOCK_thd_kill);
} }
else if (wsrep_thd_is_SR(granted_thd) && !wsrep_thd_is_SR(request_thd)) else if (wsrep_thd_is_SR(granted_thd) && !wsrep_thd_is_SR(request_thd))
{ {
...@@ -3175,6 +3183,11 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3175,6 +3183,11 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
{ {
wsrep_abort_thd(request_thd, granted_thd, 1); wsrep_abort_thd(request_thd, granted_thd, 1);
} }
else
{
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
mysql_mutex_unlock(&granted_thd->LOCK_thd_kill);
}
} }
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE) else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
{ {
...@@ -3214,14 +3227,13 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3214,14 +3227,13 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
} }
} }
} }
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
mysql_mutex_unlock(&granted_thd->LOCK_thd_kill);
DEBUG_SYNC(request_thd, "after_wsrep_thd_abort");
} }
else else
{ {
mysql_mutex_unlock(&request_thd->LOCK_thd_data); mysql_mutex_unlock(&request_thd->LOCK_thd_data);
} }
DEBUG_SYNC(request_thd, "after_wsrep_thd_abort");
} }
/**/ /**/
...@@ -3237,8 +3249,13 @@ static bool abort_replicated(THD *thd) ...@@ -3237,8 +3249,13 @@ static bool abort_replicated(THD *thd)
wsrep_abort_thd(thd, thd, TRUE); wsrep_abort_thd(thd, thd, TRUE);
ret_code= true; ret_code= true;
} }
mysql_mutex_unlock(&thd->LOCK_thd_data); else
mysql_mutex_unlock(&thd->LOCK_thd_kill); {
/* wsrep_abort_thd() above releases LOCK_thd_data and LOCK_thd_kill, so
must do it here too. */
mysql_mutex_unlock(&thd->LOCK_thd_data);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
}
return ret_code; return ret_code;
} }
......
...@@ -383,6 +383,8 @@ void wsrep_abort_thd(THD *bf_thd, ...@@ -383,6 +383,8 @@ void wsrep_abort_thd(THD *bf_thd,
} }
else else
{ {
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
WSREP_DEBUG("wsrep_abort_thd not effective: bf %llu victim %llu " WSREP_DEBUG("wsrep_abort_thd not effective: bf %llu victim %llu "
"wsrep %d wsrep_on %d RSU %d TOI %d aborting %d", "wsrep %d wsrep_on %d RSU %d TOI %d aborting %d",
(long long)bf_thd->real_id, (long long)victim_thd->real_id, (long long)bf_thd->real_id, (long long)victim_thd->real_id,
...@@ -392,6 +394,9 @@ void wsrep_abort_thd(THD *bf_thd, ...@@ -392,6 +394,9 @@ void wsrep_abort_thd(THD *bf_thd,
wsrep_thd_is_aborting(victim_thd)); wsrep_thd_is_aborting(victim_thd));
} }
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_kill);
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
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