diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2014-09-25 10:43:11 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2014-09-25 10:43:11 +0400 |
commit | b737d902a8f4b42e8e515d112aeeb6ebe5ffa91a (patch) | |
tree | fd00c194d403d29311b8d22de3556df636bed98e /sql | |
parent | d1e46a50bc59dd42e5aae55e4e20f2548c5cf3ba (diff) | |
download | mariadb-git-b737d902a8f4b42e8e515d112aeeb6ebe5ffa91a.tar.gz |
MDEV-6774 - Deadlock between SELECT, DROP TABLE, SHOW STATUS and
SET @@global.log_output
Deadlock chain:
rdlock(LOCK_logger) -> lock(LOCK_open) SELECT 1
lock(LOCK_open) -> lock(LOCK_status) DROP TABLE t1
lock(LOCK_status) -> lock(LOCK_g_s_v) SHOW STATUS
lock(LOCK_g_s_) -> wrlock(LOCK_logger) SET @@global.log_output=DEFAULT
Fixed by removing relationship between LOCK_status and
LOCK_global_system_variables during SHOW STATUS: we don't really need
LOCK_global_system_variables when accessing status vars.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/event_scheduler.cc | 9 | ||||
-rw-r--r-- | sql/sql_show.cc | 6 |
2 files changed, 4 insertions, 11 deletions
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index f8d177ac0c1..beb3c864662 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -355,14 +355,7 @@ Event_scheduler::Event_scheduler(Event_queue *queue_arg) mysql_mutex_init(key_event_scheduler_LOCK_scheduler_state, &LOCK_scheduler_state, MY_MUTEX_INIT_FAST); mysql_cond_init(key_event_scheduler_COND_state, &COND_state, NULL); - -#ifdef SAFE_MUTEX - /* Ensure right mutex order */ - mysql_mutex_lock(&LOCK_scheduler_state); - mysql_mutex_lock(&LOCK_global_system_variables); - mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_unlock(&LOCK_scheduler_state); -#endif + mysql_mutex_record_order(&LOCK_scheduler_state, &LOCK_global_system_variables); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fe1d1f38888..f6ed5702ce5 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2648,12 +2648,11 @@ static bool show_status_array(THD *thd, const char *wild, char *value=var->value; const char *pos, *end; // We assign a lot of const's - mysql_mutex_lock(&LOCK_global_system_variables); - if (show_type == SHOW_SYS) { sys_var *var= ((sys_var *) value); show_type= var->show_type(); + mysql_mutex_lock(&LOCK_global_system_variables); value= (char*) var->value_ptr(thd, value_type, &null_lex_str); charset= var->charset(thd); } @@ -2754,7 +2753,8 @@ static bool show_status_array(THD *thd, const char *wild, thd->count_cuted_fields= CHECK_FIELD_IGNORE; table->field[1]->set_notnull(); - mysql_mutex_unlock(&LOCK_global_system_variables); + if (var->type == SHOW_SYS) + mysql_mutex_unlock(&LOCK_global_system_variables); if (schema_table_store_record(thd, table)) { |