diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2018-01-27 17:46:31 +0000 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2018-01-29 07:33:52 +0000 |
commit | 7cdf759c86a3b80bf215fcc6baab87b930425170 (patch) | |
tree | fa541cde13156bd523bb9884ed5f163905aa519d /sql/set_var.cc | |
parent | 1da063a45bc43ac2c5761d8e091e55b8cac123cf (diff) | |
download | mariadb-git-7cdf759c86a3b80bf215fcc6baab87b930425170.tar.gz |
MDEV-14485 Server hangs on startup in THD::init
Solve 3 way deadlock between plugin_initialiaze(), THD::init() and
mysql_sys_var_char().
The deadlock exists because of the lock order inversion between
LOCK_global_system_variables mutex and LOCK_system_variables_hash
read-write lock-
In this case, it is enough to change LOCK_system_variables_hash to prefer
reads to fix the deadlock, i.e change it to mysql_prlock_t
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r-- | sql/set_var.cc | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc index 07395e3e708..e96e636e3d3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -595,10 +595,10 @@ int mysql_del_sys_var_chain(sys_var *first) { int result= 0; - mysql_rwlock_wrlock(&LOCK_system_variables_hash); + mysql_prlock_wrlock(&LOCK_system_variables_hash); for (sys_var *var= first; var; var= var->next) result|= my_hash_delete(&system_variable_hash, (uchar*) var); - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); return result; } @@ -1067,7 +1067,7 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond) cond= make_cond_for_info_schema(thd, cond, tables); thd->count_cuted_fields= CHECK_FIELD_WARN; - mysql_rwlock_rdlock(&LOCK_system_variables_hash); + mysql_prlock_rdlock(&LOCK_system_variables_hash); for (uint i= 0; i < system_variable_hash.records; i++) { @@ -1229,7 +1229,7 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond) } res= 0; end: - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); thd->count_cuted_fields= save_count_cuted_fields; return res; } |