Bug #39934 Slave stops for engine that only support row-based logging
Submitted: 8 Oct 2008 14:19 Modified: 4 Aug 2010 23:22
Reporter: Mats Kindahl Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S2 (Serious)
Version:5.1.29-rc,6.0 OS:Any
Assigned to: Sven Sandberg CPU Architecture:Any

[8 Oct 2008 14:19] Mats Kindahl
Description:
For an engine that only supports row-based replication, like Falcon, replication stops with an error when executing rows events.

How to repeat:
master> set binlog_format=row;
master> create table t1 (a int) engine = falcon;
master> insert into t1 values (1);

slave> show slave status;

Suggested fix:
Do not perform the checks for engine capabilities when executing a rows event (usually from the slave thread, but it can be executed as a BINLOG statement as well).
[8 Oct 2008 19:42] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/55811

2862 Mats Kindahl	2008-10-08
      Bug #39934:
      Slave stops for engine that only support row-based logging
      
      Since the SQL slave thread is running under STATEMENT mode,
      this prevents the slave from switching to row-based format
      when necessary.
      
      This patches solve the situation by always setting the SQL
      thread in MIXED mode, regardless of what the default is.
[13 Oct 2008 12:52] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/56119

2771 Mats Kindahl	2008-10-13
      Bug #39934: Slave stops for engine that only support row-based logging
      
      The slave SQL thread is now executing in STATEMENT mode, meaning that 
      for engines that do not support statement-based replication, it will 
      not be possible to switch to row-format.
      
      If a Rows_log_event arrives to the slave with rows to apply, lock_tables()
      will be executed which in turn will call lock_tables() to open the tables
      to feed the rows into.
      
      For engines that does not support statement-based replication, the slave
      will stop with an error message since it is not possible to switch to 
      row format. However, since this use is supposed to feed rows into the
      table, there should be no problems in executing this event.
      
      Bug is fixed by extending lock_tables() and friends with an extra parameter
      check_caps that will check capabilities if TRUE, and not otherwise. The 
      parameter is then set to FALSE for all calls from inside Rows_log_event
      (and the old version of the same), and subclasses.
      
      Bug is reported for 6.0 but is present in 5.1 as well, so patch is submitted
      for 5.1 but will be extended when merged to 6.0.
[15 Oct 2008 10:23] Sven Sandberg
I suggest the following.

==== Design ====

Let's set up a decision diagram on the expected behavior. There are
three parameters affecting how statements are logged: "engine
combination", "statement type", and "logging mode".

 - There are four types of engine combinations:
         ANY: all support RBL, all support SBL
         ROW: all support RBL, not all support SBL
   STATEMENT: not all support RBL, all support SBL
       ERROR: not all support RBL, not all support SBL

 - There are three statement types:
        SAFE: e.g., "INSERT INTO t1 (1)"
      UNSAFE: e.g., "INSERT INTO t1 (@@server_id)"
        ROW: pseudo-queries that inject rows ("BINLOG 'blahblah'" and row
             events in the sql thread).

   <parenthesis>
     There are actually two more query types:
          DDL: e.g., "CREATE TABLE". Always logged as statement,
               no warning.
     UNLOGGED: e.g., "INSTALL PLUGIN". Never logged, no warning.

     I'm ignoring them in this discussion because the behavior is
     independent of the other parameters. Nothing to discuss there.

     For this dicusssion, CREATE...SELECT counts as one DDL followed
     by one SAFE/UNSAFE statement (depending on the safeness of the
     SELECT).
   </parenthesis>

 - Finally, there are three well-known types of logging modes:
   STATEMENT, MIXED, and ROW.

The three types of statements behave as described by the following
decision table:

     engine combo:  AAA AAA AAA   RRR RRR RRR   SSS SSS SSS   E
   statement type:  SSS UUU RRR   SSS UUU RRR   SSS UUU RRR   *
     logging mode:  SMR SMR SMR   SMR SMR SMR   SMR SMR SMR   *
  ==============================================================
           logged:  SSR SRR RRR   RRR RRR RRR   SSS SSS ---   -
    error/warning:      1   2     3   3   2       4 554 666   7
         footnote:          1     1   2   3       1  11

Errors and warnings:

 1 - Warning: Unsafe statement logged as statement due to
     binlog_format = STATEMENT

 2 - Warning: Row injection logged as row, despite binlog_format =
     STATEMENT

 3 - Warning: Statement logged as row due to limited engine
     capabilities, despite binlog_format = STATEMENT

 4 - Warning: Statement logged as statement due to limited engine
     capabilities, despite binlog_format = ROW

 5 - Warning: Unsafe statement logged as statement due to limited
     engine capabilities

 6 - Error: Unable to binlog row-injection since engine is not capable
     of row-logging

 7 - Error: Unable to binlog statement since both row-incapable
     engines and statement-incapable engines are involved.

Footnotes:

 1 - Currently no warning here.

 2 - Currently, we give a warning that the statement is unsafe and
     will be logged in statement mode. This is incorrect, we should
     give warning 3.

 3 - This is where BUG#39934 produces an error in the SQL thread.
     Currently no warning here.

==== Implementation ====

I think the above logic can and should be contained in
decide_logging_format() in sql_base.cc. That means:

 - In [Old_]Rows_log_event::do_apply_event, there is a temporary
   switch to row mode (thd->set_current_stmt_binlog_row_based()). That
   should go away in both places. Instead, there should be a flag in
   the thread saying that the statement is a ROW statement. It could
   possibly be implemented as a third value for the "unsafe" flag.

 - The warning for unsafe statements in STATEMENT mode is currently
   generated in binlog_query(). I think it should be moved to
   decide_binlog_format().

   Note: need to check if that gives a spurious warning if the
   statement is rolled back and unlogged (e.g., due to duplicate key
   error). In that case, I still think the warning text should be
   determined in decide_binlog_format(), but saved in a buffer until
   it is determined that something is written to the log.

 - There is currently an unrelated bug in decide_binlog_format() which
   should be fixed while refactoring it.  The statement

     if (flags_all_set == 0)

   should be replaced by

     if ((flags_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0)

   With the current code, the condition will not be true if
   HA_BINLOG_STMT_CAPABLE and HA_BINLOG_ROW_CAPABLE are both 0 but
   some other flag is set.

 - decide_binlog_format() can be implemented as follows:

   if (engine_combo = E)
     error 7
     return -1
   elif (engine_combo = S)
     if (statement_type = R)
       error 6
       return -1
     elif (binlog_format = R)
       warning 4
     elif (statement_type = U)
       warning 5
     log_format = S
   elif (statement_type = R)
     if (binlog_format = S)
       warning 2
     log_format = R
   elif (engine_combo = R)
     if (binlog_format = S)
       warning 3
     log_format = R
   else // engine_combo = A and statement_type = [S | U]
     if (statement_type = U && binlog_format = S)
       warning 1
     if (binlog_format = R || (statement_type = U && binlog_format = M))
       log_format = R
     else
       log_format = S
   endif
[15 Oct 2008 14:25] Sven Sandberg
After discussing with Mats, we agreed to change the above design and
follow the principle to never log in statement format if binlog_format
= STATEMENT and never log in row format in binlog_format = ROW.

That changes the decision table to the following.

     engine combo:  AAA AAA AAA   RRR RRR RRR   SSS SSS SSS   E
   statement type:  SSS UUU RRR   SSS UUU RRR   SSS UUU RRR   *
     logging mode:  SMR SMR SMR   SMR SMR SMR   SMR SMR SMR   *
  ==============================================================
           logged:  SSR SRR -RR   -RR -RR -RR   SS- SS- ---   -
    error/warning:      1   2     3   3   2       4 554 666   7

Errors and warnings:

 1 - Warning: Unsafe statement logged as statement due to
     binlog_format = STATEMENT

 2 - Error: Cannot execute row injection since binlog_format =
     STATEMENT

 3 - Error: Cannot modify table that uses a storage engine limited to
     row-logging when binlog_format = STATEMENT

 4 - Error: Cannot modify table that uses a storage engine limited to
     statement-logging when binlog_format = ROW

 5 - Warning: Unsafe statement logged as statement since storage
     engine is limited to statement-logging.

 6 - Error: Cannot inject row in table that uses a storage engine
     limited to statement-logging

 7 - Error: Unable to binlog statement since both row-incapable
     engines and statement-incapable engines are involved.
[15 Oct 2008 16:13] Sven Sandberg
The above also implies that, if slave runs with binlog_format=STATEMENT and receives a row event from master, it is expected that the slave stops with an error. Hence, this is just a problem with error messages. Lowering severity.

(It's also a problem with a test case, but that has already been fixed and pushed to 5.1-5.1.29-rc)
[21 Oct 2008 20:35] Ann Harrison
In addition to slave.cc, there was a change to mysqld.cc around line 4025.
Last week the code looked like this:

  if (!opt_bin_log)
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
  {
    sql_print_error("You need to use --log-bin to make "
                    "--binlog-format work.");
    unireg_abort(1);
  }
    else
  {
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
    }
  else
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;

This week it looks like this:

  if (!opt_bin_log)
  {
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
    {
      sql_print_error("You need to use --log-bin to make "
                      "--binlog-format work.");
      unireg_abort(1);
    }
    else
    {
      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
    }
  }
  else
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
    else

And of course, Falcon stopped working.
[17 Nov 2008 10:35] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58932

2771 Mats Kindahl	2008-11-17
      Bug#39934: Slave stops for engine that only support row-based logging
      
      It was possible to get a row-based event in the binary log on the slave
      even if the slave is running in STATEMENT mode. 
      
      This patch clarifies the rules for what format the slave can log in and
      under what circumstances as well as adding some missing error messages
      and clarifying some other.
[17 Dec 2008 22:27] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/61921

2771 Mats Kindahl	2008-12-17
      Bug#39934: Slave stops for engine that only support row-based logging
      
      It was possible to get a row-based event in the binary log on the slave
      even if the slave is running in STATEMENT mode. 
      
      This patch clarifies the rules for what format the slave can log in and
      under what circumstances as well as adding some missing error messages
      and clarifying some other.
[30 Jun 2009 14:47] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/77544
[9 Jul 2009 18:36] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78305
[10 Jul 2009 9:10] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78356
[13 Jul 2009 13:39] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78538
[13 Jul 2009 18:39] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78568
[13 Jul 2009 18:51] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78569
[13 Jul 2009 20:33] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78592
[14 Jul 2009 17:28] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78678
[14 Jul 2009 19:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78681
[14 Jul 2009 19:38] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78684
[14 Jul 2009 20:37] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78689
[14 Jul 2009 20:40] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78690
[15 Jul 2009 17:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78758

3026 Sven Sandberg	2009-07-15
      post-push fixes for BUG#39934: make mysqldump.test pass even
      with binlog_format = MIXED or ROW.
     @ mysql-test/r/mysqldump.result
        Remove warning from result file.
     @ mysql-test/t/mysqldump.test
        The test gives a warning if binlog_format=STATEMENT due to
        BUG#45832. To make the result file not depend on binlog_format,
        we disable warnings.
[15 Jul 2009 17:48] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/78765

3025 Sven Sandberg	2009-07-15
      post-push fixes for BUG#39934: updating test cases
     @ mysql-test/r/partition_innodb_stmt.result
        Error message changed.
     @ mysql-test/r/sp_trans.result
        Error message changed.
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        Error message changed.
     @ mysql-test/suite/binlog/t/binlog_unsafe.test
        Test now uses udf's, so needs to source include/have_udf.inc
     @ mysql-test/suite/parts/r/rpl_partition.result
        updated result file
     @ mysql-test/suite/parts/t/rpl_partition.test
        We no longer allow a slave that has binlog_format=statement
        to execute row events. Hence we force the slave to have
        binlog_format=row.
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
        The test uses the example plugin, hence it must
        source include/have_example_plugin.inc.
[23 Jul 2009 12:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/79169

3029 Sven Sandberg	2009-07-22
      Post-push fixes for BUG#39934
      Suppress warnings if binlog_format=STATEMENT and the current
      database is filtered out using --binlog-[do|ignore]-db. This
      was a regression in my previous patch.
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        updated result file
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        updated result file
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors-master.opt
        Added binlog filtering rule.
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
        Added tests that no error is printed when table is filtered out
        by binlog filtering rules.
     @ sql/sql_class.cc
        Don't decide logging format if the statement is filtered out
        from the binlog using binlog filtering rules.
[23 Jul 2009 12:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/79170

3027 Sven Sandberg	2009-07-22
      BUG#39934: Slave stops for engine that only support row-based logging
      This is a post-push fix addressing review requests and
      problems with extra warnings.
      
      Problem 1: The sub-statement where an unsafe warning was detected was
      printed as part of the warning. This was ok for statements that
      were unsafe due to, e.g., calls to UUID(), but did not make
      sense for statements that were unsafe because there was more than
      one autoincrement column (unsafeness in this case comes from the
      combination of several sub-statements).
      Fix 1: Instead of printing the sub-statement, print an explanation
      of why the statement is unsafe.
      
      Problem 2:
      When a recursive construct (i.e., stored proceure, stored
      function, trigger, view, prepared statement) contained several
      sub-statements, and at least one of them was unsafe, there would be
      one unsafeness warning per sub-statement - even for safe
      sub-statements.
      Fix 2:
      Ensure that each type of warning is printed at most once, by
      remembering throughout the execution of the statement which types
      of warnings have been printed.
     @ mysql-test/extra/rpl_tests/create_recursive_construct.inc
        - Clarified comment per review request.
        - Added checks for the number of warnings in each invocation.
     @ mysql-test/extra/rpl_tests/rpl_insert_delayed.test
        Per review request, replaced @@session.binlog_format by
        @@global.binlog_format, since INSERT DELAYED reads the global
        variable. (In this test case, the two variables have the same
        value, so the change is cosmetic.)
     @ mysql-test/r/sp_trans.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_ps.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_unsafe.result
        Updated result file. Note that duplicate warnings are now gone.
     @ mysql-test/suite/binlog/t/binlog_unsafe.test
        - Added tests for: (1) a statement that is unsafe in many ways;
          (2) a statement that is unsafe in the same way several times.
        - Use -- style to invoke mysqltest commands.
     @ mysql-test/suite/rpl/r/rpl_stm_found_rows.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_loadfile.result
        updated result file
     @ mysql-test/suite/rpl/t/rpl_mix_found_rows.test
        Per review request, added comment explaining what the test case
        does (copied from rpl_stm_found_rows.test)
     @ mysql-test/suite/rpl/t/rpl_stm_found_rows.test
        Clarified grammar in comment.
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        Updated result file.
     @ sql/item_create.cc
        Made set_stmt_unsafe take one parameter, describing the
        type of unsafeness.
     @ sql/sp_head.cc
        Added unsafe_flags field and made it hold all the unsafe flags.
     @ sql/sp_head.h
        - Removed the BINLOG_ROW_BASED_IF_MIXED flag from m_flags.
          Instead, we use the new unsafe_flags field to hold the
          unsafeness state of the sp.
        - Made propagate_attributes() copy all unsafe flags.
     @ sql/sql_base.cc
        - Made LEX::set_stmt_unsafe() take an extra argument.
        - Made binlog_unsafe_warning_flags store the type of unsafeness.
        - Per review requests, clarified comments
        - Added DBUG printouts
     @ sql/sql_class.cc
        - Made warnings be generated in issue_warnings() and call that from
          binlog_query(). Wrote issue_warnings(), which prints zero or more
          warnings, avoiding to print warnings more than once per statement.
        - Per review request, added @todo so that we remember to assert
          correct behavior in binlog_query.
     @ sql/sql_class.h
        - Removed BINLOG_WARNING_PRINTED 
        - Use [set|clear]_current_stmt_binlog_row_based() instead of
          modifying the flag directly.
        - added issue_unsafe_warnings() (only called from binlog_unsafe)
        - Per review request, improved some documentation.
     @ sql/sql_insert.cc
        Added extra argument to LEX::set_stmt_unsafe()
     @ sql/sql_lex.h
        - Added enum_binlog_stmt_unsafe, listing all types of unsafe
          statements.
        - Per review requests, improved many comments for member
          functions.
        - Added [get|set]_stmt_unsafe_flags(), which return/set all the
          unsafe flags for a statement.
     @ sql/sql_parse.cc
        - Renamed binlog_warning_flags to binlog_unsafe_warning_flags.
        - Per review requests, improved comment.
     @ sql/sql_view.cc
        Made views propagate all the new unsafe flags.
     @ sql/sql_yacc.yy
        Added parameter to set_stmt_unsafe().
     @ storage/innobase/handler/ha_innodb.cc
        Per review requests, replaced DBUG_EXECUTE_IF() by DBUG_EVALUATE_IF().
[23 Jul 2009 12:23] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/79175

3028 Sven Sandberg	2009-07-22
      Post-push fix for BUG#39934
      Moved decide_logging_format to sql_class.cc
     @ sql/sql_base.cc
        Moved decide_logging_format to sql_class.cc
        The auxiliary macro FLAGSTR is not needed here any more.
     @ sql/sql_class.cc
        - Moved decide_logging_format from sql_base.cc to here.
        - To avoid copying the FLAGSTR macro, I changed some
          DBUG_PRINT to just print flags in hex. No need to
          pretty-print debug traces.
        - Changed the type of 'flags' to handler::Table_flags
          because that's the return type of handler::ha_table_flags.
[23 Jul 2009 12:24] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/79177

3027 Sven Sandberg	2009-07-22
      BUG#39934: Slave stops for engine that only support row-based logging
      This is a post-push fix addressing review requests and
      problems with extra warnings.
      
      Problem 1: The sub-statement where an unsafe warning was detected was
      printed as part of the warning. This was ok for statements that
      were unsafe due to, e.g., calls to UUID(), but did not make
      sense for statements that were unsafe because there was more than
      one autoincrement column (unsafeness in this case comes from the
      combination of several sub-statements).
      Fix 1: Instead of printing the sub-statement, print an explanation
      of why the statement is unsafe.
      
      Problem 2:
      When a recursive construct (i.e., stored proceure, stored
      function, trigger, view, prepared statement) contained several
      sub-statements, and at least one of them was unsafe, there would be
      one unsafeness warning per sub-statement - even for safe
      sub-statements.
      Fix 2:
      Ensure that each type of warning is printed at most once, by
      remembering throughout the execution of the statement which types
      of warnings have been printed.
     @ mysql-test/extra/rpl_tests/create_recursive_construct.inc
        - Clarified comment per review request.
        - Added checks for the number of warnings in each invocation.
     @ mysql-test/extra/rpl_tests/rpl_insert_delayed.test
        Per review request, replaced @@session.binlog_format by
        @@global.binlog_format, since INSERT DELAYED reads the global
        variable. (In this test case, the two variables have the same
        value, so the change is cosmetic.)
     @ mysql-test/suite/binlog/r/binlog_unsafe.result
        Updated result file. Note that duplicate warnings are now gone.
     @ mysql-test/suite/binlog/t/binlog_unsafe.test
        - Added tests for: (1) a statement that is unsafe in many ways;
          (2) a statement that is unsafe in the same way several times.
        - Use -- style to invoke mysqltest commands.
     @ mysql-test/suite/rpl/t/rpl_mix_found_rows.test
        Per review request, added comment explaining what the test case
        does (copied from rpl_stm_found_rows.test)
     @ mysql-test/suite/rpl/t/rpl_stm_found_rows.test
        Clarified grammar in comment.
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        Updated result file.
     @ sql/item_create.cc
        Made set_stmt_unsafe take one parameter, describing the
        type of unsafeness.
     @ sql/sp_head.cc
        Added unsafe_flags field and made it hold all the unsafe flags.
     @ sql/sp_head.h
        - Removed the BINLOG_ROW_BASED_IF_MIXED flag from m_flags.
          Instead, we use the new unsafe_flags field to hold the
          unsafeness state of the sp.
        - Made propagate_attributes() copy all unsafe flags.
     @ sql/sql_base.cc
        - Made LEX::set_stmt_unsafe() take an extra argument.
        - Made binlog_unsafe_warning_flags store the type of unsafeness.
        - Per review requests, clarified comments
        - Added DBUG printouts
     @ sql/sql_class.cc
        - Made warnings be generated in issue_warnings() and call that from
          binlog_query(). Wrote issue_warnings(), which prints zero or more
          warnings, avoiding to print warnings more than once per statement.
        - Per review request, added @todo so that we remember to assert
          correct behavior in binlog_query.
     @ sql/sql_class.h
        - Removed BINLOG_WARNING_PRINTED 
        - Use [set|clear]_current_stmt_binlog_row_based() instead of
          modifying the flag directly.
        - added issue_unsafe_warnings() (only called from binlog_unsafe)
        - Per review request, improved some documentation.
     @ sql/sql_insert.cc
        Added extra argument to LEX::set_stmt_unsafe()
     @ sql/sql_lex.h
        - Added enum_binlog_stmt_unsafe, listing all types of unsafe
          statements.
        - Per review requests, improved many comments for member
          functions.
        - Added [get|set]_stmt_unsafe_flags(), which return/set all the
          unsafe flags for a statement.
     @ sql/sql_parse.cc
        - Renamed binlog_warning_flags to binlog_unsafe_warning_flags.
        - Per review requests, improved comment.
     @ sql/sql_view.cc
        Made views propagate all the new unsafe flags.
     @ sql/sql_yacc.yy
        Added parameter to set_stmt_unsafe().
     @ storage/innobase/handler/ha_innodb.cc
        Per review requests, replaced DBUG_EXECUTE_IF() by DBUG_EVALUATE_IF().
[23 Jul 2009 12:25] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/79179

3027 Sven Sandberg	2009-07-22
      BUG#39934: Slave stops for engine that only support row-based logging
      This is a post-push fix addressing review requests and
      problems with extra warnings.
      
      Problem 1: The sub-statement where an unsafe warning was detected was
      printed as part of the warning. This was ok for statements that
      were unsafe due to, e.g., calls to UUID(), but did not make
      sense for statements that were unsafe because there was more than
      one autoincrement column (unsafeness in this case comes from the
      combination of several sub-statements).
      Fix 1: Instead of printing the sub-statement, print an explanation
      of why the statement is unsafe.
      
      Problem 2:
      When a recursive construct (i.e., stored proceure, stored
      function, trigger, view, prepared statement) contained several
      sub-statements, and at least one of them was unsafe, there would be
      one unsafeness warning per sub-statement - even for safe
      sub-statements.
      Fix 2:
      Ensure that each type of warning is printed at most once, by
      remembering throughout the execution of the statement which types
      of warnings have been printed.
     @ mysql-test/extra/rpl_tests/create_recursive_construct.inc
        - Clarified comment per review request.
        - Added checks for the number of warnings in each invocation.
     @ mysql-test/extra/rpl_tests/rpl_insert_delayed.test
        Per review request, replaced @@session.binlog_format by
        @@global.binlog_format, since INSERT DELAYED reads the global
        variable. (In this test case, the two variables have the same
        value, so the change is cosmetic.)
     @ mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_ps.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_unsafe.result
        Updated result file. Note that duplicate warnings are now gone.
     @ mysql-test/suite/binlog/t/binlog_unsafe.test
        - Added tests for: (1) a statement that is unsafe in many ways;
          (2) a statement that is unsafe in the same way several times.
        - Use -- style to invoke mysqltest commands.
     @ mysql-test/suite/rpl/r/rpl_stm_found_rows.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_loadfile.result
        updated result file
     @ mysql-test/suite/rpl/t/rpl_mix_found_rows.test
        Per review request, added comment explaining what the test case
        does (copied from rpl_stm_found_rows.test)
     @ mysql-test/suite/rpl/t/rpl_stm_found_rows.test
        Clarified grammar in comment.
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        Updated result file.
     @ sql/item_create.cc
        Made set_stmt_unsafe take one parameter, describing the
        type of unsafeness.
     @ sql/sp_head.cc
        Added unsafe_flags field and made it hold all the unsafe flags.
     @ sql/sp_head.h
        - Removed the BINLOG_ROW_BASED_IF_MIXED flag from m_flags.
          Instead, we use the new unsafe_flags field to hold the
          unsafeness state of the sp.
        - Made propagate_attributes() copy all unsafe flags.
     @ sql/sql_base.cc
        - Made LEX::set_stmt_unsafe() take an extra argument.
        - Made binlog_unsafe_warning_flags store the type of unsafeness.
        - Per review requests, clarified comments
        - Added DBUG printouts
     @ sql/sql_class.cc
        - Made warnings be generated in issue_warnings() and call that from
          binlog_query(). Wrote issue_warnings(), which prints zero or more
          warnings, avoiding to print warnings more than once per statement.
        - Per review request, added @todo so that we remember to assert
          correct behavior in binlog_query.
     @ sql/sql_class.h
        - Removed BINLOG_WARNING_PRINTED 
        - Use [set|clear]_current_stmt_binlog_row_based() instead of
          modifying the flag directly.
        - added issue_unsafe_warnings() (only called from binlog_unsafe)
        - Per review request, improved some documentation.
     @ sql/sql_insert.cc
        Added extra argument to LEX::set_stmt_unsafe()
     @ sql/sql_lex.h
        - Added enum_binlog_stmt_unsafe, listing all types of unsafe
          statements.
        - Per review requests, improved many comments for member
          functions.
        - Added [get|set]_stmt_unsafe_flags(), which return/set all the
          unsafe flags for a statement.
     @ sql/sql_parse.cc
        - Renamed binlog_warning_flags to binlog_unsafe_warning_flags.
        - Per review requests, improved comment.
     @ sql/sql_view.cc
        Made views propagate all the new unsafe flags.
     @ sql/sql_yacc.yy
        Added parameter to set_stmt_unsafe().
     @ storage/innobase/handler/ha_innodb.cc
        Per review requests, replaced DBUG_EXECUTE_IF() by DBUG_EVALUATE_IF().
[19 Aug 2009 11:39] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/81061

3030 Sven Sandberg	2009-08-19
      post-push fixes for BUG#39934
      Removed hard-coded error messages. All messages are now in
      errmsg.txt
      Also renamed enumeration value BINLOG_STMT_UNSAFE_FUNCTION to
      BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION to make the naming consistent
      with BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE.
     @ sql/item_create.cc
        Renamed BINLOG_STMT_UNSAFE_FUNCTION to
        BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION
     @ sql/share/errmsg.txt
        Moved hard-coded strings from THD::issue_unsafe_warnings() to
        errmsg.txt.
     @ sql/sql_class.cc
        - Moved error messages to errmsg.txt.
        - Updated comment above THD::issue_unsafe_warnings().
     @ sql/sql_lex.h
        Renamed BINLOG_STMT_UNSAFE_FUNCTION to
        BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION
     @ sql/sql_yacc.yy
        Renamed BINLOG_STMT_UNSAFE_FUNCTION to
        BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION
[30 Sep 2009 12:09] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85197
[30 Sep 2009 12:24] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85199
[30 Sep 2009 16:01] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85239
[30 Sep 2009 16:06] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85240
[30 Sep 2009 16:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85244

3107 Sven Sandberg	2009-09-30
      post-merge fixes to make tests pass after merging BUG#39934 to 5.1-rep+3.
[5 Oct 2009 19:11] Sven Sandberg
To docs team: the following has changed:

(1) At http://dev.mysql.com/doc/refman/5.1/en/binary-log-mixed.html : I changed exampledb to be statment-only, not row-only. Please update the list of storage engines.

(2) After my patch, we don't just have safe and unsafe statements; we have three types of statements: safe, unsafe, and row injections. Please update the decision table at http://dev.mysql.com/doc/refman/5.1/en/binary-log-mixed.html according to the comment above decide_logging_format in sql_class.cc
[14 Oct 2009 16:28] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/86858

3109 Sven Sandberg	2009-10-14
      BUG#39934: Slave stops for engine that only support row-based logging
      Post-push fix.
      Problem: After the original bugfix, if a statement is unsafe,
      binlog_format=mixed, and engine is statement-only, a warning was
      generated and the statement executed. However, it is a fundamental
      principle of binlogging that binlog_format=mixed should guarantee
      correct logging, no compromise. So correct behavior is to generate
      an error and don't execute the statement.
      Fix: Generate warning instead of error.
     @ mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_ps.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_unsafe.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_found_rows.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_loadfile.result
        updated result file
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        updated result file
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
        updated test:
         - ER_BINLOG_UNSAFE_AND_STMT_ENGINE is now an error.
         - added test for multiple types of unsafety
     @ sql/share/errmsg.txt
         - Reformulated ER_BINLOG_UNSAFE_AND_STMT_ENGINE to reflect that it
           is now an error, not a warning.
         - Added "Reason for unsafeness" to ER_BINLOG_UNSAFE_STATEMENT and
           ER_BINLOG_UNSAFE_AND_STMT_ENGINE.
     @ sql/sql_class.cc
        In decide_logging_format:
         - generate an error immediately in case 3, instead of scheduling a
           warning to be generated later. also updated comments accordingly
         - in case 7, there is only one unsafe warning error code now, so we
           don't need to store it in binlog_unsafe_warning_flags
           (see changes in sql_lex.h)
         - fixed compilation warning in DBUG_PRINT
        
        In issue_binlog_warning:
         - moved array of error codes to sql_lex.h (so that they are
           accessible also from decide_logging_format)
         - simplified code after the first set of bits in
           binlog_unsafe_warning_flags was removed
     @ sql/sql_class.h
         - got rid of enum_binlog_stmt_warning. It's not needed anymore
           since we only have one type of unsafe warning (one of them
           turned into an error)
         - updated comments accordingly
     @ sql/sql_lex.cc
        added initialization of the array of error codes that has been
        moved from THD::issue_unsafe_warnings to LEX.
     @ sql/sql_lex.h
        Moved array of error codes from THD::issue_unsafe_warnings to LEX.
[14 Oct 2009 16:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/86860

3109 Sven Sandberg	2009-10-14
      BUG#39934: Slave stops for engine that only support row-based logging
      Post-push fix.
      Problem: After the original bugfix, if a statement is unsafe,
      binlog_format=mixed, and engine is statement-only, a warning was
      generated and the statement executed. However, it is a fundamental
      principle of binlogging that binlog_format=mixed should guarantee
      correct logging, no compromise. So correct behavior is to generate
      an error and don't execute the statement.
      Fix: Generate error instead of warning.
      Since issue_unsafe_warnings can only generate one error message,
      this allows us to simplify the code a bit too:
      decide_logging_format does not have to save the error code for
      issue_unsafe_warnings
     @ mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_ps.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
        updated result file
     @ mysql-test/suite/binlog/r/binlog_unsafe.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_found_rows.result
        updated result file
     @ mysql-test/suite/rpl/r/rpl_stm_loadfile.result
        updated result file
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        updated result file
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
        updated test:
         - ER_BINLOG_UNSAFE_AND_STMT_ENGINE is now an error.
         - added test for multiple types of unsafety
     @ sql/share/errmsg.txt
         - Reformulated ER_BINLOG_UNSAFE_AND_STMT_ENGINE to reflect that it
           is now an error, not a warning.
         - Added "Reason for unsafeness" to ER_BINLOG_UNSAFE_STATEMENT and
           ER_BINLOG_UNSAFE_AND_STMT_ENGINE.
     @ sql/sql_class.cc
        In decide_logging_format:
         - generate an error immediately in case 3, instead of scheduling a
           warning to be generated later. also updated comments accordingly
         - in case 7, there is only one unsafe warning error code now, so we
           don't need to store it in binlog_unsafe_warning_flags
           (see changes in sql_lex.h)
         - fixed compilation warning in DBUG_PRINT
        
        In issue_binlog_warning:
         - moved array of error codes to sql_lex.h (so that they are
           accessible also from decide_logging_format)
         - simplified code after the first set of bits in
           binlog_unsafe_warning_flags was removed
     @ sql/sql_class.h
         - got rid of enum_binlog_stmt_warning. It's not needed anymore
           since we only have one type of unsafe warning (one of them
           turned into an error)
         - updated comments accordingly
     @ sql/sql_lex.cc
        added initialization of the array of error codes that has been
        moved from THD::issue_unsafe_warnings to LEX.
     @ sql/sql_lex.h
        Moved array of error codes from THD::issue_unsafe_warnings to LEX.
[14 Oct 2009 16:33] Sven Sandberg
pushed to 5.1-rpl+3
[19 Oct 2009 8:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/87256

3111 Sven Sandberg	2009-10-19
      BUG#39934: Slave stops for engine that only support row-based logging
      post-push fixes. the test case tried to use a udf that had not been loaded. removed the udf.
     @ mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
        updated result file
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
        myfunc_int() was supposed to be a udf. but the udf was not loaded.
        since the test already uses another plugin, and we don't support
        multiple plugin directories, i removed the udf function. it was not
        strictly needed.
[19 Oct 2009 8:53] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/87257

3112 Sven Sandberg	2009-10-19
      BUG#39934 - post-push fixes.
      The rpl_ndb/combinations file was introduced as part of the fix.
      The file contained an error: ndb suites shall not run with
      binlog_format=mixed. Removed that combination.
     @ mysql-test/suite/rpl_ndb/combinations
        removed binlog_format=statement combination since ndb does not
        support statement format.
     @ mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables.test
        Added have_binlog_format_mixed_or_row.inc.
[19 Oct 2009 13:12] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/87304

3113 Sven Sandberg	2009-10-19
      BUG#39934: Slave stops for engine that only support row-based logging
      Post-push fix.
      Problem: In a previous patch for BUG#39934, rpl_idempotency.test
      was split in two tests. The mtr suppressions in the original test
      did not make it into the new test. This caused pushbuild warnings.
      Fix: copy the mtr suppressions from rpl_idempotency.test to
      rpl_row_idempotency.test
     @ mysql-test/suite/rpl/t/rpl_row_idempotency.test
        copied the warnings from rpl_idempotency.test to
        rpl_row_idempotency.test
[19 Oct 2009 13:13] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/87306

3113 Sven Sandberg	2009-10-19
      BUG#39934: Slave stops for engine that only support row-based logging
      Post-push fix.
      Problem: In a previous patch for BUG#39934, rpl_idempotency.test
      was split in two tests. The mtr suppressions in the original test
      did not make it into the new test. This caused pushbuild warnings.
      Fix: copy the mtr suppressions from rpl_idempotency.test to
      rpl_row_idempotency.test
     @ mysql-test/suite/rpl/r/rpl_row_idempotency.result
        updated result file
     @ mysql-test/suite/rpl/t/rpl_row_idempotency.test
        copied the warnings from rpl_idempotency.test to
        rpl_row_idempotency.test
[18 Jan 2010 12:06] Bugs System
Pushed into 6.0.14-alpha (revid:alik@ibmvm-20100118120357-hnzhgadkpzqfnvsc) (version source revid:alik@ibmvm-20100118115413-kd3klpine09yyktw) (merge vers: 6.0.14-alpha) (pib:16)
[18 Jan 2010 12:07] Bugs System
Pushed into mysql-next-mr (revid:alik@ibmvm-20100118120111-73dulkgc893it4r9) (version source revid:alik@ibmvm-20100118115335-0stecyzftqm7bqx6) (pib:16)
[24 Jan 2010 20:40] Jon Stephens
Documented in the 5.6.0 and 6.0.14 changelogs as follows:

        For an engine that supports only row-based replication, 
        replication stopped with an error when executing row events.

        As part of the fix for this issue, the EXAMPLE storage engine is now
        changed so that it supports statement-based logging only. Previously, 
        it supported row-based logging only.

Set NDI status, waiting for 5.1 merge.
[24 Jan 2010 20:41] Jon Stephens
After I get the changelog entry for the 5.1 manual, I'll change this bug's category to Documentation and address the changes in decision-making semantics brought up in the developer comments.
[13 Feb 2010 8:36] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100213083436-9pesg4h55w1mekxc) (version source revid:luis.soares@sun.com-20100211135109-t63avry9fqpgyh78) (merge vers: 6.0.14-alpha) (pib:16)
[13 Feb 2010 9:18] Jon Stephens
Still waiting for 5.1 merge. See previous comments.
[13 Feb 2010 10:32] Jon Stephens
See also BUG#51021.
[18 Feb 2010 16:05] Jon Stephens
Luis confirms no new merges expected. Closed.
[6 Mar 2010 10:55] Bugs System
Pushed into 5.5.3-m3 (revid:alik@sun.com-20100306103849-hha31z2enhh7jwt3) (version source revid:vvaintroub@linux-rbsx-20100118220048-5vnyqi5ghsbgmdsd) (merge vers: 5.5.99-m3) (pib:16)
[8 Mar 2010 0:18] Paul DuBois
Moved 5.6.0 changelog entry to 5.5.3.
[24 Mar 2010 8:14] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100324081249-yfwol7qtcek6dh7w) (version source revid:alik@sun.com-20100324081113-kc7x1iytnplww91u) (merge vers: 6.0.14-alpha) (pib:16)
[24 Mar 2010 8:17] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100324081159-5b8juv8ldiqwce8v) (version source revid:alik@sun.com-20100324081105-y72rautcea375zxm) (pib:16)
[30 Mar 2010 13:00] Jon Stephens
http://lists.mysql.com/commits/104627 closes Docs portion of bug.
[30 Mar 2010 13:01] Jon Stephens
Also updated changelog entry.

Closed.
[15 Jun 2010 8:18] Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100615080459-smuswd9ooeywcxuc) (version source revid:marko.makela@oracle.com-20100601134335-ccthwwru23kn09qw) (merge vers: 5.1.48) (pib:16)
[15 Jun 2010 8:35] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100615080558-cw01bzdqr1bdmmec) (version source revid:marko.makela@oracle.com-20100601134335-ccthwwru23kn09qw) (pib:16)
[15 Jun 2010 8:48] Jon Stephens
Already documented fix in 5.5.3 and 6.0.14 changelogs, and corresponding effects in corresponding versions of the Manual (see previous comments from Paul and me).

Closed without further action.
[4 Aug 2010 8:05] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@ibmvm-20100804080001-bny5271e65xo34ig) (version source revid:alik@sun.com-20100324081105-y72rautcea375zxm) (merge vers: 5.6.99-m4) (pib:18)
[4 Aug 2010 8:21] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@ibmvm-20100804081533-c1d3rbipo9e8rt1s) (version source revid:alik@sun.com-20100324081105-y72rautcea375zxm) (merge vers: 5.6.99-m4) (pib:18)
[4 Aug 2010 23:22] Paul DuBois
Bug does not appear in any released 5.6.x version.
[3 Sep 2010 19:21] Jon Stephens
Set developer and lead back to old values.