An error occurred fetching the project authors.
  1. 29 Apr, 2015 1 commit
  2. 12 Apr, 2015 2 commits
  3. 03 May, 2014 1 commit
    • Michael Widenius's avatar
      Added new states to be able to better diagnose where server hangs. · a10a9448
      Michael Widenius authored
      - Table locks now ends with state "After table lock"
      - Open table now ends with state "After opening tables"
      - All calls to close_thread_tables(), not only from mysql_execute_command(), has state "closing tables"
      - Added state "executing" for mysql admin commands, like CACHE INDEX, REPAIR TABLE etc.
      - Added state "Finding key cache" for CACHE INDEX
      - Added state "Filling schema table" when we generate temporary table for SHOW commands and information schema.
      
      Other things:
      Add limit from innobase for thread_sleep_delay. This fixed a failing tests case.
      Added db.opt to support-files to make 'make package' work
      
      
      mysql-test/suite/funcs_1/datadict/processlist_val.inc:
        Use new state
      mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result:
        Updated test result because of new state
      mysql-test/suite/funcs_1/r/processlist_val_no_prot.result:
        Updated test result because of new state
      sql/CMakeLists.txt:
        Have option files in support-files
      sql/lock.cc:
        Added new state 'After table lock'
      sql/sql_admin.cc:
        Added state "executing" and "Sending data" for mysql admin commands, like CACHE INDEX, REPAIR TABLE etc.
        Added state "Finding key cache"
      sql/sql_base.cc:
        open tables now ends with state "After table lock", instead of NULL
      sql/sql_parse.cc:
        Moved state "closing tables" to close_thread_tables()
      sql/sql_show.cc:
        Added state "Filling schema table" when we generate temporary table for SHOW commands and information schema.
      storage/xtradb/buf/buf0buf.c:
        Removed compiler warning
      storage/xtradb/handler/ha_innodb.cc:
        Add limit from innobase for thread_sleep_delay. This fixed a failing tests case.
      support-files/db.opt:
        cmakes needs this to create data/test directory
      a10a9448
  4. 22 Jan, 2014 1 commit
    • Michael Widenius's avatar
      Fix for MDEV-5547: Bad error message when moving very old .frm files to MariaDB 5.5. · 04bee0af
      Michael Widenius authored
      mysql_upgrade --help now also prints out --default options and variable values.
      mysql_upgrade now prints permission errors.
      mysql_upgrade doesn't print some non essential info if --silent is used.
      Added handler error message about incompatible versions
      Fixed that mysqlbug and mysql_install_db have the executable flag set.
      Removed executable flag for some non executable files.
      Changed in mysql_install_db askmonty.org to mariadb.com.
      Ensured that all client executables prints --default options the same way.
      Allow REPAIR ... USE_FRM for old .frm files if the are still compatible.
      Extended shown error for storage engine messages.
      
      
      client/mysql.cc:
        print_defaults() should be first (as in all other programs)
      client/mysql_upgrade.c:
        --help now also prints out --default options and variable values
        Print out error if wrong permissions
        Don't print info if --silent
      client/mysqladmin.cc:
        print_defaults() should be first (as in all other programs)
      client/mysqlbinlog.cc:
        Added print_defaults() to --help
      client/mysqlcheck.c:
        Added empty line in --help
      client/mysqlimport.c:
        Added empty line in --help
      client/mysqlshow.c:
        Made --help compatible
      client/mysqlslap.c:
        Made --help compatible
      client/mysqltest.cc:
        Added print_defaults() to --help
      include/handler_ername.h:
        Added handler error message
      include/my_base.h:
        Added handler error message
      mysql-test/r/mysql_upgrade.result:
        Updated results
      mysql-test/r/repair.result:
        Added test case for better error messages
      mysql-test/std_data/host_old.MYD:
        Added test case for better error messages
      mysql-test/std_data/host_old.MYI:
        Added test case for better error messages
      mysql-test/std_data/host_old.frm:
        Added test case for better error messages
      mysql-test/t/repair.test:
        Added test case for better error messages
      mysys/my_handler_errors.h:
        Added handler error message
      scripts/CMakeLists.txt:
        Fixed that mysqlbug and mysql_install_db have the executable flag set
      scripts/mysql_install_db.sh:
        askmonty.org -> mariadb.com
      sql/ha_partition.cc:
        Sometimes table_type() can be called for errors even if partition didn't manage to open any files
      sql/handler.cc:
        Write clear text for not handled, but defined error messages.
      sql/share/errmsg-utf8.txt:
        Extended shown error for storage engine messages
      sql/sql_admin.cc:
        Allow REPAIR ... USE_FRM for old .frm files if the are still compatible
      storage/myisam/ha_myisam.cc:
        Use new error message
      04bee0af
  5. 20 Aug, 2013 2 commits
    • Dmitry Lenev's avatar
      Fix for bug#14188793 - "DEADLOCK CAUSED BY ALTER TABLE DOEN'T CLEAR · fc2c6692
      Dmitry Lenev authored
      STATUS OF ROLLBACKED TRANSACTION" and bug #17054007 - "TRANSACTION
      IS NOT FULLY ROLLED BACK IN CASE OF INNODB DEADLOCK".
      
      The problem in the first bug report was that although deadlock involving
      metadata locks was reported using the same error code and message as InnoDB
      deadlock it didn't rollback transaction like the latter. This caused
      confusion to users as in some cases after ER_LOCK_DEADLOCK transaction
      could have been restarted immediately and in some cases rollback was
      required.
      
      The problem in the second bug report was that although InnoDB deadlock
      caused transaction rollback in all storage engines it didn't cause release
      of metadata locks. So concurrent DDL on the tables used in transaction was
      blocked until implicit or explicit COMMIT or ROLLBACK was issued in the
      connection which got InnoDB deadlock.
      
      The former issue has stemmed from the fact that when support for detection
      and reporting metadata locks deadlocks was added we erroneously assumed
      that InnoDB doesn't rollback transaction on deadlock but only last statement
      (while this is what happens on InnoDB lock timeout actually) and so didn't
      implement rollback of transactions on MDL deadlocks.
      
      The latter issue was caused by the fact that rollback of transaction due
      to deadlock is carried out by setting THD::transaction_rollback_request
      flag at the point where deadlock is detected and performing rollback
      inside of trans_rollback_stmt() call when this flag is set. And
      trans_rollback_stmt() is not aware of MDL locks, so no MDL locks are
      released.
      
      This patch solves these two problems in the following way:
      
      - In case when MDL deadlock is detect transaction rollback is requested
        by setting THD::transaction_rollback_request flag.
      
      - Code performing rollback of transaction if THD::transaction_rollback_request
        is moved out from trans_rollback_stmt(). Now we handle rollback request
        on the same level as we call trans_rollback_stmt() and release statement/
        transaction MDL locks.
      fc2c6692
    • Dmitry Lenev's avatar
      Fix for bug#14188793 - "DEADLOCK CAUSED BY ALTER TABLE DOEN'T CLEAR · b07ec61f
      Dmitry Lenev authored
      STATUS OF ROLLBACKED TRANSACTION" and bug #17054007 - "TRANSACTION
      IS NOT FULLY ROLLED BACK IN CASE OF INNODB DEADLOCK".
      
      The problem in the first bug report was that although deadlock involving
      metadata locks was reported using the same error code and message as InnoDB
      deadlock it didn't rollback transaction like the latter. This caused
      confusion to users as in some cases after ER_LOCK_DEADLOCK transaction
      could have been restarted immediately and in some cases rollback was
      required.
      
      The problem in the second bug report was that although InnoDB deadlock
      caused transaction rollback in all storage engines it didn't cause release
      of metadata locks. So concurrent DDL on the tables used in transaction was
      blocked until implicit or explicit COMMIT or ROLLBACK was issued in the
      connection which got InnoDB deadlock.
      
      The former issue has stemmed from the fact that when support for detection
      and reporting metadata locks deadlocks was added we erroneously assumed
      that InnoDB doesn't rollback transaction on deadlock but only last statement
      (while this is what happens on InnoDB lock timeout actually) and so didn't
      implement rollback of transactions on MDL deadlocks.
      
      The latter issue was caused by the fact that rollback of transaction due
      to deadlock is carried out by setting THD::transaction_rollback_request
      flag at the point where deadlock is detected and performing rollback
      inside of trans_rollback_stmt() call when this flag is set. And
      trans_rollback_stmt() is not aware of MDL locks, so no MDL locks are
      released.
      
      This patch solves these two problems in the following way:
      
      - In case when MDL deadlock is detect transaction rollback is requested
        by setting THD::transaction_rollback_request flag.
      
      - Code performing rollback of transaction if THD::transaction_rollback_request
        is moved out from trans_rollback_stmt(). Now we handle rollback request
        on the same level as we call trans_rollback_stmt() and release statement/
        transaction MDL locks.
      b07ec61f
  6. 25 May, 2013 1 commit
  7. 01 Mar, 2013 1 commit
    • Michael Widenius's avatar
      Fixed bug MPDEV-628 / LP:989055 - Querying myisam table metadata may corrupt the table. · 8ed283d8
      Michael Widenius authored
      The issue was that there was that SHOW commands could open the table in the store engine, even in cases
      where it should not be allowed to do that (ie, the storage engines meta data for that table was under big changes).
      
      The cases where this should not be allowed are:
      - ALTER TABLE DISABLE KEYS
      - ALTER TABLE ENABLE KEYS
      - REPAIR TABLE
      - OPTIMIZE TABLE
      - DROP TABLE
      
      This patch adds a new mode, protected_against_usage(). If this is used then the SHOW command will wait until the table
      is accessable. This is implemented by re-using the already exising 'version' flag for TABLE_SHARE.
      It also added functions to be used to change TABLE_SHARE->version instead of changing it directly.
      	
      
      
      mysql-test/r/myisam-metadata.result:
        Added test case
      mysql-test/t/myisam-metadata.test:
        Added test case
      sql/mysqld.cc:
        Start from refresh_version 2 as 0 and 1 are reserved.
      sql/sql_admin.cc:
        Added MYSQL_OPEN_FOR_REPAIR
        Updated call to wait_while_table_is_used()
      sql/sql_base.cc:
        Updated call to wait_while_table_is_used()
        - Allow one to specify how the table should be removed (for all commands except show or for all commands).
        - Don't allow one to reopen the table if one has called share->protect_against_usage()
      sql/sql_base.h:
        Added TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE, which is used to mark that no one can reopen this table, except with MYSQL_OPEN_FOR_REPAIR .
        - Added MYSQL_OPEN_FOR_REPAIR
        - Updated prototype for wait_while_table_is_used()
      sql/sql_table.cc:
        Updated call to wait_while_table_is_used()
        Use MYSQL_OPEN_FOR_REPAIR for open tables that where repaired.
      sql/sql_truncate.cc:
        Updated call to wait_while_table_is_used()
      sql/table.cc:
        Use set_refresh_version()
      sql/table.h:
        Added functions to be used to change TABLE_SHARE->version instead of changing it directly
      8ed283d8
  8. 28 Aug, 2012 1 commit
    • Michael Widenius's avatar
      Split ER_NO_SUCH_TABLE into ER_NO_SUCH_TABLE and ER_NO_SUCH_TABLE_IN_ENGINE to... · 7dad5363
      Michael Widenius authored
      Split ER_NO_SUCH_TABLE into ER_NO_SUCH_TABLE and ER_NO_SUCH_TABLE_IN_ENGINE to be able to distingus if a .frm file is missing or if the table is missing in the engine.
      
      
      sql/handler.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/rpl_record.cc:
        Fixed wrong printf
      sql/share/errmsg-utf8.txt:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/sp.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/sp_head.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/sql_admin.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/sql_base.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/sql_show.cc:
        Added ER_NO_SUCH_TABLE_IN_ENGINE
      sql/table.cc:
        Fixed typo
      7dad5363
  9. 16 May, 2012 2 commits
    • Michael Widenius's avatar
      More fixes for LOCK TABLE and REPAIR/FLUSH · b1485a47
      Michael Widenius authored
      Changed HA_EXTRA_NORMAL to HA_EXTRA_NOT_USED (more clean)
      
      mysql-test/suite/maria/lock.result:
        More extensive tests of LOCK TABLE with FLUSH and REPAIR
      mysql-test/suite/maria/lock.test:
        More extensive tests of LOCK TABLE with FLUSH and REPAIR
      sql/sql_admin.cc:
        Fix that REPAIR TABLE ... USE_FRM works with LOCK TABLES
      sql/sql_base.cc:
        Ensure that transactions are closed in ARIA when doing flush
        HA_EXTRA_NORMAL -> HA_EXTRA_NOT_USED
        Don't call extra many times for a table in close_all_tables_for_name()
        Added test if table_list->table as this can happen in error situations
      sql/sql_partition.cc:
        HA_EXTRA_NORMAL -> HA_EXTRA_NOT_USED
      sql/sql_reload.cc:
        Fixed comment
      sql/sql_table.cc:
        HA_EXTRA_NORMAL -> HA_EXTRA_NOT_USED
      sql/sql_trigger.cc:
        HA_EXTRA_NORMAL -> HA_EXTRA_NOT_USED
      sql/sql_truncate.cc:
        HA_EXTRA_FORCE_REOPEN -> HA_EXTRA_PREPARE_FOR_DROP for truncate, as this speeds up truncate by not having to flush the cache to disk.
      b1485a47
    • Michael Widenius's avatar
      Fixed bug LP:973039 - Assertion `share->in_trans == 0' failed in maria_close... · 6d8e329c
      Michael Widenius authored
      Fixed bug LP:973039 - Assertion `share->in_trans == 0' failed in maria_close on DROP TABLE under LOCK
      - 5.5 was missing calls to ha_extra(HA_PREPARE_FOR_DROP | HA_PREPARE_FOR_RENAME);  Lost in merge 5.3 -> 5.5
      
      
      sql/sql_admin.cc:
        Updated arguments for close_all_tables_for_name
      sql/sql_base.h:
        Updated arguments for close_all_tables_for_name
      sql/sql_partition.cc:
        Updated arguments for close_all_tables_for_name
      sql/sql_table.cc:
        Updated arguments for close_all_tables_for_name
        Removed test of kill, as we have already called 'ha_extra(HA_PREPARE_FOR_DROP)' and the table may be inconsistent.
      sql/sql_trigger.cc:
        Updated arguments for close_all_tables_for_name
      sql/sql_truncate.cc:
        For truncate that is done with drop + recreate, signal that the table will be dropped.
      6d8e329c
  10. 02 Feb, 2012 2 commits
    • Mattias Jonsson's avatar
      Bug#13593865 - 64037: CRASH IN HA_PARTITION::CREATE_HANDLERS ON · 7ebeb143
      Mattias Jonsson authored
                            ALTER TABLE AFTER DROP PARTITION
      Bug#13608188 - 64038: CRASH IN HANDLER::HA_THD ON ALTER TABLE AFTER
                            REPAIR NON-EXISTING PARTITION
      
      Backport of bug#13357766 from -trunk to -5.5.
      
      The state of some partitions was not reset on failure, leading
      to invalid states of partitions in consequent statements.
      
      Fixed by reverting back to original state for all partitions
      if not all partition names was resolved.
      
      Also adding extra security by forcing tables to be reopened
      in case of error in mysql_alter_table.
      
      (There is also removal of \r at the end of some lines.)
      7ebeb143
    • Mattias Jonsson's avatar
      Bug#13593865 - 64037: CRASH IN HA_PARTITION::CREATE_HANDLERS ON · 98d3ef96
      Mattias Jonsson authored
                            ALTER TABLE AFTER DROP PARTITION
      Bug#13608188 - 64038: CRASH IN HANDLER::HA_THD ON ALTER TABLE AFTER
                            REPAIR NON-EXISTING PARTITION
      
      Backport of bug#13357766 from -trunk to -5.5.
      
      The state of some partitions was not reset on failure, leading
      to invalid states of partitions in consequent statements.
      
      Fixed by reverting back to original state for all partitions
      if not all partition names was resolved.
      
      Also adding extra security by forcing tables to be reopened
      in case of error in mysql_alter_table.
      
      (There is also removal of \r at the end of some lines.)
      98d3ef96
  11. 25 Apr, 2011 1 commit
  12. 15 Apr, 2011 2 commits
    • Alexander Nozdrin's avatar
      A patch for Bug#11763166 (55847: SHOW WARNINGS returns empty · 060541c0
      Alexander Nozdrin authored
      result set when SQLEXCEPTION is active.
      
      The problem was in a hackish THD::no_warnings_for_error attribute.
      When it was set, an error was not written to Warning_info -- only
      Diagnostics_area state was changed. That means, Diagnostics_area
      might contain error state, which is not present in Warning_info.
      
      The user-visible problem was that in some cases SHOW WARNINGS
      returned empty result set (i.e. there were no warnings) while
      the previous SQL statement failed. According to the MySQL
      protocol errors must be presented in warning list.
      
      The main idea of this patch is to remove THD::no_warnings_for_error.
      There were few places where it was used:
        - sql_admin.cc, handling of REPAIR TABLE USE_FRM.
        - sql_show.cc, when calling fill_schema_table_from_frm().
        - sql_show.cc, when calling fill_table().
      The fix is to either use internal-error-handlers, or to use
      temporary Warning_info storing warnings, which might be ignored.
      
      This patch is needed to fix Bug 11763162 (55843).
      060541c0
    • Alexander Nozdrin's avatar
      A patch for Bug#11763166 (55847: SHOW WARNINGS returns empty · 506ff594
      Alexander Nozdrin authored
      result set when SQLEXCEPTION is active.
      
      The problem was in a hackish THD::no_warnings_for_error attribute.
      When it was set, an error was not written to Warning_info -- only
      Diagnostics_area state was changed. That means, Diagnostics_area
      might contain error state, which is not present in Warning_info.
      
      The user-visible problem was that in some cases SHOW WARNINGS
      returned empty result set (i.e. there were no warnings) while
      the previous SQL statement failed. According to the MySQL
      protocol errors must be presented in warning list.
      
      The main idea of this patch is to remove THD::no_warnings_for_error.
      There were few places where it was used:
        - sql_admin.cc, handling of REPAIR TABLE USE_FRM.
        - sql_show.cc, when calling fill_schema_table_from_frm().
        - sql_show.cc, when calling fill_table().
      The fix is to either use internal-error-handlers, or to use
      temporary Warning_info storing warnings, which might be ignored.
      
      This patch is needed to fix Bug 11763162 (55843).
      506ff594
  13. 08 Mar, 2011 2 commits
    • Jon Olav Hauglid's avatar
      Bug #11755431 (former 47205) · 0db0e64f
      Jon Olav Hauglid authored
      MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT
      SUPPORTING NATIVE REPAIR
      
      Executing 'mysqlcheck --check-upgrade --auto-repair ...' will first issue
      'CHECK TABLE FOR UPGRADE' for all tables in the database in order to check if the
      tables are compatible with the current version of MySQL. Any tables that are
      found incompatible are then upgraded using 'REPAIR TABLE'.
      
      The problem was that some engines (e.g. InnoDB) do not support 'REPAIR TABLE'.
      This caused any such tables to be left incompatible. As a result such tables were
      not properly fixed by the mysql_upgrade tool.
      
      This patch fixes the problem by first changing 'CHECK TABLE FOR UPGRADE' to return
      a different error message if the engine does not support REPAIR. Instead of
      "Table upgrade required. Please do "REPAIR TABLE ..." it will report
      "Table rebuild required. Please do "ALTER TABLE ... FORCE ..."
      
      Second, the patch changes mysqlcheck to do 'ALTER TABLE ... FORCE' instead of
      'REPAIR TABLE' in these cases.
      
      This patch also fixes 'ALTER TABLE ... FORCE' to actually rebuild the table.
      This change should be reflected in the documentation. Before this patch,
      'ALTER TABLE ... FORCE' was unused (See Bug#11746162)
      
      Test case added to mysqlcheck.test
      
      
      client/mysqlcheck.c:
        Changed mysqlcheck to do 'ALTER TABLE ... FORCE' if
        'CHECK TABLE FOR UPGRADE' reports ER_TABLE_NEEDS_REBUILD
        and not ER_TABLE_NEEDS_UPGRADE.
      mysql-test/r/mysqlcheck.result:
        Added regression test.
      mysql-test/std_data/bug47205.frm:
        InnoDB 5.0 FRM which contains a varchar primary key using
        utf8_general_ci. This is an incompatible FRM for 5.5.
      mysql-test/t/mysqlcheck.test:
        Added regression test.
      sql/handler.h:
        Added new HA_CAN_REPAIR flag.
      sql/share/errmsg-utf8.txt:
        Added new error message ER_TABLE_NEEDS_REBUILD
      sql/sql_admin.cc:
        Changed 'CHECK TABLE FOR UPDATE' to give ER_TABLE_NEEDS_REBUILD
        instead of ER_TABLE_NEEDS_UPGRADE if the engine does not support
        REPAIR (as indicated by the new HA_CAN_REPAIR flag).
      sql/sql_lex.h:
        Remove unused ALTER_FORCE flag.
      sql/sql_yacc.yy:
        Make sure ALTER TABLE ... FORCE recreates the table
        by setting the ALTER_RECREATE flag as the ALTER_FORCE
        flag was unused.
      storage/archive/ha_archive.h:
        Added new HA_CAN_REPAIR flag to Archive
      storage/csv/ha_tina.h:
        Added new HA_CAN_REPAIR flag to CSV
      storage/federated/ha_federated.h:
        Added new HA_CAN_REPAIR flag to Federated
      storage/myisam/ha_myisam.cc:
        Added new HA_CAN_REPAIR flag to MyISAM
      0db0e64f
    • Jon Olav Hauglid's avatar
      Bug #11755431 (former 47205) · 984988cf
      Jon Olav Hauglid authored
      MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT
      SUPPORTING NATIVE REPAIR
      
      Executing 'mysqlcheck --check-upgrade --auto-repair ...' will first issue
      'CHECK TABLE FOR UPGRADE' for all tables in the database in order to check if the
      tables are compatible with the current version of MySQL. Any tables that are
      found incompatible are then upgraded using 'REPAIR TABLE'.
      
      The problem was that some engines (e.g. InnoDB) do not support 'REPAIR TABLE'.
      This caused any such tables to be left incompatible. As a result such tables were
      not properly fixed by the mysql_upgrade tool.
      
      This patch fixes the problem by first changing 'CHECK TABLE FOR UPGRADE' to return
      a different error message if the engine does not support REPAIR. Instead of
      "Table upgrade required. Please do "REPAIR TABLE ..." it will report
      "Table rebuild required. Please do "ALTER TABLE ... FORCE ..."
      
      Second, the patch changes mysqlcheck to do 'ALTER TABLE ... FORCE' instead of
      'REPAIR TABLE' in these cases.
      
      This patch also fixes 'ALTER TABLE ... FORCE' to actually rebuild the table.
      This change should be reflected in the documentation. Before this patch,
      'ALTER TABLE ... FORCE' was unused (See Bug#11746162)
      
      Test case added to mysqlcheck.test
      984988cf
  14. 10 Jan, 2011 2 commits
    • Jon Olav Hauglid's avatar
      Bug #58933 Assertion `thd- >is_error()' fails on shutdown with ongoing · 6bbfe7c6
      Jon Olav Hauglid authored
                 OPTIMIZE TABLE
      
      OPTIMIZE TABLE for InnoDB tables is handled as recreate + analyze.
      The triggered assert checked that an error had been reported if either
      recreate or analyze failed. However the assert failed to take into
      account that they could have failed because OPTIMIZE TABLE had been
      victim of KILL QUERY, KILL CONNECTION or server shutdown.
      
      This patch adjusts the assert to take this possibility into account.
      The problem was only noticeable on debug versions of the server.
      
      Test case added to innodb_mysql_sync.test.
      6bbfe7c6
    • Jon Olav Hauglid's avatar
      Bug #58933 Assertion `thd- >is_error()' fails on shutdown with ongoing · 04823e33
      Jon Olav Hauglid authored
                 OPTIMIZE TABLE
      
      OPTIMIZE TABLE for InnoDB tables is handled as recreate + analyze.
      The triggered assert checked that an error had been reported if either
      recreate or analyze failed. However the assert failed to take into
      account that they could have failed because OPTIMIZE TABLE had been
      victim of KILL QUERY, KILL CONNECTION or server shutdown.
      
      This patch adjusts the assert to take this possibility into account.
      The problem was only noticeable on debug versions of the server.
      
      Test case added to innodb_mysql_sync.test.
      04823e33
  15. 11 Nov, 2010 2 commits
    • Dmitry Lenev's avatar
      Patch that refactors global read lock implementation and fixes · 6bf6272f
      Dmitry Lenev authored
      bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ
      LOCK" and bug #54673 "It takes too long to get readlock for
      'FLUSH TABLES WITH READ LOCK'".
      
      The first bug manifested itself as a deadlock which occurred
      when a connection, which had some table open through HANDLER
      statement, tried to update some data through DML statement
      while another connection tried to execute FLUSH TABLES WITH
      READ LOCK concurrently.
      
      What happened was that FTWRL in the second connection managed
      to perform first step of GRL acquisition and thus blocked all
      upcoming DML. After that it started to wait for table open
      through HANDLER statement to be flushed. When the first connection
      tried to execute DML it has started to wait for GRL/the second
      connection creating deadlock.
      
      The second bug manifested itself as starvation of FLUSH TABLES
      WITH READ LOCK statements in cases when there was a constant
      stream of concurrent DML statements (in two or more
      connections).
      
      This has happened because requests for protection against GRL
      which were acquired by DML statements were ignoring presence of
      pending GRL and thus the latter was starved.
      
      This patch solves both these problems by re-implementing GRL
      using metadata locks.
      
      Similar to the old implementation acquisition of GRL in new
      implementation is two-step. During the first step we block
      all concurrent DML and DDL statements by acquiring global S
      metadata lock (each DML and DDL statement acquires global IX
      lock for its duration). During the second step we block commits
      by acquiring global S lock in COMMIT namespace (commit code
      acquires global IX lock in this namespace).
      
      Note that unlike in old implementation acquisition of
      protection against GRL in DML and DDL is semi-automatic.
      We assume that any statement which should be blocked by GRL
      will either open and acquires write-lock on tables or acquires
      metadata locks on objects it is going to modify. For any such
      statement global IX metadata lock is automatically acquired
      for its duration.
      
      The first problem is solved because waits for GRL become
      visible to deadlock detector in metadata locking subsystem
      and thus deadlocks like one in the first bug become impossible.
      
      The second problem is solved because global S locks which
      are used for GRL implementation are given preference over
      IX locks which are acquired by concurrent DML (and we can
      switch to fair scheduling in future if needed).
      
      Important change:
      FTWRL/GRL no longer blocks DML and DDL on temporary tables.
      Before this patch behavior was not consistent in this respect:
      in some cases DML/DDL statements on temporary tables were
      blocked while in others they were not. Since the main use cases
      for FTWRL are various forms of backups and temporary tables are
      not preserved during backups we have opted for consistently
      allowing DML/DDL on temporary tables during FTWRL/GRL.
      
      Important change:
      This patch changes thread state names which are used when
      DML/DDL of FTWRL is waiting for global read lock. It is now
      either "Waiting for global read lock" or "Waiting for commit
      lock" depending on the stage on which FTWRL is.
      
      Incompatible change:
      To solve deadlock in events code which was exposed by this
      patch we have to replace LOCK_event_metadata mutex with
      metadata locks on events. As result we have to prohibit
      DDL on events under LOCK TABLES.
      
      This patch also adds extensive test coverage for interaction
      of DML/DDL and FTWRL.
      
      Performance of new and old global read lock implementations
      in sysbench tests were compared. There were no significant
      difference between new and old implementations.
      
      mysql-test/include/check_ftwrl_compatible.inc:
        Added helper script which allows to check that a statement is
        compatible with FLUSH TABLES WITH READ LOCK.
      mysql-test/include/check_ftwrl_incompatible.inc:
        Added helper script which allows to check that a statement is
        incompatible with FLUSH TABLES WITH READ LOCK.
      mysql-test/include/handler.inc:
        Adjusted test case to the fact that now DROP TABLE closes
        open HANDLERs for the table to be dropped before checking
        if there active FTWRL in this connection.
      mysql-test/include/wait_show_condition.inc:
        Fixed small error in the timeout message. The correct name
        of variable used as parameter for this script is "$condition"
        and not "$wait_condition".
      mysql-test/r/delayed.result:
        Added test coverage for scenario which triggered assert in
        metadata locking subsystem.
      mysql-test/r/events_2.result:
        Updated test results after prohibiting event DDL operations
        under LOCK TABLES.
      mysql-test/r/flush.result:
        Added test coverage for bug #57006 "Deadlock between HANDLER
        and FLUSH TABLES WITH READ LOCK".
      mysql-test/r/flush_read_lock.result:
        Added test coverage for various aspects of FLUSH TABLES WITH
        READ LOCK functionality.
      mysql-test/r/flush_read_lock_kill.result:
        Adjusted test case after replacing custom global read lock
        implementation with one based on metadata locks. Use new
        debug_sync point. Do not disable concurrent inserts as now
        InnoDB we always use InnoDB table.
      mysql-test/r/handler_innodb.result:
        Adjusted test case to the fact that now DROP TABLE closes
        open HANDLERs for the table to be dropped before checking
        if there active FTWRL in this connection.
      mysql-test/r/handler_myisam.result:
        Adjusted test case to the fact that now DROP TABLE closes
        open HANDLERs for the table to be dropped before checking
        if there active FTWRL in this connection.
      mysql-test/r/mdl_sync.result:
        Adjusted test case after replacing custom global read lock
        implementation with one based on metadata locks. Replaced
        usage of GRL-specific debug_sync's with appropriate sync
        points in MDL subsystem.
      mysql-test/suite/perfschema/r/dml_setup_instruments.result:
        Updated test results after removing global
        COND_global_read_lock condition variable.
      mysql-test/suite/perfschema/r/func_file_io.result:
        Ensure that this test doesn't affect subsequent tests.
        At the end of its execution enable back P_S instrumentation
        which this test disables at some point.
      mysql-test/suite/perfschema/r/func_mutex.result:
        Ensure that this test doesn't affect subsequent tests.
        At the end of its execution enable back P_S instrumentation
        which this test disables at some point.
      mysql-test/suite/perfschema/r/global_read_lock.result:
        Adjusted test case to take into account that new GRL
        implementation is based on MDL.
      mysql-test/suite/perfschema/r/server_init.result:
        Adjusted test case after replacing custom global read
        lock implementation with one based on MDL and replacing
        LOCK_event_metadata mutex with metadata lock.
      mysql-test/suite/perfschema/t/func_file_io.test:
        Ensure that this test doesn't affect subsequent tests.
        At the end of its execution enable back P_S instrumentation
        which this test disables at some point.
      mysql-test/suite/perfschema/t/func_mutex.test:
        Ensure that this test doesn't affect subsequent tests.
        At the end of its execution enable back P_S instrumentation
        which this test disables at some point.
      mysql-test/suite/perfschema/t/global_read_lock.test:
        Adjusted test case to take into account that new GRL
        implementation is based on MDL.
      mysql-test/suite/perfschema/t/server_init.test:
        Adjusted test case after replacing custom global read
        lock implementation with one based on MDL and replacing
        LOCK_event_metadata mutex with metadata lock.
      mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result:
        Updated test results after prohibiting event DDL under
        LOCK TABLES.
      mysql-test/t/delayed.test:
        Added test coverage for scenario which triggered assert in
        metadata locking subsystem.
      mysql-test/t/events_2.test:
        Updated test case after prohibiting event DDL operations
        under LOCK TABLES.
      mysql-test/t/flush.test:
        Added test coverage for bug #57006 "Deadlock between HANDLER
        and FLUSH TABLES WITH READ LOCK".
      mysql-test/t/flush_block_commit.test:
        Adjusted test case after changing thread state name which
        is used when COMMIT waits for FLUSH TABLES WITH READ LOCK
        from "Waiting for release of readlock" to "Waiting for commit
        lock".
      mysql-test/t/flush_block_commit_notembedded.test:
        Adjusted test case after changing thread state name which is
        used when DML waits for FLUSH TABLES WITH READ LOCK. Now we
        use "Waiting for global read lock" in this case.
      mysql-test/t/flush_read_lock.test:
        Added test coverage for various aspects of FLUSH TABLES WITH
        READ LOCK functionality.
      mysql-test/t/flush_read_lock_kill-master.opt:
        We no longer need to use make_global_read_lock_block_commit_loop
        debug tag in this test. Instead we rely on an appropriate
        debug_sync point in MDL code.
      mysql-test/t/flush_read_lock_kill.test:
        Adjusted test case after replacing custom global read lock
        implementation with one based on metadata locks. Use new
        debug_sync point. Do not disable concurrent inserts as now
        InnoDB we always use InnoDB table.
      mysql-test/t/lock_multi.test:
        Adjusted test case after changing thread state names which
        are used when DML or DDL waits for FLUSH TABLES WITH READ
        LOCK to "Waiting for global read lock".
      mysql-test/t/mdl_sync.test:
        Adjusted test case after replacing custom global read lock
        implementation with one based on metadata locks. Replaced
        usage of GRL-specific debug_sync's with appropriate sync
        points in MDL subsystem. Updated thread state names which
        are used when DDL waits for FTWRL.
      mysql-test/t/trigger_notembedded.test:
        Adjusted test case after changing thread state names which
        are used when DML or DDL waits for FLUSH TABLES WITH READ
        LOCK to "Waiting for global read lock".
      sql/event_data_objects.cc:
        Removed Event_queue_element::status/last_executed_changed
        members and Event_queue_element::update_timing_fields()
        method. We no longer use this class for updating mysql.events
        once event is chosen for execution. Accesses to instances of
        this class in scheduler thread require protection by
        Event_queue::LOCK_event_queue mutex and we try to avoid
        updating table while holding this lock.
      sql/event_data_objects.h:
        Removed Event_queue_element::status/last_executed_changed
        members and Event_queue_element::update_timing_fields()
        method. We no longer use this class for updating mysql.events
        once event is chosen for execution. Accesses to instances of
        this class in scheduler thread require protection by
        Event_queue::LOCK_event_queue mutex and we try to avoid
        updating table while holding this lock.
      sql/event_db_repository.cc:
        - Changed Event_db_repository methods to not release all
          metadata locks once they are done updating mysql.events
          table. This allows to keep metadata lock protecting
          against GRL and lock protecting particular event around
          until corresponding DDL statement is written to the binary
          log.
        - Removed logic for conditional update of "status" and
          "last_executed" fields from update_timing_fields_for_event()
          method. In the only case when this method is called now
          "last_executed" is always modified and tracking change
          of "status" is too much hassle.
      sql/event_db_repository.h:
        Removed logic for conditional update of "status" and
        "last_executed" fields from Event_db_repository::
        update_timing_fields_for_event() method.
        In the only case when this method is called now "last_executed"
        is always modified and tracking change of "status" field is
        too much hassle.
      sql/event_queue.cc:
        Changed event scheduler code not to update mysql.events
        table while holding Event_queue::LOCK_event_queue mutex.
        Doing so led to a deadlock with a new GRL implementation.
        This deadlock didn't occur with old implementation due to
        fact that code acquiring protection against GRL ignored
        pending GRL requests (which lead to GRL starvation).
        One of goals of new implementation is to disallow GRL
        starvation and so we have to solve problem with this
        deadlock in a different way.
      sql/events.cc:
        Changed methods of Events class to acquire protection
        against GRL while perfoming DDL statement and keep it
        until statement is written to the binary log.
        Unfortunately this step together with new GRL implementation
        exposed deadlock involving Events::LOCK_event_metadata
        and GRL. To solve it Events::LOCK_event_metadata mutex was
        replaced with a metadata lock on event. As a side-effect
        events DDL has to be prohibited under LOCK TABLES even in
        cases when mysql.events table was explicitly locked for
        write.
      sql/events.h:
        Replaced Events::LOCK_event_metadata mutex with a metadata
        lock on event.
      sql/ha_ndbcluster.cc:
        Updated code after replacing custom global read lock
        implementation with one based on MDL. Since MDL subsystem
        should now be able to detect deadlocks involving metadata
        locks and GRL there is no need for special handling of
        active GRL.
      sql/handler.cc:
        Replaced custom implementation of global read lock with
        one based on metadata locks. Consequently when doing
        commit instead of calling method of Global_read_lock
        class to acquire protection against GRL we simply acquire
        IX in COMMIT namespace.
      sql/lock.cc:
        Replaced custom implementation of global read lock with
        one based on metadata locks. This step allows to expose
        wait for GRL to deadlock detector of MDL subsystem and
        thus succesfully resolve deadlocks similar to one behind
        bug #57006 "Deadlock between HANDLER and FLUSH TABLES
        WITH READ LOCK". It also solves problem with GRL starvation
        described in bug #54673 "It takes too long to get readlock
        for 'FLUSH TABLES WITH READ LOCK'" since metadata locks used
        by GRL give preference to FTWRL statement instead of DML
        statements (if needed in future this can be changed to
        fair scheduling).
        
        Similar to old implementation of acquisition of GRL is
        two-step. During the first step we block all concurrent
        DML and DDL statements by acquiring global S metadata lock
        (each DML and DDL statement acquires global IX lock for
        its duration). During the second step we block commits by
        acquiring global S lock in COMMIT namespace (commit code
        acquires global IX lock in this namespace).
        
        Note that unlike in old implementation acquisition of
        protection against GRL in DML and DDL is semi-automatic.
        We assume that any statement which should be blocked by GRL
        will either open and acquires write-lock on tables or acquires
        metadata locks on objects it is going to modify. For any such
        statement global IX metadata lock is automatically acquired
        for its duration.
        
        To support this change:
        - Global_read_lock::lock/unlock_global_read_lock and
          make_global_read_lock_block_commit methods were changed
          accordingly.
        - Global_read_lock::wait_if_global_read_lock() and
          start_waiting_global_read_lock() methods were dropped.
          It is now responsibility of code acquiring metadata locks
          opening tables to acquire protection against GRL by
          explicitly taking global IX lock with statement duration.
        - Global variables, mutex and condition variable used by
          old implementation was removed.
        - lock_routine_name() was changed to use statement duration for
          its global IX lock. It was also renamed to lock_object_name()
          as it now also used to take metadata locks on events.
        - Global_read_lock::set_explicit_lock_duration() was added which
          allows not to release locks used for GRL when leaving prelocked
          mode.
      sql/lock.h:
        - Renamed lock_routine_name() to lock_object_name() and changed
          its signature to allow its usage for events.
        - Removed broadcast_refresh() function. It is no longer needed
          with new GRL implementation.
      sql/log_event.cc:
        Release metadata locks with statement duration at the end
        of processing legacy event for LOAD DATA. This ensures that
        replication thread processing such event properly releases
        its protection against global read lock.
      sql/mdl.cc:
        Changed MDL subsystem to support new MDL-based implementation
        of global read lock.
        
        Added COMMIT and EVENTS namespaces for metadata locks. Changed
        thread state name for GLOBAL namespace to "Waiting for global
        read lock".
        
        Optimized MDL_map::find_or_insert() method to avoid taking
        m_mutex mutex when looking up MDL_lock objects for GLOBAL
        or COMMIT namespaces. We keep pre-created MDL_lock objects
        for these namespaces around and simply return pointers to
        these global objects when needed.
        
        Changed MDL_lock/MDL_scoped_lock to properly handle
        notification of insert delayed handler threads when FTWRL
        takes global S lock.
        
        Introduced concept of lock duration. In addition to locks with
        transaction duration which work in the way which is similar to
        how locks worked before (i.e. they are released at the end of
        transaction), locks with statement and explicit duration were
        introduced.
        Locks with statement duration are automatically released at the
        end of statement. Locks with explicit duration require explicit
        release and obsolete concept of transactional sentinel.
        
        * Changed MDL_request and MDL_ticket classes to support notion
          of duration.
        * Changed MDL_context to keep locks with different duration in
          different lists. Changed code handling ticket list to take
          this into account.
        * Changed methods responsible for releasing locks to take into
          account duration of tickets. Particularly public
          MDL_context::release_lock() method now only can release
          tickets with explicit duration (there is still internal
          method which allows to specify duration). To release locks
          with statement or transaction duration one have to use
          release_statement/transactional_locks() methods.
        * Concept of savepoint for MDL subsystem now has to take into
          account locks with statement duration. Consequently
          MDL_savepoint class was introduced and methods working with
          savepoints were updated accordingly.
        * Added methods which allow to set duration for one or all
          locks in the context.
      sql/mdl.h:
        Changed MDL subsystem to support new MDL-based implementation
        of global read lock.
        
        Added COMMIT and EVENTS namespaces for metadata locks.
        
        Introduced concept of lock duration. In addition to locks with
        transaction duration which work in the way which is similar to
        how locks worked before (i.e. they are released at the end of
        transaction), locks with statement and explicit duration were
        introduced.
        Locks with statement duration are automatically released at the
        end of statement. Locks with explicit duration require explicit
        release and obsolete concept of transactional sentinel.
        
        * Changed MDL_request and MDL_ticket classes to support notion
          of duration.
        * Changed MDL_context to keep locks with different duration in
          different lists. Changed code handling ticket list to take
          this into account.
        * Changed methods responsible for releasing locks to take into
          account duration of tickets. Particularly public
          MDL_context::release_lock() method now only can release
          tickets with explicit duration (there is still internal
          method which allows to specify duration). To release locks
          with statement or transaction duration one have to use
          release_statement/transactional_locks() methods.
        * Concept of savepoint for MDL subsystem now has to take into
          account locks with statement duration. Consequently
          MDL_savepoint class was introduced and methods working with
          savepoints were updated accordingly.
        * Added methods which allow to set duration for one or all
          locks in the context.
      sql/mysqld.cc:
        Removed global mutex and condition variables which were used
        by old implementation of GRL.
        Also we no longer need to initialize Events::LOCK_event_metadata
        mutex as it was replaced with metadata locks on events.
      sql/mysqld.h:
        Removed global variable, mutex and condition variables which
        were used by old implementation of GRL.
      sql/rpl_rli.cc:
        When slave thread closes tables which were open for handling
        of RBR events ensure that it releases global IX lock which
        was acquired as protection against GRL.
      sql/sp.cc:
        Adjusted code to the new signature of lock_object/routine_name(),
        to the fact that one now needs specify duration of lock when
        initializing MDL_request and to the fact that savepoints for MDL
        subsystem are now represented by MDL_savepoint class.
      sql/sp_head.cc:
        Ensure that statements in stored procedures release statement
        metadata locks and thus release their protectiong against GRL
        in proper moment in time.
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request.
      sql/sql_admin.cc:
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request.
      sql/sql_base.cc:
        - Implemented support for new approach to acquiring protection
          against global read lock. We no longer acquire such protection
          explicitly on the basis of statement flags. Instead we always
          rely on code which is responsible for acquiring metadata locks
          on object to be changed acquiring this protection. This is
          achieved by acquiring global IX metadata lock with statement
          duration. Code doing this also responsible for checking that
          current connection has no active GRL by calling an
          Global_read_lock::can_acquire_protection() method.
          Changed code in open_table() and lock_table_names()
          accordingly.
          Note that as result of this change DDL and DML on temporary
          tables is always compatible with GRL (before it was
          incompatible in some cases and compatible in other cases).
        - To speed-up code acquiring protection against GRL introduced
          m_has_protection_against_grl member in Open_table_context
          class. It indicates that protection was already acquired
          sometime during open_tables() execution and new attempts
          can be skipped.
        - Thanks to new GRL implementation calls to broadcast_refresh()
          became unnecessary and were removed.
        - Adjusted code to the fact that one now needs specify duration
          of lock when initializing MDL_request and to the fact that
          savepoints for MDL subsystem are now represented by
          MDL_savepoint class.
      sql/sql_base.h:
        Adjusted code to the fact that savepoints for MDL subsystem are
        now represented by MDL_savepoint class.
        Also introduced Open_table_context::m_has_protection_against_grl
        member which allows to avoid acquiring protection against GRL
        while opening tables if such protection was already acquired.
      sql/sql_class.cc:
        Changed THD::leave_locked_tables_mode() after transactional
        sentinel for metadata locks was obsoleted by introduction of
        locks with explicit duration.
      sql/sql_class.h:
        - Adjusted code to the fact that savepoints for MDL subsystem
          are now represented by MDL_savepoint class.
        - Changed Global_read_lock class according to changes in
          global read lock implementation:
          * wait_if_global_read_lock and start_waiting_global_read_lock
            are now gone. Instead code needing protection against GRL
            has to acquire global IX metadata lock with statement
            duration itself. To help it new can_acquire_protection()
            was introduced. Also as result of the above change
            m_protection_count member is gone too.
          * Added m_mdl_blocks_commits_lock member to store metadata
            lock blocking commits.
          * Adjusted code to the fact that concept of transactional
            sentinel was obsoleted by concept of lock duration.
        - Removed CF_PROTECT_AGAINST_GRL flag as it is no longer
          necessary. New GRL implementation acquires protection
          against global read lock automagically when statement
          acquires metadata locks on tables or other objects it
          is going to change.
      sql/sql_db.cc:
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request.
      sql/sql_handler.cc:
        Removed call to broadcast_refresh() function. It is no longer
        needed with new GRL implementation.
        Adjusted code after introducing duration concept for metadata
        locks. Particularly to the fact transactional sentinel was
        replaced with explicit duration.
      sql/sql_handler.h:
        Renamed mysql_ha_move_tickets_after_trans_sentinel() to
        mysql_ha_set_explicit_lock_duration() after transactional
        sentinel was obsoleted by locks with explicit duration.
      sql/sql_insert.cc:
        Adjusted code handling delaying inserts after switching to
        new GRL implementation. Now connection thread initiating
        delayed insert has to acquire global IX lock in addition
        to metadata lock on table being inserted into. This IX lock
        protects against GRL and similarly to SW lock on table being
        inserted into has to be passed to handler thread in order to
        avoid deadlocks.
      sql/sql_lex.cc:
        LEX::protect_against_global_read_lock member is no longer
        necessary since protection against GRL is automatically
        taken by code acquiring metadata locks/opening tables.
      sql/sql_lex.h:
        LEX::protect_against_global_read_lock member is no longer
        necessary since protection against GRL is automatically
        taken by code acquiring metadata locks/opening tables.
      sql/sql_parse.cc:
        - Implemented support for new approach to acquiring protection
          against global read lock. We no longer acquire such protection
          explicitly on the basis of statement flags. Instead we always
          rely on code which is responsible for acquiring metadata locks
          on object to be changed acquiring this protection. This is
          achieved by acquiring global IX metadata lock with statement
          duration. This lock is automatically released at the end of
          statement execution.
        - Changed implementation of CREATE/DROP PROCEDURE/FUNCTION not
          to release metadata locks and thus protection against of GRL
          in the middle of statement execution.
        - Adjusted code to the fact that one now needs specify duration
          of lock when initializing MDL_request and to the fact that
          savepoints for MDL subsystem are now represented by
          MDL_savepoint class.
      sql/sql_prepare.cc:
        Adjusted code to the to the fact that savepoints for MDL
        subsystem are now represented by MDL_savepoint class.
      sql/sql_rename.cc:
        With new GRL implementation there is no need to explicitly
        acquire protection against GRL before renaming tables.
        This happens automatically in code which acquires metadata
        locks on tables being renamed.
      sql/sql_show.cc:
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request and to the fact that
        savepoints for MDL subsystem are now represented by
        MDL_savepoint class.
      sql/sql_table.cc:
        - With new GRL implementation there is no need to explicitly
          acquire protection against GRL before dropping tables.
          This happens automatically in code which acquires metadata
          locks on tables being dropped.
        - Changed mysql_alter_table() not to release lock on new table
          name explicitly and to rely on automatic release of locks
          at the end of statement instead. This was necessary since
          now MDL_context::release_lock() is supported only for locks
          for explicit duration.
      sql/sql_trigger.cc:
        With new GRL implementation there is no need to explicitly
        acquire protection against GRL before changing table triggers.
        This happens automatically in code which acquires metadata
        locks on tables which triggers are to be changed.
      sql/sql_update.cc:
        Fix bug exposed by GRL testing. During prepare phase acquire
        only S metadata locks instead of SW locks to keep prepare of
        multi-UPDATE compatible with concurrent LOCK TABLES WRITE
        and global read lock.
      sql/sql_view.cc:
        With new GRL implementation there is no need to explicitly
        acquire protection against GRL before creating view.
        This happens automatically in code which acquires metadata
        lock on view to be created.
      sql/sql_yacc.yy:
        LEX::protect_against_global_read_lock member is no longer
        necessary since protection against GRL is automatically
        taken by code acquiring metadata locks/opening tables.
      sql/table.cc:
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request.
      sql/table.h:
        Adjusted code to the fact that one now needs specify duration
        of lock when initializing MDL_request.
      sql/transaction.cc:
        Replaced custom implementation of global read lock with
        one based on metadata locks. Consequently when doing
        commit instead of calling method of Global_read_lock
        class to acquire protection against GRL we simply acquire
        IX in COMMIT namespace.
        Also adjusted code to the fact that MDL savepoint is now
        represented by MDL_savepoint class.
      6bf6272f
    • Dmitry Lenev's avatar
      Patch that refactors global read lock implementation and fixes · 378cdc58
      Dmitry Lenev authored
      bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ
      LOCK" and bug #54673 "It takes too long to get readlock for
      'FLUSH TABLES WITH READ LOCK'".
      
      The first bug manifested itself as a deadlock which occurred
      when a connection, which had some table open through HANDLER
      statement, tried to update some data through DML statement
      while another connection tried to execute FLUSH TABLES WITH
      READ LOCK concurrently.
      
      What happened was that FTWRL in the second connection managed
      to perform first step of GRL acquisition and thus blocked all
      upcoming DML. After that it started to wait for table open
      through HANDLER statement to be flushed. When the first connection
      tried to execute DML it has started to wait for GRL/the second
      connection creating deadlock.
      
      The second bug manifested itself as starvation of FLUSH TABLES
      WITH READ LOCK statements in cases when there was a constant
      stream of concurrent DML statements (in two or more
      connections).
      
      This has happened because requests for protection against GRL
      which were acquired by DML statements were ignoring presence of
      pending GRL and thus the latter was starved.
      
      This patch solves both these problems by re-implementing GRL
      using metadata locks.
      
      Similar to the old implementation acquisition of GRL in new
      implementation is two-step. During the first step we block
      all concurrent DML and DDL statements by acquiring global S
      metadata lock (each DML and DDL statement acquires global IX
      lock for its duration). During the second step we block commits
      by acquiring global S lock in COMMIT namespace (commit code
      acquires global IX lock in this namespace).
      
      Note that unlike in old implementation acquisition of
      protection against GRL in DML and DDL is semi-automatic.
      We assume that any statement which should be blocked by GRL
      will either open and acquires write-lock on tables or acquires
      metadata locks on objects it is going to modify. For any such
      statement global IX metadata lock is automatically acquired
      for its duration.
      
      The first problem is solved because waits for GRL become
      visible to deadlock detector in metadata locking subsystem
      and thus deadlocks like one in the first bug become impossible.
      
      The second problem is solved because global S locks which
      are used for GRL implementation are given preference over
      IX locks which are acquired by concurrent DML (and we can
      switch to fair scheduling in future if needed).
      
      Important change:
      FTWRL/GRL no longer blocks DML and DDL on temporary tables.
      Before this patch behavior was not consistent in this respect:
      in some cases DML/DDL statements on temporary tables were
      blocked while in others they were not. Since the main use cases
      for FTWRL are various forms of backups and temporary tables are
      not preserved during backups we have opted for consistently
      allowing DML/DDL on temporary tables during FTWRL/GRL.
      
      Important change:
      This patch changes thread state names which are used when
      DML/DDL of FTWRL is waiting for global read lock. It is now
      either "Waiting for global read lock" or "Waiting for commit
      lock" depending on the stage on which FTWRL is.
      
      Incompatible change:
      To solve deadlock in events code which was exposed by this
      patch we have to replace LOCK_event_metadata mutex with
      metadata locks on events. As result we have to prohibit
      DDL on events under LOCK TABLES.
      
      This patch also adds extensive test coverage for interaction
      of DML/DDL and FTWRL.
      
      Performance of new and old global read lock implementations
      in sysbench tests were compared. There were no significant
      difference between new and old implementations.
      378cdc58
  16. 22 Sep, 2010 2 commits
    • Jon Olav Hauglid's avatar
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for · e14934d2
      Jon Olav Hauglid authored
                 REPAIR of merge table
      Bug #56422 CHECK TABLE run when the table is locked reports
                 corruption along with timeout
      
      The crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents maintenance
      statements from continuing and trying to upgrade the metadata lock.
      
      The patch includes a 5.5 version of the fix for
      Bug #46339 crash on REPAIR TABLE merge table USE_FRM.
      This bug caused REPAIR TABLE ... USE_FRM to give an assert 
      when used on merge tables.
      
      The patch also enables the CHECK TABLE statement for log tables.
      Before, CHECK TABLE for log tables gave ER_CANT_LOCK_LOG_TABLE,
      yet still counted the statement as successfully executed.
      With the changes to table maintenance statement error handling
      in this patch, CHECK TABLE would no longer be considered as
      successful in this case. This would have caused upgrade scripts
      to mistakenly think that the general and slow logs are corrupted
      and have to be repaired. Enabling CHECK TABLES for log tables
      prevents this from happening.
      
      Finally, the patch changes the error message from "Corrupt" to
      "Operation failed" for a number of issues not related to table
      corruption. For example "Lock wait timeout exceeded" and 
      "Deadlock found trying to get lock".
      
      Test cases added to merge.test and check.test.
      e14934d2
    • Jon Olav Hauglid's avatar
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for · 5d06dddf
      Jon Olav Hauglid authored
                 REPAIR of merge table
      Bug #56422 CHECK TABLE run when the table is locked reports
                 corruption along with timeout
      
      The crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents maintenance
      statements from continuing and trying to upgrade the metadata lock.
      
      The patch includes a 5.5 version of the fix for
      Bug #46339 crash on REPAIR TABLE merge table USE_FRM.
      This bug caused REPAIR TABLE ... USE_FRM to give an assert 
      when used on merge tables.
      
      The patch also enables the CHECK TABLE statement for log tables.
      Before, CHECK TABLE for log tables gave ER_CANT_LOCK_LOG_TABLE,
      yet still counted the statement as successfully executed.
      With the changes to table maintenance statement error handling
      in this patch, CHECK TABLE would no longer be considered as
      successful in this case. This would have caused upgrade scripts
      to mistakenly think that the general and slow logs are corrupted
      and have to be repaired. Enabling CHECK TABLES for log tables
      prevents this from happening.
      
      Finally, the patch changes the error message from "Corrupt" to
      "Operation failed" for a number of issues not related to table
      corruption. For example "Lock wait timeout exceeded" and 
      "Deadlock found trying to get lock".
      
      Test cases added to merge.test and check.test.
      5d06dddf
  17. 16 Aug, 2010 4 commits
    • Mattias Jonsson's avatar
    • Mattias Jonsson's avatar
    • Mattias Jonsson's avatar
      Bug#49907: ALTER TABLE ... TRUNCATE PARTITION does not wait for · 4b20ccaf
      Mattias Jonsson authored
                 locks on the table
      
      Fixing the partitioning specifics after TRUNCATE TABLE in
      bug-42643 was fixed.
      
      Reorganize of code to decrease the size of the giant switch
      in mysql_execute_command, and to prepare for future parser
      reengineering. Moved code into Sql_statement objects.
      
      Updated patch according to davi's review comments.
      
      libmysqld/CMakeLists.txt:
        Added new files.
      libmysqld/Makefile.am:
        Added new files.
      mysql-test/r/not_partition.result:
        now returning error on partitioning commands
        if partitioning is not enabled.
      mysql-test/r/partition_disabled.result:
        There is no partition handlerton, so it cannot
        find the specified engine in the .frm file.
      mysql-test/r/partition_truncate.result:
        Updated test results.
      mysql-test/suite/parts/inc/partition_mgm.inc:
        Added check that TRUNCATE PARTITION does not delete on failure.
      mysql-test/suite/parts/r/partition_debug_sync_innodb.result:
        updated results.
      mysql-test/suite/parts/r/partition_mgm_lc0_archive.result:
        updated results.
      mysql-test/suite/parts/r/partition_mgm_lc1_archive.result:
        updated results.
      mysql-test/suite/parts/r/partition_mgm_lc2_archive.result:
        updated results.
      mysql-test/suite/parts/t/partition_debug_sync_innodb.test:
        Test case for this bug.
      mysql-test/t/not_partition.test:
        Added check for TRUNCATE PARTITION without partitioning.
      mysql-test/t/partition_truncate.test:
        Added test of TRUNCATE PARTITION on non partitioned table.
      sql/CMakeLists.txt:
        Added new files.
      sql/Makefile.am:
        Added new files.
      sql/datadict.cc:
        Moved out the storage engine check into an own
        function, including assert for lock.
      sql/datadict.h:
        added dd_frm_storage_engine.
      sql/sql_alter_table.cc:
        moved the code for SQLCOM_ALTER_TABLE in mysql_execute_command
        into its own file, and using the Sql_statement object to
        prepare for future parser reengineering.
      sql/sql_alter_table.h:
        Created Sql_statement object for ALTER TABLE.
      sql/sql_lex.cc:
        resetting m_stmt.
      sql/sql_lex.h:
        Temporary hack for forward declaration of enum_alter_table_change_level.
      sql/sql_parse.cc:
        Moved out ALTER/ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
        from the giant switch into their own Sql_statement
        objects.
      sql/sql_parse.h:
        Exporting check_merge_table_access.
      sql/sql_partition_admin.cc:
        created Sql_statement for
        ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR/TRUNCATE
        PARTITION. To be able to reuse the TABLE equivalents.
      sql/sql_partition_admin.h:
        Added Sql_statement of partition admin statements.
      sql/sql_table.cc:
        Moved table maintenance code into sql_table_maintenance.cc
      sql/sql_table.h:
        Moved table maintenance code into sql_table_maintenance.h
        exporting functions used by sql_table_maintenance.
      sql/sql_table_maintenance.cc:
        Moved table maintenance code from sql_table.cc
      sql/sql_table_maintenance.h:
        Sql_statement objects for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE.
        Also declaring the keycache functions.
      sql/sql_truncate.cc:
        Moved code from SQLCOM_TRUNCATE in mysql_execute_command into
        Truncate_statement::execute.
        Added check for partitioned table on TRUNCATE PARTITION.
        Moved locking fix for partitioned table into
        Alter_table_truncate_partition::execute.
      sql/sql_truncate.h:
        Truncate_statement declaration (sub class of Sql_statement).
      sql/sql_yacc.yy:
        Using the new Sql_statment objects.
      4b20ccaf
    • Mattias Jonsson's avatar
      Bug#49907: ALTER TABLE ... TRUNCATE PARTITION does not wait for · 25ae81f1
      Mattias Jonsson authored
                 locks on the table
      
      Fixing the partitioning specifics after TRUNCATE TABLE in
      bug-42643 was fixed.
      
      Reorganize of code to decrease the size of the giant switch
      in mysql_execute_command, and to prepare for future parser
      reengineering. Moved code into Sql_statement objects.
      
      Updated patch according to davi's review comments.
      25ae81f1