Skip to content

Commit f3db9bf

Browse files
Christopher Powersbjornmu
authored andcommitted
Bug#22225549 MYSQL_CHANGE_USER/MYSQL_RESET_CONNECTION+SET INNODB_*:LOGIN NOT POSSIBLE
Update of plugin-defined session variable triggers resync with global variables and deadlocks on THD::LOCK_thd_sysvar in alloc_and_copy_thd_dynamic_variables(). In alloc_and_copy_thd_dynamic_variables(), removed LOCK_thd_sysvar and extended the coverage of LOCK_global_system_variables (cherry picked from commit d02eed42ce96d52c28a007105bd056003bbff315)
1 parent 91d8ae2 commit f3db9bf

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

mysql-test/suite/perfschema/r/show_plugin.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,33 @@ COUNT(*)
841841
# Connect con2 - reap
842842
connection con2;
843843

844+
================================================================================
845+
TEST 5 - BUG#22225549 MYSQL_CHANGE_USER/MYSQL_RESET_CONNECTION + SET INNODB...
846+
Update to plugin-defined session variable triggers resync with global
847+
variables and deadlocks on THD::LOCK_thd_sysvar.
848+
================================================================================
849+
SELECT @@global.show_compatibility_56;
850+
@@global.show_compatibility_56
851+
0
852+
select @@session.innodb_strict_mode;
853+
@@session.innodb_strict_mode
854+
1
855+
select user(), current_user();
856+
user() current_user()
857+
root@localhost root@localhost
858+
change_user root
859+
#
860+
# Trigger a resync of session variables with global variables.
861+
#
862+
set @@session.innodb_strict_mode=off;
863+
864+
# Restore
865+
866+
set @@session.innodb_strict_mode=1;
867+
select @@session.innodb_strict_mode;
868+
@@session.innodb_strict_mode
869+
1
870+
844871
================================================================================
845872
CLEAN UP
846873
================================================================================

mysql-test/suite/perfschema/t/show_plugin.test

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,37 @@ connection con2;
404404
--reap
405405
--enable_warnings
406406

407+
--echo
408+
--echo ================================================================================
409+
--echo TEST 5 - BUG#22225549 MYSQL_CHANGE_USER/MYSQL_RESET_CONNECTION + SET INNODB...
410+
--echo Update to plugin-defined session variable triggers resync with global
411+
--echo variables and deadlocks on THD::LOCK_thd_sysvar.
412+
--echo ================================================================================
413+
#
414+
# THD:LOCK_thd_sysvar is only used when SHOW_COMPATIBILITY_56 = OFF
415+
#
416+
SELECT @@global.show_compatibility_56;
417+
#
418+
# The deadlock occurs when plugin-defined session variables are resynced with the global
419+
# variables. To force a resync, change the user and update a session variable from a
420+
# plugin, in this case InnoDB.
421+
#
422+
select @@session.innodb_strict_mode;
423+
let $innodb_strict_mode_save = `select @@session.innodb_strict_mode`;
424+
select user(), current_user();
425+
--echo change_user root
426+
--change_user root
427+
--echo #
428+
--echo # Trigger a resync of session variables with global variables.
429+
--echo #
430+
set @@session.innodb_strict_mode=off;
431+
432+
--echo
433+
--echo # Restore
434+
--echo
435+
eval set @@session.innodb_strict_mode=$innodb_strict_mode_save;
436+
select @@session.innodb_strict_mode;
437+
407438
--echo
408439
--echo ================================================================================
409440
--echo CLEAN UP

sql/sql_plugin.cc

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,8 +2807,10 @@ void alloc_and_copy_thd_dynamic_variables(THD *thd, bool global_lock)
28072807

28082808
mysql_rwlock_rdlock(&LOCK_system_variables_hash);
28092809

2810-
/* Block system variable reads from other threads. */
2811-
mysql_mutex_lock(&thd->LOCK_thd_sysvar);
2810+
if (global_lock)
2811+
mysql_mutex_lock(&LOCK_global_system_variables);
2812+
2813+
mysql_mutex_assert_owner(&LOCK_global_system_variables);
28122814

28132815
/*
28142816
MAINTAINER:
@@ -2823,10 +2825,6 @@ void alloc_and_copy_thd_dynamic_variables(THD *thd, bool global_lock)
28232825
global_variables_dynamic_size,
28242826
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
28252827

2826-
if (global_lock)
2827-
mysql_mutex_lock(&LOCK_global_system_variables);
2828-
2829-
mysql_mutex_assert_owner(&LOCK_global_system_variables);
28302828
/*
28312829
Debug hook which allows tests to check that this code is not
28322830
called for InnoDB after connection was created.
@@ -2879,7 +2877,6 @@ void alloc_and_copy_thd_dynamic_variables(THD *thd, bool global_lock)
28792877
thd->variables.dynamic_variables_size=
28802878
global_system_variables.dynamic_variables_size;
28812879

2882-
mysql_mutex_unlock(&thd->LOCK_thd_sysvar);
28832880
mysql_rwlock_unlock(&LOCK_system_variables_hash);
28842881
}
28852882

@@ -2904,7 +2901,8 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
29042901
if (!thd->variables.dynamic_variables_ptr ||
29052902
(uint)offset > thd->variables.dynamic_variables_head)
29062903
{
2907-
if (current_thd == thd) /* TODO WL#6629: Supported for current_thd only. */
2904+
/* Current THD only. Don't trigger resync on remote THD. */
2905+
if (current_thd == thd)
29082906
alloc_and_copy_thd_dynamic_variables(thd, global_lock);
29092907
else
29102908
return (uchar*) global_system_variables.dynamic_variables_ptr + offset;

0 commit comments

Comments
 (0)