1. 27 Jul, 2010 2 commits
    • Dmitry Lenev's avatar
      Fix for bug #52044 "FLUSH TABLES WITH READ LOCK and FLUSH · 00496b7a
      Dmitry Lenev authored
      TABLES <list> WITH READ LOCK are incompatible".
      
      The problem was that FLUSH TABLES <list> WITH READ LOCK
      which was issued when other connection has acquired global
      read lock using FLUSH TABLES WITH READ LOCK was blocked
      and has to wait until global read lock is released.
      
      This issue stemmed from the fact that FLUSH TABLES <list>
      WITH READ LOCK implementation has acquired X metadata locks
      on tables to be flushed. Since these locks required acquiring
      of global IX lock this statement was incompatible with global
      read lock.
      
      This patch addresses problem by using SNW metadata type of
      lock for tables to be flushed by FLUSH TABLES <list> WITH
      READ LOCK. It is OK to acquire them without global IX lock
      as long as we won't try to upgrade those locks. Since SNW
      locks allow concurrent statements using same table FLUSH
      TABLE <list> WITH READ LOCK now has to wait until old
      versions of tables to be flushed go away after acquiring
      metadata locks. Since such waiting can lead to deadlock
      MDL deadlock detector was extended to take into account
      waits for flush and resolve such deadlocks.
      
      As a bonus code in open_tables() which was responsible for
      waiting old versions of tables to go away was refactored.
      Now when we encounter old version of table in open_table()
      we don't back-off and wait for all old version to go away,
      but instead wait for this particular table to be flushed.
      Such approach supported by deadlock detection should reduce
      number of scenarios in which FLUSH TABLES aborts concurrent
      multi-statement transactions.
      
      Note that active FLUSH TABLES <list> WITH READ LOCK still
      blocks concurrent FLUSH TABLES WITH READ LOCK statement
      as the former keeps tables open and thus prevents the
      latter statement from doing flush.
      
      mysql-test/include/handler.inc:
        Adjusted test case after changing status which is set
        when FLUSH TABLES waits for tables to be flushed from
        "Flushing tables" to "Waiting for table".
      mysql-test/r/flush.result:
        Added test which checks that "flush tables <list> with
        read lock" is compatible with active "flush tables with
        read lock" but not vice-versa. This test also covers
        bug #52044 "FLUSH TABLES WITH READ LOCK and FLUSH TABLES
        <list> WITH READ LOCK are incompatible".
      mysql-test/r/mdl_sync.result:
        Added scenarios in which wait for table to be flushed
        causes deadlocks to the coverage of MDL deadlock detector.
      mysql-test/suite/perfschema/r/dml_setup_instruments.result:
        Adjusted test results after removal of COND_refresh
        condition variable.
      mysql-test/suite/perfschema/r/server_init.result:
        Adjusted test and its results after removal of COND_refresh
        condition variable.
      mysql-test/suite/perfschema/t/server_init.test:
        Adjusted test and its results after removal of COND_refresh
        condition variable.
      mysql-test/t/flush.test:
        Added test which checks that "flush tables <list> with
        read lock" is compatible with active "flush tables with
        read lock" but not vice-versa. This test also covers
        bug #52044 "FLUSH TABLES WITH READ LOCK and FLUSH TABLES
        <list> WITH READ LOCK are incompatible".
      mysql-test/t/kill.test:
        Adjusted test case after changing status which is set
        when FLUSH TABLES waits for tables to be flushed from
        "Flushing tables" to "Waiting for table".
      mysql-test/t/lock_multi.test:
        Adjusted test case after changing status which is set
        when FLUSH TABLES waits for tables to be flushed from
        "Flushing tables" to "Waiting for table".
      mysql-test/t/mdl_sync.test:
        Added scenarios in which wait for table to be flushed
        causes deadlocks to the coverage of MDL deadlock detector.
      sql/ha_ndbcluster.cc:
        Adjusted code after adding one more parameter for
        close_cached_tables() call - timeout for waiting for
        table to be flushed.
      sql/ha_ndbcluster_binlog.cc:
        Adjusted code after adding one more parameter for
        close_cached_tables() call - timeout for waiting for
        table to be flushed.
      sql/lock.cc:
        Removed COND_refresh condition variable. See comment
        for sql_base.cc for details.
      sql/mdl.cc:
        Now MDL deadlock detector takes into account information
        about waits for table flushes when searching for deadlock.
        To implement this change:
        - Declaration of enum_deadlock_weight and
          Deadlock_detection_visitor were moved to mdl.h header
          to make them available to the code in table.cc which
          implements deadlock detector traversal through edges
          of waiters graph representing waiting for flush.
        - Since now MDL_context may wait not only for metadata
          lock but also for table to be flushed an abstract
          Wait_for_edge class was introduced. Its descendants
          MDL_ticket and Flush_ticket incapsulate specifics
          of inspecting waiters graph when following through
          edge representing wait of particular type.
        
        We no longer require global IX metadata lock when acquiring
        SNW or SNRW locks. Such locks are needed only when metadata
        locks of these types are upgraded to X locks. This allows
        to use SNW locks in FLUSH TABLES <list> WITH READ LOCK
        implementation and keep the latter compatible with global
        read lock.
      sql/mdl.h:
        Now MDL deadlock detector takes into account information
        about waits for table flushes when searching for deadlock.
        To implement this change:
        - Declaration of enum_deadlock_weight and
          Deadlock_detection_visitor were moved to mdl.h header
          to make them available to the code in table.cc which
          implements deadlock detector traversal through edges
          of waiters graph representing waiting for flush.
        - Since now MDL_context may wait not only for metadata
          lock but also for table to be flushed an abstract
          Wait_for_edge class was introduced. Its descendants
          MDL_ticket and Flush_ticket incapsulate specifics
          of inspecting waiters graph when following through
          edge representing wait of particular type.
        - Deadlock_detection_visitor now has m_table_shares_visited
          member which allows to support recursive locking for
          LOCK_open. This is required when deadlock detector
          inspects waiters graph which contains several edges
          representing waits for flushes or needs to come through
          the such edge more than once.
      sql/mysqld.cc:
        Removed COND_refresh condition variable. See comment
        for sql_base.cc for details.
      sql/mysqld.h:
        Removed COND_refresh condition variable. See comment
        for sql_base.cc for details.
      sql/sql_base.cc:
        Changed approach to how threads are waiting for table
        to be flushed. Now thread that wants to wait for old
        table to go away subscribes for notification by adding
        Flush_ticket to table's share and waits using
        MDL_context::m_wait object. Once table gets flushed
        (i.e. all tables are closed and table share is ready
        to be destroyed) all such waiters are notified
        individually.
        Thanks to this change MDL deadlock detector can take
        such waits into account.
        
        To implement this/as result of this change:
        - tdc_wait_for_old_versions() was replaced with
          tdc_wait_for_old_version() which waits for individual
          old share to go away and which is called by open_table()
          after finding out that share is outdated. We don't
          need to perform back-off before such waiting thanks
          to the fact that deadlock detector now sees such waits.
        - As result Open_table_ctx::m_mdl_requests became
          unnecessary and was removed. We no longer allocate
          copies of MDL_request objects on MEM_ROOT when
          MYSQL_OPEN_FORCE_SHARED/SHARED_HIGH_PRIO flags are
          in effect.
        - close_cached_tables() and tdc_wait_for_old_version()
          share code which implements waiting for share to be
          flushed - the both use TABLE_SHARE::wait_until_flush()
          method. Thanks to this close_cached_tables() supports
          timeouts and has extra parameter for this.
        - Open_table_context::OT_MDL_CONFLICT enum element was
          renamed to OT_CONFLICT as it is now also used in cases
          when back-off is required to resolve deadlock caused
          by waiting for flush and not metadata lock.
        - In cases when we discover that current connection tries
          to open tables from different generation we now simply
          back-off and restart process of opening tables. To
          support this Open_table_context::OT_REOPEN_TABLES enum
          element was added.
        - COND_refresh condition variable became unnecessary and
          was removed.
        - mysql_notify_thread_having_shared_lock() no longer wakes
          up connections waiting for flush as all such connections
          can be waken up by deadlock detector if necessary.
      sql/sql_base.h:
        - close_cached_tables() now has one more parameter -
          timeout for waiting for table to be flushed.
        - Open_table_context::OT_MDL_CONFLICT enum element was
          renamed to OT_CONFLICT as it is now also used in cases
          when back-off is required to resolve deadlock caused
          by waiting for flush and not metadata lock.
          Added new OT_REOPEN_TABLES enum element to be used in
          cases when we need to restart open tables process even
          in the middle of transaction.
        - Open_table_ctx::m_mdl_requests became unnecessary and
          was removed.
      sql/sql_class.h:
        Added assert ensuring that we won't use LOCK_open mutex
        with THD::enter_cond(). Otherwise deadlocks can arise in
        MDL deadlock detector.
      sql/sql_parse.cc:
        Changed FLUSH TABLES <list> WITH READ LOCK to take SNW
        metadata locks instead of X locks on tables to be flushed.
        Since we no longer require global IX lock to be taken
        when SNW locks are taken this makes this statement
        compatible with FLUSH TABLES WITH READ LOCK statement.
        Since SNW locks allow other connections to have table
        opened FLUSH TABLES <list> WITH READ LOCK now has to
        wait during open_tables() for old version to go away.
        Such waits can lead to deadlocks which will be detected
        by MDL deadlock detector which now takes waits for table
        to be flushed into account.
        
        Also adjusted code after adding one more parameter for
        close_cached_tables() call - timeout for waiting for
        table to be flushed.
      sql/sql_yacc.yy:
        FLUSH TABLES <list> WITH READ LOCK now needs only SNW
        metadata locks on tables.
      sql/sys_vars.cc:
        Adjusted code after adding one more parameter for
        close_cached_tables() call - timeout for waiting for
        table to be flushed.
      sql/table.cc:
        Implemented new approach to how threads are waiting for
        table to be flushed. Now thread that wants to wait for
        old table to go away subscribes for notification by
        adding Flush_ticket to table's share and waits using
        MDL_context::m_wait object. Once table gets flushed
        (i.e. all tables are closed and table share is ready
        to be destroyed) all such waiters are notified
        individually. This change allows to make such waits
        visible inside of MDL deadlock detector.
        To do it:
        
        - Added list of waiters/Flush_tickets to TABLE_SHARE
          class.
        - Changed free_table_share() to postpone freeing of
          share memory until last waiter goes away and to
          wake up subscribed waiters.
        - Added TABLE_SHARE::wait_until_flushed() method which
          implements subscription to the list of waiters for
          table to be flushed and waiting for this event.
        
        Implemented interface which allows to expose waits for
        flushes to MDL deadlock detector:
        
        - Introduced Flush_ticket class a descendant of
          Wait_for_edge class.
        - Added TABLE_SHARE::find_deadlock() method which allows
          deadlock detector to find out what contexts are still
          using old version of table in question (i.e. to find
          out what contexts are waited for by owner of
          Flush_ticket).
      sql/table.h:
        In order to support new strategy of waiting for table flush
        (see comment for table.cc for details) added list of
        waiters/Flush_tickets to TABLE_SHARE class.
        
        Implemented interface which allows to expose waits for
        flushes to MDL deadlock detector:
        - Introduced Flush_ticket class a descendant of
          Wait_for_edge class.
        - Added TABLE_SHARE::find_deadlock() method which allows
          deadlock detector to find out what contexts are still
          using old version of table in question (i.e. to find
          out what contexts are waited for by owner of
          Flush_ticket).
      00496b7a
    • Konstantin Osipov's avatar
      A pre-requisite patch for the fix for Bug#52044. · 36290c09
      Konstantin Osipov authored
      This patch also fixes Bug#55452 "SET PASSWORD is
      replicated twice in RBR mode".
      
      The goal of this patch is to remove the release of 
      metadata locks from close_thread_tables().
      This is necessary to not mistakenly release
      the locks in the course of a multi-step
      operation that involves multiple close_thread_tables()
      or close_tables_for_reopen().
      
      On the same token, move statement commit outside 
      close_thread_tables().
      
      Other cleanups:
      Cleanup COM_FIELD_LIST.
      Don't call close_thread_tables() in COM_SHUTDOWN -- there
      are no open tables there that can be closed (we leave
      the locked tables mode in THD destructor, and this
      close_thread_tables() won't leave it anyway).
      
      Make open_and_lock_tables() and open_and_lock_tables_derived()
      call close_thread_tables() upon failure.
      Remove the calls to close_thread_tables() that are now
      unnecessary.
      
      Simplify the back off condition in Open_table_context.
      
      Streamline metadata lock handling in LOCK TABLES 
      implementation.
      
      Add asserts to ensure correct life cycle of 
      statement transaction in a session.
      
      Remove a piece of dead code that has also become redundant
      after the fix for Bug 37521.
      
      mysql-test/r/variables.result:
        Update results: set @@autocommit and statement transaction/
        prelocked mode.
      mysql-test/r/view.result:
        A harmless change in CHECK TABLE <view> status for a broken view.
        If previously a failure to prelock all functions used in a view 
        would leave the connection in LTM_PRELOCKED mode, now we call
        close_thread_tables() from open_and_lock_tables()
        and leave prelocked mode, thus some check in mysql_admin_table() that
        works only in prelocked/locked tables mode is no longer activated.
      mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result:
        Fixed Bug#55452 "SET PASSWORD is replicated twice in
        RBR mode": extra binlog events are gone from the
        binary log.
      mysql-test/t/variables.test:
        Add a test case: set autocommit and statement transaction/prelocked
        mode.
      sql/event_data_objects.cc:
        Simplify code in Event_job_data::execute().
        Move sp_head memory management to lex_end().
      sql/event_db_repository.cc:
        Move the release of metadata locks outside
        close_thread_tables().
        Make sure we call close_thread_tables() when
        open_and_lock_tables() fails and remove extra
        code from the events data dictionary.
        Use close_mysql_tables(), a new internal
        function to properly close mysql.* tables
        in the data dictionary.
        Contract Event_db_repository::drop_events_by_field,
        drop_schema_events into one function.
        When dropping all events in a schema,
        make sure we don't mistakenly release all
        locks acquired by DROP DATABASE. These
        include locks on the database name
        and the global intention exclusive
        metadata lock.
      sql/event_db_repository.h:
        Function open_event_table() does not require an instance 
        of Event_db_repository.
      sql/events.cc:
        Use close_mysql_tables() instead of close_thread_tables()
        to bootstrap events, since the latter no longer
        releases metadata locks.
      sql/ha_ndbcluster.cc:
        - mysql_rm_table_part2 no longer releases
        acquired metadata locks. Do it in the caller.
      sql/ha_ndbcluster_binlog.cc:
        Deploy the new protocol for closing thread
        tables in run_query() and ndb_binlog_index
        code.
      sql/handler.cc:
        Assert that we never call ha_commit_trans/
        ha_rollback_trans in sub-statement, which
        is now the case.
      sql/handler.h:
        Add an accessor to check whether THD_TRANS object
        is empty (has no transaction started).
      sql/log.cc:
        Update a comment.
      sql/log_event.cc:
        Since now we commit/rollback statement transaction in 
        mysql_execute_command(), we need a mechanism to communicate
        from Query_log_event::do_apply_event() to mysql_execute_command()
        that the statement transaction should be rolled back, not committed.
        Ideally it would be a virtual method of THD. I hesitate
        to make THD a virtual base class in this already large patch.
        Use a thd->variables.option_bits for now.
        
        Remove a call to close_thread_tables() from the slave IO
        thread. It doesn't open any tables, and the protocol
        for closing thread tables is more complicated now.
        
        Make sure we properly close thread tables, however, 
        in Load_data_log_event, which doesn't
        follow the standard server execution procedure
        with mysql_execute_command().
        @todo: this piece should use Server_runnable
        framework instead.
        Remove an unnecessary call to mysql_unlock_tables().
      sql/rpl_rli.cc:
        Update Relay_log_info::slave_close_thread_tables()
        to follow the new close protocol.
      sql/set_var.cc:
        Remove an unused header.
      sql/slave.cc:
        Remove an unnecessary call to
        close_thread_tables().
      sql/sp.cc:
        Remove unnecessary calls to close_thread_tables()
        from SP DDL implementation. The tables will
        be closed by the caller, in mysql_execute_command().
        When dropping all routines in a database, make sure
        to not mistakenly drop all metadata locks acquired
        so far, they include the scoped lock on the schema.
      sql/sp_head.cc:
        Correct the protocol that closes thread tables
        in an SP instruction.
        Clear lex->sphead before cleaning up lex
        with lex_end to make sure that we don't
        delete the sphead twice. It's considered
        to be "cleaner" and more in line with
        future changes than calling delete lex->sphead
        in other places that cleanup the lex.
      sql/sp_head.h:
        When destroying m_lex_keeper of an instruction,
        don't delete the sphead that all lex objects
        share. 
        @todo: don't store a reference to routine's sp_head
        instance in instruction's lex.
      sql/sql_acl.cc:
        Don't call close_thread_tables() where the caller will
        do that for us.
        Fix Bug#55452 "SET PASSWORD is replicated twice in RBR 
        mode" by disabling RBR replication in change_password()
        function.
        Use close_mysql_tables() in bootstrap and ACL reload
        code to make sure we release all metadata locks.
      sql/sql_base.cc:
        This is the main part of the patch:
        - remove manipulation with thd->transaction
        and thd->mdl_context from close_thread_tables().
        Now this function is only responsible for closing
        tables, nothing else.
        This is necessary to be able to easily use
        close_thread_tables() in procedures, that
        involve multiple open/close tables, which all
        need to be protected continuously by metadata
        locks.
        Add asserts ensuring that TABLE object
        is only used when is protected by a metadata lock.
        Simplify the back off condition of Open_table_context,
        we no longer need to look at the autocommit mode.
        Make open_and_lock_tables() and open_normal_and_derived_tables()
        close thread tables and release metadata locks acquired so-far 
        upon failure. This simplifies their usage.
        Implement close_mysql_tables().
      sql/sql_base.h:
        Add declaration for close_mysql_tables().
      sql/sql_class.cc:
        Remove a piece of dead code that has also become redundant
        after the fix for Bug 37521.
        The code became dead when my_eof() was made a non-protocol method,
        but a method that merely modifies the diagnostics area.
        The code became redundant with the fix for Bug#37521, when 
        we started to cal close_thread_tables() before
        Protocol::end_statement().
      sql/sql_do.cc:
        Do nothing in DO if inside a substatement
        (the assert moved out of trans_rollback_stmt).
      sql/sql_handler.cc:
        Add comments.
      sql/sql_insert.cc:
        Remove dead code. 
        Release metadata locks explicitly at the
        end of the delayed insert thread.
      sql/sql_lex.cc:
        Add destruction of lex->sphead to lex_end(),
        lex "reset" method called at the end of each statement.
      sql/sql_parse.cc:
        Move close_thread_tables() and other related
        cleanups to mysql_execute_command()
        from dispatch_command(). This has become
        possible after the fix for Bug#37521.
        Mark federated SERVER statements as DDL.
        
        Next step: make sure that we don't store
        eof packet in the query cache, and move
        the query cache code outside mysql_parse.
        
        Brush up the code of COM_FIELD_LIST.
        Remove unnecessary calls to close_thread_tables().
        
        When killing a query, don't report "OK"
        if it was a suicide.
      sql/sql_parse.h:
        Remove declaration of a function that is now static.
      sql/sql_partition.cc:
        Remove an unnecessary call to close_thread_tables().
      sql/sql_plugin.cc:
        open_and_lock_tables() will clean up
        after itself after a failure.
        Move close_thread_tables() above
        end: label, and replace with close_mysql_tables(),
        which will also release the metadata lock
        on mysql.plugin.
      sql/sql_prepare.cc:
        Now that we no longer release locks in close_thread_tables()
        statement prepare code has become more straightforward.
        Remove the now redundant check for thd->killed() (used
        only by the backup project) from Execute_server_runnable.
        Reorder code to take into account that now mysql_execute_command()
        performs lex->unit.cleanup() and close_thread_tables().
      sql/sql_priv.h:
        Add a new option to server options to interact
        between the slave SQL thread and execution
        framework (hack). @todo: use a virtual
        method of class THD instead.
      sql/sql_servers.cc:
        Due to Bug 25705 replication of 
        DROP/CREATE/ALTER SERVER is broken.
        Make sure at least we do not attempt to 
        replicate these statements using RBR,
        as this violates the assert in close_mysql_tables().
      sql/sql_table.cc:
        Do not release metadata locks in mysql_rm_table_part2,
        this is done by the caller.
        Do not call close_thread_tables() in mysql_create_table(),
        this is done by the caller. 
        Fix a bug in DROP TABLE under LOCK TABLES when,
        upon error in wait_while_table_is_used() we would mistakenly
        release the metadata lock on a non-dropped table.
        Explicitly release metadata locks when doing an implicit
        commit.
      sql/sql_trigger.cc:
        Now that we delete lex->sphead in lex_end(),
        zero the trigger's sphead in lex after loading
        the trigger, to avoid double deletion.
      sql/sql_udf.cc:
        Use close_mysql_tables() instead of close_thread_tables().
      sql/sys_vars.cc:
        Remove code added in scope of WL#4284 which would
        break when we perform set @@session.autocommit along
        with setting other variables and using tables or functions.
        A test case added to variables.test.
      sql/transaction.cc:
        Add asserts.
      sql/tztime.cc:
        Use close_mysql_tables() rather than close_thread_tables().
      36290c09
  2. 26 Jul, 2010 1 commit
  3. 23 Jul, 2010 1 commit
    • Jon Olav Hauglid's avatar
      Bug #55498 SHOW CREATE TRIGGER takes wrong type of metadata lock · 54c5e7c8
      Jon Olav Hauglid authored
      The first problem was that SHOW CREATE TRIGGER took a stronger metadata
      lock than required. This caused the statement to be blocked when it was
      not needed. For example, LOCK TABLE WRITE in one connection would block
      SHOW CREATE TRIGGER in another connection.
      
      Another problem was that a SHOW CREATE TRIGGER statement issued inside
      a transaction did not release its metadata locks at the end of the
      statement execution. This happened even if SHOW CREATE TRIGGER is an
      information statement. The consequence was that SHOW CREATE TRIGGER
      was able to block other connections from accessing the table
      (e.g. using ALTER TABLE).
      
      This patch fixes the problem by changing SHOW CREATE TRIGGER to take
      a MDL_SHARED_HIGH_PRIO metadata lock similar to what is already done
      for SHOW CREATE TABLE. The patch also changes SHOW CREATE TRIGGER to
      explicitly release any metadata locks taken by the statement after
      it completes.
      
      Test case added to show_check.test.
      54c5e7c8
  4. 22 Jul, 2010 3 commits
    • Davi Arnaut's avatar
    • Jon Olav Hauglid's avatar
      Bug #54905 Connection with WRITE lock cannot ALTER table due to · 2857a849
      Jon Olav Hauglid authored
                 concurrent SHOW CREATE
      
      The problem was that a SHOW CREATE TABLE statement issued inside
      a transaction did not release its metadata locks at the end of the
      statement execution. This happened even if SHOW CREATE TABLE is an
      information statement. 
      
      The consequence was that SHOW CREATE TABLE was able to block other
      connections from accessing the table (e.g. using ALTER TABLE).
      
      This patch fixes the problem by explicitly releasing any metadata
      locks taken by SHOW CREATE TABLE after the statement completes.
      
      Test case added to show_check.test.
      2857a849
    • Jon Olav Hauglid's avatar
      Bug #55223 assert in Protocol::end_statement during CREATE DATABASE · ec002090
      Jon Olav Hauglid authored
      The problem was that a statement could cause an assert if it was aborted by
      KILL QUERY while it waited on a metadata lock. This assert checks that a
      statement either sends OK or an error to the client. If the bug was triggered
      on release builds, it caused OK to be sent to the client instead of
      ER_QUERY_INTERRUPTED.
      
      The root cause of the problem was that there are two separate ways to tell if a
      statement is killed: thd->killed and mysys_var->abort. KILL QUERY causes both
      to be set, thd->killed before mysys_var->abort. Also, both values are reset
      at the end of statement execution. This means that it is possible for
      KILL QUERY to first set thd->killed, then have the killed statement reset
      both thd->killed and mysys_var->abort and finally have KILL QUERY set
      mysys_var->abort. This means that the connection with the killed statement
      will start executing the next statement with the two values out of sync - i.e.
      thd->killed not set but mysys_var->abort set.
      
      Since mysys_var->abort is used to check if a wait for a metadata lock should
      be aborted, the next statement would immediately abort any such waiting.
      When waiting is aborted, no OK message is sent and thd->killed is checked to
      see if ER_QUERY_INTERRUPTED should be sent to the client. But since
      the->killed had been reset, neither OK nor an error message was sent to the
      client. This then triggered the assert.
      
      This patch fixes the problem by changing the metadata lock waiting code to
      check thd->killed.
      
      No test case added as reproducing the assert is dependent on very exact timing
      of two (or more) threads. The patch has been checked using RQG and the grammar
      posted on the bug report.
      ec002090
  5. 19 Jul, 2010 1 commit
  6. 17 Jul, 2010 2 commits
  7. 16 Jul, 2010 20 commits
  8. 15 Jul, 2010 10 commits