MDEV-16005 sporadic failures with galera tests MW-328B and MW-328C
These test can sporadically show mutex deadlock warnings between LOCK_wsrep_thd and LOCK_thd_data mutexes. This means that these mutexes can be locked in opposite order by different threads, and thus result in deadlock situation. To fix such issue, the locking policy of these mutexes should be revised and enforced to be uniform. However, a quick code review shows that the number of lock/unlock operations for these mutexes combined is between 100-200, and all these mutex invocations should be checked/fixed. On the other hand, it turns out that LOCK_wsrep_thd is used for protecting access to wsrep variables of THD (wsrep_conflict_state, wsrep_query_state), whereas LOCK_thd_data protects query, db and mysys_var variables in THD. Extending LOCK_thd_data to protect also wsrep variables looks like a viable solution, as there should not be a use case where separate threads need simultaneous access to wsrep variables and THD data variables. In this commit LOCK_wsrep_thd mutex is refactored to be replaced by LOCK_thd_data. By bluntly replacing LOCK_wsrep_thd by LOCK_thd_data, will result in double locking of LOCK_thd_data, and some adjustements have been performed to fix such situations.
This commit is contained in:
parent
82d4f08186
commit
2f0b8f3e02
@ -3898,10 +3898,10 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
|
||||
DBUG_RETURN(1);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state == NO_CONFLICT)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
#endif /* WITH_WSREP */
|
||||
if (slave_trans_retries)
|
||||
{
|
||||
@ -3978,7 +3978,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
else
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thread_safe_increment64(&rli->executed_entries);
|
||||
|
@ -1008,7 +1008,6 @@ THD::THD(bool is_wsrep_applier)
|
||||
*scramble= '\0';
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
mysql_mutex_init(key_LOCK_wsrep_thd, &LOCK_wsrep_thd, MY_MUTEX_INIT_FAST);
|
||||
wsrep_ws_handle.trx_id = WSREP_UNDEFINED_TRX_ID;
|
||||
wsrep_ws_handle.opaque = NULL;
|
||||
wsrep_retry_counter = 0;
|
||||
@ -1644,9 +1643,6 @@ THD::~THD()
|
||||
mysql_mutex_unlock(&LOCK_thd_data);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
mysql_mutex_lock(&LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&LOCK_wsrep_thd);
|
||||
mysql_mutex_destroy(&LOCK_wsrep_thd);
|
||||
if (wsrep_rgi) delete wsrep_rgi;
|
||||
#endif
|
||||
/* Close connection */
|
||||
|
@ -4105,7 +4105,6 @@ public:
|
||||
query_id_t wsrep_last_query_id;
|
||||
enum wsrep_query_state wsrep_query_state;
|
||||
enum wsrep_conflict_state wsrep_conflict_state;
|
||||
mysql_mutex_t LOCK_wsrep_thd;
|
||||
wsrep_trx_meta_t wsrep_trx_meta;
|
||||
uint32 wsrep_rand;
|
||||
Relay_log_info *wsrep_rli;
|
||||
|
@ -1335,9 +1335,9 @@ void do_handle_one_connection(THD *thd_arg)
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_query_state= QUERY_EXITING;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif
|
||||
end_thread:
|
||||
|
@ -4388,16 +4388,16 @@ bool select_create::send_eof()
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state != NO_CONFLICT)
|
||||
{
|
||||
WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s",
|
||||
thd->thread_id, thd->wsrep_conflict_state, thd->query());
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
abort_result_set();
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
@ -939,13 +939,13 @@ bool do_command(THD *thd)
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_query_state= QUERY_IDLE;
|
||||
if (thd->wsrep_conflict_state==MUST_ABORT)
|
||||
{
|
||||
wsrep_client_rollback(thd);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
@ -991,15 +991,15 @@ bool do_command(THD *thd)
|
||||
packet_length= my_net_read_packet(net, 1);
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
/* these THD's are aborted or are aborting during being idle */
|
||||
if (thd->wsrep_conflict_state == ABORTING)
|
||||
{
|
||||
while (thd->wsrep_conflict_state == ABORTING) {
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
my_sleep(1000);
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
}
|
||||
thd->store_globals();
|
||||
}
|
||||
@ -1009,7 +1009,7 @@ bool do_command(THD *thd)
|
||||
}
|
||||
|
||||
thd->wsrep_query_state= QUERY_EXEC;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
@ -1022,13 +1022,13 @@ bool do_command(THD *thd)
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT)
|
||||
{
|
||||
DBUG_PRINT("wsrep",("aborted for wsrep rollback: %lu", thd->real_id));
|
||||
wsrep_client_rollback(thd);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
@ -1256,7 +1256,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
thd->wsrep_PA_safe= true;
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_query_state= QUERY_EXEC;
|
||||
if (thd->wsrep_conflict_state== RETRY_AUTOCOMMIT)
|
||||
{
|
||||
@ -1272,14 +1272,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
{
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction");
|
||||
WSREP_DEBUG("Deadlock error for: %s", thd->query());
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
thd->reset_killed();
|
||||
thd->mysys_var->abort = 0;
|
||||
thd->wsrep_conflict_state = NO_CONFLICT;
|
||||
thd->wsrep_retry_counter = 0;
|
||||
goto dispatch_end;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
#if defined(ENABLED_PROFILING)
|
||||
@ -1934,10 +1934,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
DBUG_ASSERT((command != COM_QUIT && command != COM_STMT_CLOSE)
|
||||
|| thd->get_stmt_da()->is_disabled());
|
||||
/* wsrep BF abort in query exec phase */
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
do_end_of_statement= thd->wsrep_conflict_state != REPLAYING &&
|
||||
thd->wsrep_conflict_state != RETRY_AUTOCOMMIT;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
else
|
||||
do_end_of_statement= true;
|
||||
@ -7192,7 +7192,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
|
||||
if (WSREP(thd)) {
|
||||
/* wsrep BF abort in query exec phase */
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT) {
|
||||
wsrep_client_rollback(thd);
|
||||
|
||||
@ -7201,8 +7201,11 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
|
||||
if (thd->wsrep_conflict_state == MUST_REPLAY)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
if (thd->lex->explain)
|
||||
delete_explain_query(thd->lex);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
wsrep_replay_transaction(thd);
|
||||
}
|
||||
|
||||
@ -7242,13 +7245,13 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
if (thd->wsrep_conflict_state != REPLAYING)
|
||||
thd->wsrep_retry_counter= 0; // reset
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
thd->reset_killed();
|
||||
}
|
||||
else
|
||||
{
|
||||
set_if_smaller(thd->wsrep_retry_counter, 0); // reset; eventually ok
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8207,7 +8210,7 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
|
||||
|
||||
if (((thd->security_ctx->master_access & SUPER_ACL) ||
|
||||
thd->security_ctx->user_matches(tmp->security_ctx)) &&
|
||||
!wsrep_thd_is_BF(tmp, true))
|
||||
!wsrep_thd_is_BF(tmp, false))
|
||||
{
|
||||
tmp->awake(kill_signal);
|
||||
error=0;
|
||||
|
@ -3920,7 +3920,7 @@ reexecute:
|
||||
|
||||
if (WSREP_ON)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
switch (thd->wsrep_conflict_state)
|
||||
{
|
||||
case CERT_FAILURE:
|
||||
@ -3936,7 +3936,7 @@ reexecute:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
@ -3958,7 +3958,6 @@ reexecute:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
|
||||
{
|
||||
|
@ -98,11 +98,11 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd,
|
||||
DBUG_RETURN(WSREP_CB_FAILURE);
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_query_state= QUERY_EXEC;
|
||||
if (thd->wsrep_conflict_state!= REPLAYING)
|
||||
thd->wsrep_conflict_state= NO_CONFLICT;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
if (!buf_len) WSREP_DEBUG("empty rbr buffer to apply: %lld",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
@ -197,9 +197,9 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd,
|
||||
}
|
||||
|
||||
error:
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_query_state= QUERY_IDLE;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
assert(thd->wsrep_exec_mode== REPL_RECV);
|
||||
|
||||
|
@ -238,12 +238,12 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
switch (thd->wsrep_exec_mode)
|
||||
{
|
||||
case TOTAL_ORDER:
|
||||
case REPL_RECV:
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
WSREP_DEBUG("Avoiding wsrep rollback for failed DDL: %s", thd->query());
|
||||
DBUG_RETURN(0);
|
||||
default: break;
|
||||
@ -261,7 +261,7 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all)
|
||||
}
|
||||
wsrep_cleanup_transaction(thd);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
|
||||
(thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY))
|
||||
{
|
||||
@ -305,7 +305,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all)
|
||||
wsrep_cleanup_transaction(thd);
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -333,20 +333,20 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
|
||||
if (thd->wsrep_exec_mode == REPL_RECV) {
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT) {
|
||||
if (wsrep_debug)
|
||||
WSREP_INFO("WSREP: must abort for BF");
|
||||
DBUG_PRINT("wsrep", ("BF apply commit fail"));
|
||||
thd->wsrep_conflict_state = NO_CONFLICT;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
//
|
||||
// TODO: test all calls of the rollback.
|
||||
// rollback must happen automagically innobase_rollback(hton, thd, 1);
|
||||
//
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
if (thd->wsrep_exec_mode != LOCAL_STATE) DBUG_RETURN(WSREP_TRX_OK);
|
||||
@ -358,11 +358,11 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
|
||||
DBUG_PRINT("wsrep", ("replicating commit"));
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT) {
|
||||
DBUG_PRINT("wsrep", ("replicate commit fail"));
|
||||
thd->wsrep_conflict_state = ABORTED;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
if (wsrep_debug) {
|
||||
WSREP_INFO("innobase_commit, abort %s",
|
||||
(thd->query()) ? thd->query() : "void");
|
||||
@ -379,7 +379,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
{
|
||||
|
||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
mysql_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd_proc_info(thd, "wsrep waiting on replaying");
|
||||
@ -407,7 +407,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
thd->mysys_var->current_cond= 0;
|
||||
mysql_mutex_unlock(&thd->mysys_var->mutex);
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||
@ -415,14 +415,14 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT) {
|
||||
DBUG_PRINT("wsrep", ("replicate commit fail"));
|
||||
thd->wsrep_conflict_state = ABORTED;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
WSREP_DEBUG("innobase_commit abort after replaying wait %s",
|
||||
(thd->query()) ? thd->query() : "void");
|
||||
DBUG_RETURN(WSREP_TRX_CERT_FAIL);
|
||||
}
|
||||
|
||||
thd->wsrep_query_state = QUERY_COMMITTING;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
cache = get_trans_log(thd);
|
||||
rcode = 0;
|
||||
@ -487,10 +487,10 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
} else if (rcode == WSREP_BF_ABORT) {
|
||||
WSREP_DEBUG("thd %lu seqno %lld BF aborted by provider, will replay",
|
||||
thd->thread_id, (long long)thd->wsrep_trx_meta.gtid.seqno);
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_conflict_state = MUST_REPLAY;
|
||||
DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0);
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
||||
wsrep_replaying++;
|
||||
WSREP_DEBUG("replaying increased: %d, thd: %lu",
|
||||
@ -504,7 +504,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
DEBUG_SYNC(thd, "wsrep_after_replication");
|
||||
|
||||
@ -558,26 +558,26 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
WSREP_LOG_CONFLICT(NULL, thd, FALSE);
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
DBUG_RETURN(WSREP_TRX_CERT_FAIL);
|
||||
|
||||
case WSREP_SIZE_EXCEEDED:
|
||||
WSREP_ERROR("transaction size exceeded");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_RETURN(WSREP_TRX_SIZE_EXCEEDED);
|
||||
case WSREP_CONN_FAIL:
|
||||
WSREP_ERROR("connection failure");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
default:
|
||||
WSREP_ERROR("unknown connection failure");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
}
|
||||
|
||||
thd->wsrep_query_state= QUERY_EXEC;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
DBUG_RETURN(WSREP_TRX_OK);
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ ulong wsrep_running_threads = 0; // # of currently running wsrep threads
|
||||
ulong my_bind_addr;
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd,
|
||||
PSI_mutex_key key_LOCK_wsrep_rollback,
|
||||
key_LOCK_wsrep_replaying, key_LOCK_wsrep_ready, key_LOCK_wsrep_sst,
|
||||
key_LOCK_wsrep_sst_thread, key_LOCK_wsrep_sst_init,
|
||||
key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync,
|
||||
@ -148,7 +148,6 @@ static PSI_mutex_info wsrep_mutexes[]=
|
||||
{ &key_LOCK_wsrep_sst_init, "LOCK_wsrep_sst_init", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_wsrep_sst, "LOCK_wsrep_sst", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_wsrep_rollback, "LOCK_wsrep_rollback", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_wsrep_thd, "THD::LOCK_wsrep_thd", 0},
|
||||
{ &key_LOCK_wsrep_replaying, "LOCK_wsrep_replaying", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_wsrep_slave_threads, "LOCK_wsrep_slave_threads", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL},
|
||||
@ -1659,7 +1658,7 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
|
||||
if (thd->wsrep_exec_mode == REPL_RECV)
|
||||
return 0;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT)
|
||||
{
|
||||
@ -1667,10 +1666,10 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
|
||||
thd->thread_id,
|
||||
(thd->db ? thd->db : "(null)"),
|
||||
thd->query());
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
return WSREP_TRX_FAIL;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
DBUG_ASSERT(thd->wsrep_exec_mode == LOCAL_STATE);
|
||||
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno == WSREP_SEQNO_UNDEFINED);
|
||||
@ -1786,23 +1785,23 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
const char* schema= key->db_name();
|
||||
int schema_len= key->db_name_length();
|
||||
|
||||
mysql_mutex_lock(&request_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&request_thd->LOCK_thd_data);
|
||||
if (request_thd->wsrep_exec_mode == TOTAL_ORDER ||
|
||||
request_thd->wsrep_exec_mode == REPL_RECV)
|
||||
{
|
||||
mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&request_thd->LOCK_thd_data);
|
||||
WSREP_MDL_LOG(DEBUG, "MDL conflict ", schema, schema_len,
|
||||
request_thd, granted_thd);
|
||||
ticket->wsrep_report(wsrep_debug);
|
||||
|
||||
mysql_mutex_lock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&granted_thd->LOCK_thd_data);
|
||||
if (granted_thd->wsrep_exec_mode == TOTAL_ORDER ||
|
||||
granted_thd->wsrep_exec_mode == REPL_RECV)
|
||||
{
|
||||
WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", schema, schema_len,
|
||||
request_thd, granted_thd);
|
||||
ticket->wsrep_report(true);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (granted_thd->lex->sql_command == SQLCOM_FLUSH ||
|
||||
@ -1810,14 +1809,14 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
{
|
||||
WSREP_DEBUG("BF thread waiting for FLUSH");
|
||||
ticket->wsrep_report(wsrep_debug);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
|
||||
{
|
||||
WSREP_DEBUG("DROP caused BF abort");
|
||||
ticket->wsrep_report(wsrep_debug);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
|
||||
ret = FALSE;
|
||||
}
|
||||
@ -1825,7 +1824,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
{
|
||||
WSREP_DEBUG("MDL granted, but committing thd abort scheduled");
|
||||
ticket->wsrep_report(wsrep_debug);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
|
||||
ret = FALSE;
|
||||
}
|
||||
@ -1834,14 +1833,14 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", schema, schema_len,
|
||||
request_thd, granted_thd);
|
||||
ticket->wsrep_report(wsrep_debug);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&request_thd->LOCK_thd_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2006,9 +2005,9 @@ static inline bool is_replaying_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2018,9 +2017,9 @@ static inline bool is_committing_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2403,13 +2402,13 @@ wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd)
|
||||
|
||||
void wsrep_thd_LOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
void wsrep_thd_UNLOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,8 +272,6 @@ extern my_bool wsrep_preordered_opt;
|
||||
extern handlerton *wsrep_hton;
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
extern PSI_mutex_key key_LOCK_wsrep_thd;
|
||||
extern PSI_cond_key key_COND_wsrep_thd;
|
||||
extern PSI_mutex_key key_LOCK_wsrep_ready;
|
||||
extern PSI_mutex_key key_COND_wsrep_ready;
|
||||
extern PSI_mutex_key key_LOCK_wsrep_sst;
|
||||
|
@ -47,7 +47,7 @@ int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must have (&thd->LOCK_wsrep_thd) */
|
||||
/* must have (&thd->LOCK_thd_data) */
|
||||
void wsrep_client_rollback(THD *thd)
|
||||
{
|
||||
WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s",
|
||||
@ -56,7 +56,7 @@ void wsrep_client_rollback(THD *thd)
|
||||
WSREP_ATOMIC_ADD_LONG(&wsrep_bf_aborts_counter, 1);
|
||||
|
||||
thd->wsrep_conflict_state= ABORTING;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
trans_rollback(thd);
|
||||
|
||||
if (thd->locked_tables_mode && thd->lock)
|
||||
@ -83,7 +83,7 @@ void wsrep_client_rollback(THD *thd)
|
||||
WSREP_DEBUG("clearing binlog table map for BF abort (%ld)", thd->thread_id);
|
||||
thd->clear_binlog_table_maps();
|
||||
}
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->wsrep_conflict_state= ABORTED;
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ void wsrep_replay_transaction(THD *thd)
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
|
||||
thd->wsrep_conflict_state= REPLAYING;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
thd->reset_for_next_command();
|
||||
thd->reset_killed();
|
||||
@ -269,7 +269,7 @@ void wsrep_replay_transaction(THD *thd)
|
||||
if (thd->wsrep_conflict_state!= REPLAYING)
|
||||
WSREP_WARN("lost replaying mode: %d", thd->wsrep_conflict_state );
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
switch (rcode)
|
||||
{
|
||||
@ -326,7 +326,7 @@ void wsrep_replay_transaction(THD *thd)
|
||||
/* we're now in inconsistent state, must abort */
|
||||
|
||||
/* http://bazaar.launchpad.net/~codership/codership-mysql/5.6/revision/3962#sql/wsrep_thd.cc */
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
unireg_abort(1);
|
||||
break;
|
||||
@ -496,29 +496,29 @@ static void wsrep_rollback_process(THD *thd)
|
||||
*/
|
||||
mysql_mutex_unlock(&LOCK_wsrep_rollback);
|
||||
|
||||
mysql_mutex_lock(&aborting->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&aborting->LOCK_thd_data);
|
||||
if (aborting->wsrep_conflict_state== ABORTED)
|
||||
{
|
||||
WSREP_DEBUG("WSREP, thd already aborted: %llu state: %d",
|
||||
(long long)aborting->real_id,
|
||||
aborting->wsrep_conflict_state);
|
||||
|
||||
mysql_mutex_unlock(&aborting->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&aborting->LOCK_thd_data);
|
||||
mysql_mutex_lock(&LOCK_wsrep_rollback);
|
||||
continue;
|
||||
}
|
||||
aborting->wsrep_conflict_state= ABORTING;
|
||||
|
||||
mysql_mutex_unlock(&aborting->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&aborting->LOCK_thd_data);
|
||||
|
||||
set_current_thd(aborting);
|
||||
aborting->store_globals();
|
||||
|
||||
mysql_mutex_lock(&aborting->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&aborting->LOCK_thd_data);
|
||||
wsrep_client_rollback(aborting);
|
||||
WSREP_DEBUG("WSREP rollbacker aborted thd: (%lu %llu)",
|
||||
aborting->thread_id, (long long)aborting->real_id);
|
||||
mysql_mutex_unlock(&aborting->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&aborting->LOCK_thd_data);
|
||||
|
||||
set_current_thd(thd);
|
||||
thd->store_globals();
|
||||
@ -558,10 +558,10 @@ enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd, my_bool sync)
|
||||
enum wsrep_conflict_state state = NO_CONFLICT;
|
||||
if (thd)
|
||||
{
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
state = thd->wsrep_conflict_state;
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -585,12 +585,12 @@ my_bool wsrep_thd_is_BF(THD *thd, my_bool sync)
|
||||
if (wsrep_thd_is_wsrep(thd))
|
||||
{
|
||||
if (sync)
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
status = ((thd->wsrep_exec_mode == REPL_RECV) ||
|
||||
(thd->wsrep_exec_mode == TOTAL_ORDER));
|
||||
if (sync)
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@ -603,12 +603,12 @@ my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync)
|
||||
if (thd_ptr)
|
||||
{
|
||||
THD* thd = (THD*)thd_ptr;
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
status = ((thd->wsrep_exec_mode == REPL_RECV) ||
|
||||
(thd->wsrep_exec_mode == TOTAL_ORDER) ||
|
||||
(thd->wsrep_exec_mode == LOCAL_COMMIT));
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -620,10 +620,10 @@ my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync)
|
||||
if (thd_ptr)
|
||||
{
|
||||
THD* thd = (THD*)thd_ptr;
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
status = (thd->wsrep_exec_mode == LOCAL_STATE);
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -4899,7 +4899,6 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
|
||||
{
|
||||
DBUG_ENTER("innobase_kill_query");
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_thd_LOCK(thd);
|
||||
if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) {
|
||||
/* if victim has been signaled by BF thread and/or aborting
|
||||
is already progressing, following query aborting is not necessary
|
||||
@ -4907,10 +4906,8 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
|
||||
Also, BF thread should own trx mutex for the victim, which would
|
||||
conflict with trx_mutex_enter() below
|
||||
*/
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (trx_t* trx = thd_to_trx(thd)) {
|
||||
|
@ -5496,7 +5496,6 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
|
||||
DBUG_ENTER("innobase_kill_query");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_thd_LOCK(thd);
|
||||
if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) {
|
||||
/* if victim has been signaled by BF thread and/or aborting
|
||||
is already progressing, following query aborting is not necessary
|
||||
@ -5504,10 +5503,8 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
|
||||
Also, BF thread should own trx mutex for the victim, which would
|
||||
conflict with trx_mutex_enter() below
|
||||
*/
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
#endif /* WITH_WSREP */
|
||||
if (trx_t* trx = thd_to_trx(thd)) {
|
||||
ut_ad(trx->mysql_thd == thd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user