Commit e1e5ce0d authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-5345 - Deadlock between mysql_change_user(), SHOW VARIABLES and

            INSTALL PLUGIN

There was mixed lock order between LOCK_plugin, LOCK_global_system_variables
and LOCK_system_variables_hash. This patch ensures that write-lock on
LOCK_system_variables_hash doesn't intersect with LOCK_plugin.

Fixed by moving initialization/deinitialization of plugin options from
plugin_add()/plugin_del() to plugin_initialize()/plugin_deinitalize().
So that plugin options are handled without protection of LOCK_plugin.
parent 94868914
#
# MDEV-5345 - Deadlock between mysql_change_user(), SHOW VARIABLES and
# INSTALL PLUGIN
#
CREATE PROCEDURE p_install(x INT)
BEGIN
DECLARE CONTINUE HANDLER FOR 1126 BEGIN END;
WHILE x DO
SET x= x - 1;
INSTALL PLUGIN no_such_plugin SONAME 'no_such_object';
END WHILE;
END|
CREATE PROCEDURE p_show_vars(x INT)
WHILE x DO
SET x= x - 1;
SHOW VARIABLES;
END WHILE|
CALL p_install(100);
CALL p_show_vars(100);
USE test;
DROP PROCEDURE p_install;
DROP PROCEDURE p_show_vars;
--echo #
--echo # MDEV-5345 - Deadlock between mysql_change_user(), SHOW VARIABLES and
--echo # INSTALL PLUGIN
--echo #
# Prepare test
delimiter |;
CREATE PROCEDURE p_install(x INT)
BEGIN
DECLARE CONTINUE HANDLER FOR 1126 BEGIN END;
WHILE x DO
SET x= x - 1;
INSTALL PLUGIN no_such_plugin SONAME 'no_such_object';
END WHILE;
END|
CREATE PROCEDURE p_show_vars(x INT)
WHILE x DO
SET x= x - 1;
SHOW VARIABLES;
END WHILE|
delimiter ;|
connect(con1, localhost, root,,);
connect(con2, localhost, root,,);
# Start test
connection con1;
--send CALL p_install(100)
connection con2;
--send CALL p_show_vars(100)
connection default;
disable_result_log;
let $i= 100;
while ($i)
{
change_user;
dec $i;
}
# Cleanup
connection con1;
reap;
connection con2;
reap;
connection default;
enable_result_log;
disconnect con1;
disconnect con2;
USE test;
DROP PROCEDURE p_install;
DROP PROCEDURE p_show_vars;
...@@ -441,10 +441,10 @@ int mysql_del_sys_var_chain(sys_var *first) ...@@ -441,10 +441,10 @@ int mysql_del_sys_var_chain(sys_var *first)
{ {
int result= 0; int result= 0;
/* A write lock should be held on LOCK_system_variables_hash */ mysql_rwlock_wrlock(&LOCK_system_variables_hash);
for (sys_var *var= first; var; var= var->next) for (sys_var *var= first; var; var= var->next)
result|= my_hash_delete(&system_variable_hash, (uchar*) var); result|= my_hash_delete(&system_variable_hash, (uchar*) var);
mysql_rwlock_unlock(&LOCK_system_variables_hash);
return result; return result;
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment