1. 14 Jul, 2009 1 commit
    • Sven Sandberg's avatar
      BUG#39934: Slave stops for engine that only support row-based logging · 41783de5
      Sven Sandberg authored
      General overview:
      The logic for switching to row format when binlog_format=MIXED had
      numerous flaws. The underlying problem was the lack of a consistent
      architecture.
      General purpose of this changeset:
      This changeset introduces an architecture for switching to row format
      when binlog_format=MIXED. It enforces the architecture where it has
      to. It leaves some bugs to be fixed later. It adds extensive tests to
      verify that unsafe statements work as expected and that appropriate
      errors are produced by problems with the selection of binlog format.
      It was not practical to split this into smaller pieces of work.
      
      Problem 1:
      To determine the logging mode, the code has to take several parameters
      into account (namely: (1) the value of binlog_format; (2) the
      capabilities of the engines; (3) the type of the current statement:
      normal, unsafe, or row injection). These parameters may conflict in
      several ways, namely:
       - binlog_format=STATEMENT for a row injection
       - binlog_format=STATEMENT for an unsafe statement
       - binlog_format=STATEMENT for an engine only supporting row logging
       - binlog_format=ROW for an engine only supporting statement logging
       - statement is unsafe and engine does not support row logging
       - row injection in a table that does not support statement logging
       - statement modifies one table that does not support row logging and
         one that does not support statement logging
      Several of these conflicts were not detected, or were detected with
      an inappropriate error message. The problem of BUG#39934 was that no
      appropriate error message was written for the case when an engine
      only supporting row logging executed a row injection with
      binlog_format=ROW. However, all above cases must be handled.
      Fix 1:
      Introduce new error codes (sql/share/errmsg.txt). Ensure that all
      conditions are detected and handled in decide_logging_format()
      
      Problem 2:
      The binlog format shall be determined once per statement, in
      decide_logging_format(). It shall not be changed before or after that.
      Before decide_logging_format() is called, all information necessary to
      determine the logging format must be available. This principle ensures
      that all unsafe statements are handled in a consistent way.
      However, this principle is not followed:
      thd->set_current_stmt_binlog_row_based_if_mixed() is called in several
      places, including from code executing UPDATE..LIMIT,
      INSERT..SELECT..LIMIT, DELETE..LIMIT, INSERT DELAYED, and
      SET @@binlog_format. After Problem 1 was fixed, that caused
      inconsistencies where these unsafe statements would not print the
      appropriate warnings or errors for some of the conflicts.
      Fix 2:
      Remove calls to THD::set_current_stmt_binlog_row_based_if_mixed() from
      code executed after decide_logging_format(). Compensate by calling the
      set_current_stmt_unsafe() at parse time. This way, all unsafe statements
      are detected by decide_logging_format().
      
      Problem 3:
      INSERT DELAYED is not unsafe: it is logged in statement format even if
      binlog_format=MIXED, and no warning is printed even if
      binlog_format=STATEMENT. This is BUG#45825.
      Fix 3:
      Made INSERT DELAYED set itself to unsafe at parse time. This allows
      decide_logging_format() to detect that a warning should be printed or
      the binlog_format changed.
      
      Problem 4:
      LIMIT clause were not marked as unsafe when executed inside stored
      functions/triggers/views/prepared statements. This is
      BUG#45785.
      Fix 4:
      Make statements containing the LIMIT clause marked as unsafe at
      parse time, instead of at execution time. This allows propagating
      unsafe-ness to the view.
      
      
      mysql-test/extra/rpl_tests/create_recursive_construct.inc:
        Added auxiliary file used by binlog_unsafe.test to create and
        execute recursive constructs
        (functions/procedures/triggers/views/prepared statements).
      mysql-test/extra/rpl_tests/rpl_foreign_key.test:
        removed unnecessary set @@session.binlog_format
      mysql-test/extra/rpl_tests/rpl_insert_delayed.test:
        Filter out table id from table map events in binlog listing.
        Got rid of $binlog_format_statement.
      mysql-test/extra/rpl_tests/rpl_ndb_apply_status.test:
        disable warnings around call to unsafe procedure
      mysql-test/include/rpl_udf.inc:
        Disabled warnings for code that generates warnings
        for some binlog formats. That would otherwise cause
        inconsistencies in the result file.
      mysql-test/r/mysqldump.result:
        Views are now unsafe if they contain a LIMIT clause.
        That fixed BUG#45831. Due to BUG#45832, a warning is
        printed for the CREATE VIEW statement.
      mysql-test/r/sp_trans.result:
        Unsafe statements in stored procedures did not give a warning if
        binlog_format=statement. This is BUG#45824. Now they do, so this
        result file gets a new warning.
      mysql-test/suite/binlog/r/binlog_multi_engine.result:
        Error message changed.
      mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result:
        INSERT DELAYED didn't generate a warning when binlog_format=STATEMENT.
        That was BUG#45825. Now there is a warning, so result file needs to be
        updated.
      mysql-test/suite/binlog/r/binlog_stm_ps.result:
        Changed error message.
      mysql-test/suite/binlog/r/binlog_unsafe.result:
        updated result file:
         - error message changed
         - added test for most combinations of unsafe constructs invoked
           from recursive constructs
         - INSERT DELAYED now gives a warning (because BUG#45826 is fixed)
         - INSERT..SELECT..LIMIT now gives a warning from inside recursive
           constructs (because BUG#45785 was fixed)
         - When a recursive construct (e.g., stored proc or function)
           contains more than one statement, at least one of which is
           unsafe, then all statements in the recursive construct give
           warnings. This is a new bug introduced by this changeset.
           It will be addressed in a post-push fix.
      mysql-test/suite/binlog/t/binlog_innodb.test:
        Changed error code for innodb updates with READ COMMITTED or 
        READ UNCOMMITTED transaction isolation level and
        binlog_format=statement.
      mysql-test/suite/binlog/t/binlog_multi_engine.test:
        The error code has changed for statements where more than one
        engine is involved and one of them is self-logging.
      mysql-test/suite/binlog/t/binlog_unsafe-master.opt:
        Since binlog_unsafe now tests unsafe-ness of UDF's, we need an extra
        flag in the .opt file.
      mysql-test/suite/binlog/t/binlog_unsafe.test:
         - Clarified comment.
         - Rewrote first part of test. Now it tests not only unsafe variables
           and functions, but also unsafe-ness due to INSERT..SELECT..LIMIT,
           INSERT DELAYED, insert into two autoinc columns, use of UDF's, and
           access to log tables in the mysql database.
           Also, in addition to functions, procedures, triggers, and prepared
           statements, it now also tests views; and it constructs recursive
           calls in two levels by combining these recursive constructs.
           Part of the logic is in extra/rpl_tests/create_recursive_construct.inc.
         - added tests for all special system variables that should not be unsafe.
         - added specific tests for BUG#45785 and BUG#45825
      mysql-test/suite/rpl/r/rpl_events.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_idempotency.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_mix_found_rows.result:
        Split rpl_found_rows.test into rpl_mix_found_rows.test (a new file) and
        rpl_stm_found_rows.test (renamed rpl_found_rows.test). This file equals
        the second half of the old rpl_found_rows.result, with the following
        modifications:
         - minor formatting changes
         - additional initialization
      mysql-test/suite/rpl/r/rpl_mix_insert_delayed.result:
        Moved out code operating in mixed mode from rpl_stm_insert_delayed
        (into rpl_mix_insert_delayed) and got rid of explicit setting of
        binlog format.
      mysql-test/suite/rpl/r/rpl_rbr_to_sbr.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_row_idempotency.result:
        Moved the second half of rpl_idempotency.test, which only
        executed in row mode, to rpl_row_idempotency.test. This is
        the new result file.
      mysql-test/suite/rpl/r/rpl_row_insert_delayed.result:
        Got rid of unnecessary explicit setting of binlog format.
      mysql-test/suite/rpl/r/rpl_stm_found_rows.result:
        Split rpl_found_rows.test into rpl_mix_found_rows.test (a new file) and
        rpl_stm_found_rows.test (renamed rpl_found_rows.test). Changes in
        this file:
         - minor formatting changes
         - warning is now issued for unsafe statements inside procedures
           (since BUG#45824 is fixed)
         - second half of file is moved to rpl_mix_found_rows.result
      mysql-test/suite/rpl/r/rpl_stm_insert_delayed.result:
        Moved out code operating in mixed mode from rpl_stm_insert_delayed
        (into rpl_mix_insert_delayed) and got rid of explicit setting of
        binlog format.
      mysql-test/suite/rpl/r/rpl_stm_loadfile.result:
        error message changed
      mysql-test/suite/rpl/r/rpl_temporary_errors.result:
        updated result file
      mysql-test/suite/rpl/r/rpl_udf.result:
        Remove explicit set of binlog format (and triplicate test execution)
        and rely on test system executing the test in all binlog formats.
      mysql-test/suite/rpl/t/rpl_bug31076.test:
        Test is only valid in mixed or row mode since it generates row events.
      mysql-test/suite/rpl/t/rpl_events.test:
        Removed explicit set of binlog_format and removed duplicate testing.
        Instead, we rely on the test system to try all binlog formats.
      mysql-test/suite/rpl/t/rpl_extraColmaster_innodb.test:
        Removed triplicate testing and instead relying on test system.
        Test is only relevant for row format since statement-based replication
        cannot handle extra columns on master.
      mysql-test/suite/rpl/t/rpl_extraColmaster_myisam.test:
        Removed triplicate testing and instead relying on test system.
        Test is only relevant for row format since statement-based replication
        cannot handle extra columns on master.
      mysql-test/suite/rpl/t/rpl_idempotency-slave.opt:
        Removed .opt file to avoid server restarts.
      mysql-test/suite/rpl/t/rpl_idempotency.test:
        - Moved out row-only tests to a new test file, rpl_row_idempotency.test.
          rpl_idempotency now only contains tests that execute in all
          binlog_formats.
        - While I was here, also removed .opt file to avoid server restarts.
          The slave_exec_mode is now set inside the test instead.
      mysql-test/suite/rpl/t/rpl_mix_found_rows.test:
        Split rpl_found_rows.test into rpl_mix_found_rows.test (a new file) and
        rpl_stm_found_rows.test (renamed rpl_found_rows.test). This file
        contains the second half of the original rpl_found_rows.test with the
        follwing changes:
         - initialization
         - removed SET_BINLOG_FORMAT and added have_binlog_format_mixed.inc
         - minor formatting changes
      mysql-test/suite/rpl/t/rpl_mix_insert_delayed.test:
        Moved out code operating in mixed mode from rpl_stm_insert_delayed
        (into rpl_mix_insert_delayed) and got rid of explicit setting of
        binlog format.
      mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test:
        Test cannot execute in statement mode, since we no longer
        switch to row format when binlog_format=statement.
        Enforced mixed mode throughout the test.
      mysql-test/suite/rpl/t/rpl_row_idempotency.test:
        Moved the second half of rpl_idempotency.test, which only
        executed in row mode, to this new file. We now rely on the
        test system to set binlog format.
      mysql-test/suite/rpl/t/rpl_row_insert_delayed.test:
         - Got rid of unnecessary explicit setting of binlog format.
         - extra/rpl_tests/rpl_insert_delayed.test does not need the
           $binlog_format_statement variable any more, so that was
           removed.
      mysql-test/suite/rpl/t/rpl_slave_skip.test:
        The test switches binlog_format internally and master generates both
        row and statement events. Hence, the slave must be able to log in both
        statement and row format. Hence test was changed to only execute in
        mixed mode.
      mysql-test/suite/rpl/t/rpl_stm_found_rows.test:
        Split rpl_found_rows.test into rpl_mix_found_rows.test (a new file) and
        rpl_stm_found_rows.test (renamed rpl_found_rows.test). Changes in
        this file:
         - minor formatting changes
         - added have_binlog_format_statement and removed SET BINLOG_FORMAT.
         - second half of file is moved to rpl_mix_found_rows.test
         - added cleanup code
      mysql-test/suite/rpl/t/rpl_stm_insert_delayed.test:
        Moved out code operating in mixed mode from rpl_stm_insert_delayed
        (into rpl_mix_insert_delayed) and got rid of explicit setting of
        binlog format.
      mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test:
        The test switches binlog_format internally and master generates both
        row and statement events. Hence, the slave must be able to log in both
        statement and row format. Hence test was changed to only execute in
        mixed mode on slave.
      mysql-test/suite/rpl/t/rpl_temporary_errors.test:
        Removed explicit set of binlog format. Instead, the test now only
        executes in row mode.
      mysql-test/suite/rpl/t/rpl_udf.test:
        Remove explicit set of binlog format (and triplicate test execution)
        and rely on test system executing the test in all binlog formats.
      mysql-test/suite/rpl_ndb/combinations:
        Added combinations file for rpl_ndb.
      mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result:
        new result file
      mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result:
        updated result file
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2myisam.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors-master.opt:
        new option file
      mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors-slave.opt:
        new option file
      mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test:
        New test case to verify all errors and warnings generated by
        decide_logging_format.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_blob.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_blob2.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
        While I was here, also made the test clean up after itself.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_commit_afterflush.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_ctype_ucs2_def.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_delete_nowhere.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_do_db.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_do_table.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_func003.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_insert_ignore.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_update3.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_rep_ignore.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_row_001.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_sp003.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_sp006.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/suite/rpl_ndb/t/rpl_ndb_trig004.test:
        The test needs slave to be able to switch to row mode, so the
        test was changed to only execute in mixed and row mode.
      mysql-test/t/partition_innodb_stmt.test:
        Changed error code for innodb updates with READ COMMITTED or 
        READ UNCOMMITTED transaction isolation level and
        binlog_format=statement.
      sql/event_db_repository.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/events.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/ha_ndbcluster_binlog.cc:
        reset_current_stmt_binlog_row_based() is not a no-op for the ndb_binlog
        thread any more. Instead, the ndb_binlog thread now forces row mode both
        initially and just after calling mysql_parse.  (mysql_parse() is the only
        place where reset_current_stmt_binlog_row_based() may be called from
        the ndb_binlog thread, so these are the only two places that need to
        change.)
      sql/ha_partition.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/handler.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/item_create.cc:
        Added DBUG_ENTER to some functions, to be able to trace when
        set_stmt_unsafe is called.
      sql/log.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/log_event.cc:
         - Moved logic for changing to row format out of do_apply_event (and into
           decide_logging_format).
         - Added @todo comment for post-push cleanup.
      sql/log_event_old.cc:
        Move logic for changing to row format out of do_apply_event (and into
        decide_logging_format).
      sql/mysql_priv.h:
        Make decide_logging_format() a member of the THD class, for two reasons:
         - It is natural from an object-oriented perspective.
         - decide_logging_format() needs to access private members of THD
           (specifically, the new binlog_warning_flags field).
      sql/rpl_injector.cc:
        Removed call to set_current_stmt_binlog_row_based().
        From now on, only decide_logging_fromat is allowed to modify
        current_stmt_binlog_row_based. This call is from the ndb_binlog
        thread, mostly executing code in ha_ndbcluster_binlog.cc.
        This call can be safely removed, because:
         - current_stmt_binlog_row_based is initialized for the ndb_binlog
           thread's THD object when the THD object is created. So we're
           not going to read uninitialized memory.
         - The behavior of ndb_binlog thread does not use the state of the
           current_stmt_binlog_row_based. It is conceivable that the
           ndb_binlog thread would rely on the current_stmt_binlog_format
           in two situations:
            (1) when it calls mysql_parse;
            (2) when it calls THD::binlog_query.
           In case (1), it always clears THD::options&OPTION_BIN_LOG (because
           run_query() in ha_ndbcluster_binlog.cc is only called with
           disable_binlogging = TRUE).
           In case (2), it always uses qtype=STMT_QUERY_TYPE.
      sql/set_var.cc:
        Added @todo comment for post-push cleanup.
      sql/share/errmsg.txt:
        Added new error messages and clarified ER_BINLOG_UNSAFE_STATEMENT.
      sql/sp.cc:
        Added DBUG_ENTER, to be able to trace when set_stmt_unsafe is called.
        Got rid of MYSQL_QUERY_TYPE: it was equivalent to STMT_QUERY_TYPE.
      sql/sp_head.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/sp_head.h:
        Added DBUG_ENTER, to be able to trace when set_stmt_unsafe is called.
      sql/sql_acl.cc:
        Got rid of MYSQL_QUERY_TYPE: it was equivalent to STMT_QUERY_TYPE.
      sql/sql_base.cc:
         - Made decide_logging_format take care of all logic for deciding the
           logging format, and for determining the related warnings and errors.
           See comment above decide_logging_format for details.
         - Made decide_logging_format a member function of THD, since it needs
           to access private members of THD and since its purpose is to update
           the state of a THD object.
         - Added DBUG_ENTER, to be able to trace when set_stmt_unsafe is called.
      sql/sql_class.cc:
        - Moved logic for determining unsafe warnings away from THD::binlog_query
          (and into decide_logging_format()). Now, it works like this:
          1. decide_logging_format detects that the current statement shall
             produce a warning, if it ever makes it to the binlog
          2. decide_logging_format sets a flag of THD::binlog_warning_flags.
          3. THD::binlog_query reads the flag. If the flag is set, it generates
             a warning.
        - Use member function to read current_stmt_binlog_row_based.
      sql/sql_class.h:
        - Added THD::binlog_warning_flags (see sql_class.cc for explanation).
        - Made decide_logging_format() and reset_for_next_command() member
          functions of THD (instead of standalone functions). This was needed
          for two reasons: (1) the functions need to access the private member
          THD::binlog_warning_flags; (2) the purpose of these functions is to
          update the staet of a THD object, so from an object-oriented point
          of view they should be member functions.
        - Encapsulated current_stmt_binlog_row_based, so it is now private and
          can only be accessed from a member function. Also changed the
          data type to an enumeration instead of a bool.
        - Removed MYSQL_QUERY_TYPE, because it was equivalent to
          STMT_QUERY_TYPE anyways.
        - When reset_current_stmt_binlog_row_based was called from the
          ndb_binlog thread, it would behave as a no-op. This special
          case has been removed, and the behavior of
          reset_current_stmt_binlog_row_based does not depend on which thread
          calls it any more. The special case did not serve any purpose,
          since the ndb binlog thread did not take the
          current_stmt_binlog_row_based flag into account anyways.
      sql/sql_delete.cc:
        - Moved logic for setting row format for DELETE..LIMIT away from
          mysql_prepare_delete.
          (Instead, we mark the statement as unsafe at parse time (sql_yacc.yy)
          and rely on decide_logging_format() (sql_class.cc) to set row format.)
          This is part of the fix for BUG#45831.
        - Use member function to read current_stmt_binlog_row_based.
      sql/sql_insert.cc:
         - Removed unnecessary calls to thd->lex->set_stmt_unsafe() and
           thd->set_current_stmt_binlog_row_based_if_mixed() from
           handle_delayed_insert(). The calls are unnecessary because they
           have already been made; they were made in the constructor of
           the `di' object.
         - Since decide_logging_format() is now a member function of THD, code
           that calls decide_logging_format() had to be updated.
         - Added DBUG_ENTER call, to be able to trace when set_stmt_unsafe is
           called.
         - Moved call to set_stmt_unsafe() for INSERT..SELECT..LIMIT away from
           mysql_insert_select_prepare() (and into decide_logging_format).
           This is part of the fix for BUG#45831.
         - Use member function to read current_stmt_binlog_row_based.
      sql/sql_lex.h:
         - Added the flag BINLOG_STMT_FLAG_ROW_INJECTION to enum_binlog_stmt_flag.
           This was necessary so that a statement can identify itself as a row
           injection.
         - Added appropriate setter and getter functions for the new flag.
         - Added or clarified some comments.
         - Added DBUG_ENTER()
      sql/sql_load.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/sql_parse.cc:
         - Made mysql_reset_thd_for_next_command() clear thd->binlog_warning_flags.
         - Since thd->binlog_warning_flags is private, it must be set in a
           member function of THD. Hence, moved the body of
           mysql_reset_thd_for_next_command() to the new member function
           THD::reset_thd_for_next_command(), and made
           mysql_reset_thd_for_next_command() call
           THD::reset_thd_for_next_command().
         - Removed confusing comment.
         - Use member function to read current_stmt_binlog_row_based.
      sql/sql_repl.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/sql_table.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/sql_udf.cc:
        Use member function to read current_stmt_binlog_row_based.
      sql/sql_update.cc:
        Moved logic for setting row format for UPDATE..LIMIT away from
        mysql_prepare_update.
        (Instead, we mark the statement as unsafe at parse time (sql_yacc.yy)
        and rely on decide_logging_format() (sql_class.cc) to set row format.)
        This is part of the fix for BUG#45831.
      sql/sql_yacc.yy:
        Made INSERT DELAYED, INSERT..SELECT..LIMIT, UPDATE..LIMIT, and
        DELETE..LIMIT mark themselves as unsafe at parse time (instead
        of at execution time).
        This is part of the fixes BUG#45831 and BUG#45825.
      storage/example/ha_example.cc:
        Made exampledb accept inserts. This was needed by the new test case
        rpl_ndb_binlog_format_errors, because it needs an engine that
        is statement-only (and accepts inserts).
      storage/example/ha_example.h:
        Made exampledb a statement-only engine instead of a row-only engine.
        No existing test relied exampledb's row-only capabilities. The new
        test case rpl_ndb_binlog_format_errors needs an engine that is
        statement-only.
      storage/innobase/handler/ha_innodb.cc:
        - Changed error error code and message given by innodb when 
          binlog_format=STATEMENT and transaction isolation level is
          READ COMMITTED or READ UNCOMMITTED.
        - While I was here, also simplified the condition for
          checking when to give the error.
      41783de5
  2. 15 Jun, 2009 5 commits
    • Staale Smedseng's avatar
      Bug #45387 Information about statement id for prepared · 37a5f2d4
      Staale Smedseng authored
      statements missed from general log
      
      A FLUSH LOGS is added to ensure that the log info hits
      the file before attempting to process.
      
      mysql-test/t/log_tables_debug.test:
        A FLUSH LOGS is added, and in the event that a match is
        not found, <FILE> is reset and the contents of the log
        file is dumped for debugging purposes.
      37a5f2d4
    • Bernt M. Johnsen's avatar
      nullmerge · 32b63110
      Bernt M. Johnsen authored
      32b63110
    • Bernt M. Johnsen's avatar
      d6a9e61c
    • Georgi Kodinov's avatar
      automerge · f2646970
      Georgi Kodinov authored
      f2646970
    • Georgi Kodinov's avatar
      Bug #44810: index merge and order by with low sort_buffer_size · 6df6c8ee
      Georgi Kodinov authored
      crashes server!
      
      The problem affects the scenario when index merge is followed by a filesort
      and the sort buffer is not big enough for all the sort keys.
      In this case the filesort function will read the data to the end through the 
      index merge quick access method (and thus closing the cursor etc), 
      but will leave the pointer to the quick select method in place.
      It will then create a temporary file to hold the results of the filesort and
      will add it as a sort output file (in sort.io_cache).
      Note that filesort will copy the original 'sort' structure in an automatic
      variable and restore it after it's done.
      As a result at exiting filesort() we have a sort.io_cache filled in and 
      nothing else (as a result of close of the cursors at end of reading data 
      through index merge).
      Now create_sort_index() will note that there is a select and will clean it up
      (as it's been used already by filesort() reading the data in). While doing that
      a special case in the index merge destructor will clean up the sort.io_cache,
      assuming it's an output of the index merge method and is not needed anymore.
      As a result the code that tries to read the data back from the filesort output 
      will get no data in both memory and disk and will crash.
            
      Fixed similarly to how filesort() does it : by copying the sort.io_cache structure
      to a local variable, removing the pointer to the io_cache (so that it's not freed 
      by QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT) and restoring the original 
      structure (together with the valid pointer) after the cleanup is done.
      This is a safe thing to do because all the structures are already cleaned up by
      hitting the end of the index merge's read method (QUICK_INDEX_MERGE_SELECT::get_next()) 
      and the cleanup code being written in a way that tolerates repeating cleanups.
      
      mysql-test/r/index_merge.result:
        Bug #44810: test case
      mysql-test/t/index_merge.test:
        Bug #44810: test case
      sql/sql_select.cc:
        Bug #44810: preserve the io_cache produced by filesort while cleaning up
        the index merge quick access method (QUICK_INDEX_MERGE_SELECT).
      6df6c8ee
  3. 12 Jun, 2009 8 commits
    • Davi Arnaut's avatar
      Bug#45100: Incomplete DROP USER in case of SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH' · 66398a87
      Davi Arnaut authored
      The SQL-mode PAD_CHAR_TO_FULL_LENGTH could prevent a DROP USER
      statement from privileges associated with the user being dropped.
      What ocurred was that reading from the User and Host fields of
      the tables tables_priv or columns_priv would yield values padded
      with spaces, causing a failure to match a specified user or host 
      ('user' != 'user     ');
      
      The solution is to disregard the PAD_CHAR_TO_FULL_LENGTH mode
      when iterating over and matching values in the privileges tables
      for a DROP USER statement.
      
      mysql-test/r/sql_mode.result:
        Add test case result for Bug#45100.
      mysql-test/t/sql_mode.test:
        Add test case for Bug#45100.
      sql/sql_acl.cc:
        Clear MODE_PAD_CHAR_TO_FULL_LENGTH before dropping privileges.
      66398a87
    • Staale Smedseng's avatar
      Bug #45387 Information about statement id for prepared · 35cf6632
      Staale Smedseng authored
      statements missed from general log
      
      A refinement of the test in the previous patch to avoid
      using sleep as a means to ensure that timestamps are
      added to the log entries.
      
      mysql-test/t/log_tables_debug.test:
        New test file. A debug feature is used to ensure that
        log entries are prefixed with a timestamp.
      sql/log.cc:
        A debug feature is implemented to ensure that
        log entries are prefixed with a timestamp.
      35cf6632
    • Georgi Kodinov's avatar
      automerge · c4930f35
      Georgi Kodinov authored
      c4930f35
    • Georgi Kodinov's avatar
      fixed the build-tags command · dfb06c38
      Georgi Kodinov authored
      dfb06c38
    • Georgi Kodinov's avatar
      automerge · ed112a80
      Georgi Kodinov authored
      ed112a80
    • Georgi Kodinov's avatar
      automerge · 4228f437
      Georgi Kodinov authored
      4228f437
    • Patrick Crews's avatar
      Bug#44920: MTR2 is not processing master.opt input properly on Windows · 62a32540
      Patrick Crews authored
      Re-enabled tests main.init_connect and rpl.rpl_init_slave.test for non-Windows
      platforms.
      
      Please remove this code upon fixing the bug.
      62a32540
    • Georgi Kodinov's avatar
      Bug #45386: Wrong query result with MIN function in field list, · 3e82a86e
      Georgi Kodinov authored
      WHERE and GROUP BY clause
      
      Loose index scan may use range conditions on the argument of 
      the MIN/MAX aggregate functions to find the beginning/end of 
      the interval that satisfies the range conditions in a single go.
      These range conditions may have open or closed minimum/maximum 
      values. When the comparison returns 0 (equal) the code should 
      check the type of the min/max values of the current interval 
      and accept or reject the row based on whether the limit is 
      open or not.
      There was a wrong composite condition on checking this and it was
      not working in all cases.
      Fixed by simplifying the conditions and reversing the logic.
      
      mysql-test/r/group_min_max.result:
        Bug #45386: test case
      mysql-test/t/group_min_max.test:
        Bug #45386: test case
      sql/opt_range.cc:
        Bug #45386: fix the check whether to use the value if on the
        interval boundry
      3e82a86e
  4. 10 Jun, 2009 3 commits
    • Davi Arnaut's avatar
      Merge from mysql-5.0-bugteam. · eac6619f
      Davi Arnaut authored
      eac6619f
    • Davi Arnaut's avatar
      Bug#41190: shared memory connections do not work in Vista, if server started from cmdline · afacea4d
      Davi Arnaut authored
      Backport to MySQL 5.0/1 fix by Vladislav Vaintroub:
      
      In Vista and later and also in when using terminal services, when
      server is started from  command line, client cannot connect to it
      via shared memory protocol.
      
      This is a regression introduced when  Bug#24731 was fixed.  The
      reason is that client is trying to attach to shared memory using
      global kernel object  namespace (all kernel objects are prefixed
      with Global\). However, server started from the command line in
      Vista and later will create shared memory and events using current
      session namespace. Thus, client is unable to find the server and
      connection fails.
      
      The fix for the client is to first try to find server using "local"
      names  (omitting Global\  prefix) and only if server is not found,
      trying global namespace.
      afacea4d
    • Philip Stoev's avatar
      Bug #29971 status.test fails · d98dee2c
      Philip Stoev authored
      This test uses SHOW STATUS and the like, which may be unstable in the face
      of logging to table, since the CSV handler is actively executing operations
      and thus incrementing the counters.
      
      Fixed by disabling logging to table for the duration of the test and restoring
      it afterwards. This causes various counters to properly start counting from zero
      and never advance due to CSV operations.
      d98dee2c
  5. 09 Jun, 2009 8 commits
  6. 08 Jun, 2009 5 commits
  7. 07 Jun, 2009 1 commit
    • Gleb Shchepa's avatar
      Bug #44886: SIGSEGV in test_if_skip_sort_order() - · ed7f0f30
      Gleb Shchepa authored
                  uninitialized variable used as subscript
      
      Grouping select from a "constant" InnoDB table (a table
      of a single row) joined with other tables caused a crash.
      
      
      mysql-test/r/innodb_mysql.result:
        Added test case for bug bug #44886.
      mysql-test/t/innodb_mysql.test:
        Added test case for bug bug #44886.
      sql/sql_select.cc:
        Bug #44886: SIGSEGV in test_if_skip_sort_order() -
                    uninitialized variable used as subscript
        
        1. The test_if_order_by_key function returned unitialized
           used_key_parts parameter in case of a "constant" InnoDB
           table. Calling function uses this parameter values as
           an array index, thus sometimes it caused a crash.
           The test_if_order_by_key function has been modified
           to set used_key_parts to 0 (no need for ordering).
        
        2. The test_if_skip_sort_order function has been
           modified to accept zero used_key_parts value and
           to prevent an array access by negative index.
      ed7f0f30
  8. 06 Jun, 2009 7 commits
  9. 05 Jun, 2009 2 commits
    • Davi Arnaut's avatar
      Bug#44672: Assertion failed: thd->transaction.xid_state.xid.is_null() · 12f91b1d
      Davi Arnaut authored
      The problem is that when a optimization of read-only transactions
      (bypass 2-phase commit) was implemented, it removed the code that
      reseted the XID once a transaction wasn't active anymore:
      
      sql/sql_parse.cc:
      
      -  bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
      -  if (!thd->active_transaction())
      -    thd->transaction.xid_state.xid.null();
      +  thd->transaction.stmt.reset();
      
      This mostly worked fine as the transaction commit and rollback
      functions (in handler.cc) reset the XID once the transaction is
      ended. But those functions wouldn't reset the XID in case of
      a empty transaction, leading to a assertion when a new starting
      a new XA transaction.
      
      The solution is to ensure that the XID state is reset when empty
      transactions are ended (by either commit or rollback). This is
      achieved by reorganizing the code so that the transaction cleanup
      routine is invoked whenever a transaction is ended.
      
      mysql-test/r/xa.result:
        Add test case result for Bug#44672
      mysql-test/t/xa.test:
        Add test case for Bug#44672
      sql/handler.cc:
        Invoke transaction cleanup function whenever a transaction is
        ended. Move XID state reset logic to the transaction cleanup
        function.
      sql/sql_class.h:
        Add XID state reset logic.
      12f91b1d
    • Tatiana A. Nurnberg's avatar
      automerge · 56ae4a7f
      Tatiana A. Nurnberg authored
      56ae4a7f