• Gopal Shankar's avatar
    Bug#12636001 : deadlock from thd_security_context · 21faded5
    Gopal Shankar authored
    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
    
    21faded5
sql_parse.cc 239 KB