summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2023-03-13 22:51:23 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-03-23 13:43:48 +0300
commitd8c908bb3996269b3b2cdb20bacac66ec1c3a2fa (patch)
treee76e2d78c1c11f6fe13e83590f91f8c35d6b5689
parent295689ccbe2bd06cd883abebfa27e36c36d3f770 (diff)
downloadmariadb-git-d8c908bb3996269b3b2cdb20bacac66ec1c3a2fa.tar.gz
APC: fix LOCK_global_system_variables contention
-rw-r--r--sql/sys_vars.cc8
-rw-r--r--sql/sys_vars.inl18
-rw-r--r--storage/perfschema/pfs_variable.cc7
3 files changed, 21 insertions, 12 deletions
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index cd0fb5967dc..1a34d6b295c 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5535,18 +5535,20 @@ Sys_slave_net_timeout(
*/
ulonglong Sys_var_multi_source_ulonglong::
-get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const
+get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset, bool lock) const
{
Master_info *mi;
ulonglong res= 0; // Default value
- mysql_mutex_unlock(&LOCK_global_system_variables);
+ if (lock)
+ mysql_mutex_unlock(&LOCK_global_system_variables);
if ((mi= get_master_info(&thd->variables.default_master_connection,
Sql_condition::WARN_LEVEL_WARN)))
{
res= *((ulonglong*) (((uchar*) mi) + master_info_offset));
mi->release();
}
- mysql_mutex_lock(&LOCK_global_system_variables);
+ if (lock)
+ mysql_mutex_lock(&LOCK_global_system_variables);
return res;
}
diff --git a/sql/sys_vars.inl b/sql/sys_vars.inl
index 97e3a28b67e..b5e29d69fd5 100644
--- a/sql/sys_vars.inl
+++ b/sql/sys_vars.inl
@@ -2378,6 +2378,14 @@ class Sys_var_multi_source_ulonglong :public Sys_var_ulonglong
{
ptrdiff_t master_info_offset;
on_multi_source_update_function update_multi_source_variable_func;
+ const uchar *get_value_ptr(THD *thd, bool lock) const
+ {
+ ulonglong *tmp, res;
+ tmp= (ulonglong*) (((uchar*)&(thd->variables)) + offset);
+ res= get_master_info_ulonglong_value(thd, master_info_offset, lock);
+ *tmp= res;
+ return (uchar*) tmp;
+ }
public:
Sys_var_multi_source_ulonglong(const char *name_arg,
const char *comment, int flag_args,
@@ -2407,17 +2415,13 @@ public:
}
const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
- ulonglong *tmp, res;
- tmp= (ulonglong*) (((uchar*)&(thd->variables)) + offset);
- res= get_master_info_ulonglong_value(thd, master_info_offset);
- *tmp= res;
- return (uchar*) tmp;
+ return get_value_ptr(thd, false);
}
const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
{
- return session_value_ptr(thd, base);
+ return get_value_ptr(thd, true);
}
- ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const;
+ ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset, bool lock) const;
bool update_variable(THD *thd, Master_info *mi)
{
return update_multi_source_variable_func(this, thd, mi);
diff --git a/storage/perfschema/pfs_variable.cc b/storage/perfschema/pfs_variable.cc
index 4dc193b3a1d..698ff1eca6c 100644
--- a/storage/perfschema/pfs_variable.cc
+++ b/storage/perfschema/pfs_variable.cc
@@ -562,13 +562,16 @@ void System_variable::init(THD *target_thd, const SHOW_VAR *show_var,
/* Get the value of the system variable. */
String buf(m_value_str, sizeof(m_value_str) - 1, system_charset_info);
- mysql_mutex_lock(&LOCK_global_system_variables);
+ if (query_scope == OPT_GLOBAL || system_var->scope() == sys_var::GLOBAL)
+ mysql_mutex_lock(&LOCK_global_system_variables);
if (!system_var->val_str_nolock(&buf, target_thd,
system_var->value_ptr(target_thd,
query_scope,
&null_clex_str)))
buf.length(0);
- mysql_mutex_unlock(&LOCK_global_system_variables);
+
+ if (query_scope == OPT_GLOBAL || system_var->scope() == sys_var::GLOBAL)
+ mysql_mutex_unlock(&LOCK_global_system_variables);
m_value_length= MY_MIN(buf.length(), SHOW_VAR_FUNC_BUFF_SIZE);