The LOCK_global_system_variables must not be held when taking mutexes
such as LOCK_commit_ordered and LOCK_log, as this causes inconsistent
mutex locking order that can theoretically cause the server to
deadlock.

To avoid this, temporarily release LOCK_global_system_variables in two
system variable update functions, like it is done in many other
places.

Enforce the correct locking order at server startup, to more easily
catch (in debug builds) any remaining wrong orders that may be hidden
elsewhere in the code.

Signed-off-by: Kristian Nielsen <kniel...@knielsen-hq.org>
---
 sql/log.cc      | 8 ++++++++
 sql/sys_vars.cc | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/sql/log.cc b/sql/log.cc
index 512be2e2a6d..70fe33f9272 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -3595,6 +3595,12 @@ void MYSQL_BIN_LOG::init_pthread_objects()
 
   mysql_mutex_init(m_key_LOCK_binlog_end_pos, &LOCK_binlog_end_pos,
                    MY_MUTEX_INIT_SLOW);
+
+  /* Fix correct mutex order to catch violations quicker (MDEV-35197). */
+  mysql_mutex_lock(&LOCK_log);
+  mysql_mutex_lock(&LOCK_global_system_variables);
+  mysql_mutex_unlock(&LOCK_global_system_variables);
+  mysql_mutex_unlock(&LOCK_log);
 }
 
 
@@ -11753,6 +11759,7 @@ binlog_checksum_update(MYSQL_THD thd, struct 
st_mysql_sys_var *var,
   bool check_purge= false;
   ulong UNINIT_VAR(prev_binlog_id);
 
+  mysql_mutex_unlock(&LOCK_global_system_variables);
   mysql_mutex_lock(mysql_bin_log.get_log_lock());
   if(mysql_bin_log.is_open())
   {
@@ -11771,6 +11778,7 @@ binlog_checksum_update(MYSQL_THD thd, struct 
st_mysql_sys_var *var,
   mysql_mutex_unlock(mysql_bin_log.get_log_lock());
   if (check_purge)
     mysql_bin_log.checkpoint_and_purge(prev_binlog_id);
+  mysql_mutex_lock(&LOCK_global_system_variables);
 }
 
 
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index cb35386f883..115bbdf499b 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1660,7 +1660,9 @@ Sys_max_binlog_stmt_cache_size(
 
 static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type)
 {
+  mysql_mutex_unlock(&LOCK_global_system_variables);
   mysql_bin_log.set_max_size(max_binlog_size);
+  mysql_mutex_lock(&LOCK_global_system_variables);
   return false;
 }
 static Sys_var_on_access_global<Sys_var_ulong,
-- 
2.39.2

_______________________________________________
commits mailing list -- commits@lists.mariadb.org
To unsubscribe send an email to commits-le...@lists.mariadb.org

Reply via email to