diff options
author | Gopal Shankar <gopal.shankar@oracle.com> | 2012-05-17 18:07:59 +0530 |
---|---|---|
committer | Gopal Shankar <gopal.shankar@oracle.com> | 2012-05-17 18:07:59 +0530 |
commit | 047fea0682414c7bc6d8b7db60ce173c8162dd39 (patch) | |
tree | 43832224070441d18080f5b3f4854d565e03dad6 /sql/sql_class.h | |
parent | 4f5ada6d02409958052340385f1f4d4e83d4f2bf (diff) | |
download | mariadb-git-047fea0682414c7bc6d8b7db60ce173c8162dd39.tar.gz |
Bug#12636001 : deadlock from thd_security_context
PROBLEM:
Threads end-up in deadlock due to locks acquired as described
below,
con1: Run Query on a table.
It is important that this SELECT must back-off while
trying to open the t1 and enter into wait_for_condition().
The SELECT then is blocked trying to lock mysys_var->mutex
which is held by con3. The very significant fact here is
that mysys_var->current_mutex will still point to LOCK_open,
even if LOCK_open is no longer held by con1 at this point.
con2: Try dropping table used in con1 or query some table.
It will hold LOCK_open and be blocked trying to lock
kernel_mutex held by con4.
con3: Try killing the query run by con1.
It will hold THD::LOCK_thd_data belonging to con1 while
trying to lock mysys_var->current_mutex belonging to con1.
But current_mutex will point to LOCK_open which is held
by con2.
con4: Get innodb engine status
It will hold kernel_mutex, trying to lock THD::LOCK_thd_data
belonging to con1 which is held by con3.
So while technically only con2, con3 and con4 participate in the
deadlock, con1's mysys_var->current_mutex pointing to LOCK_open
is a vital component of the deadlock.
CYCLE = (THD::LOCK_thd_data -> LOCK_open ->
kernel_mutex -> THD::LOCK_thd_data)
FIX:
LOCK_thd_data has responsibility of protecting,
1) thd->query, thd->query_length
2) VIO
3) thd->mysys_var (used by KILL statement and shutdown)
4) THD during thread delete.
Among above responsibilities, 1), 2)and (3,4) seems to be three
independent group of responsibility. If there is different LOCK
owning responsibility of (3,4), the above mentioned deadlock cycle
can be avoid. This fix introduces LOCK_thd_kill to handle
responsibility (3,4), which eliminates the deadlock issue.
Note: The problem is not found in 5.5. Introduction MDL subsystem
caused metadata locking responsibility to be moved from TDC/TC to
MDL subsystem. Due to this, responsibility of LOCK_open is reduced.
As the use of LOCK_open is removed in open_table() and
mysql_rm_table() the above mentioned CYCLE does not form.
Revision ID for changes,
open_table() = dlenev@mysql.com-20100727133458-m3ua9oslnx8fbbvz
mysql_rm_table() = jon.hauglid@oracle.com-20101116100012-kxep9txz2fxy3nmw
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r-- | sql/sql_class.h | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 31d2c664aae..3ecf032db71 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1342,11 +1342,23 @@ public: Protects THD data accessed from other threads: - thd->query and thd->query_length (used by SHOW ENGINE INNODB STATUS and SHOW PROCESSLIST - - thd->mysys_var (used by KILL statement and shutdown). - Is locked when THD is deleted. */ pthread_mutex_t LOCK_thd_data; + /** + - Protects thd->mysys_var (used during KILL statement and shutdown). + - Is Locked when THD is deleted. + + Note: This responsibility was earlier handled by LOCK_thd_data. + This lock is introduced to solve a deadlock issue waiting for + LOCK_thd_data. As this lock reduces responsibility of LOCK_thd_data + the deadlock issues is solved. + Caution: LOCK_thd_kill should not be taken while holding LOCK_thd_data. + THD::awake() currently takes LOCK_thd_data after holding + LOCK_thd_kill. + */ + pthread_mutex_t LOCK_thd_kill; + /* all prepared statements and cursors of this connection */ Statement_map stmt_map; /* |