From ca051fa0275a09ff63ef4172dc6db9d8ee6cdcea Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 8 Oct 2015 10:16:35 +0300 Subject: [PATCH] Allow row events in replication stream for slave in all cases (even when configured with --binlog-format=statement). Before we got an error on the slave and the slave stopped if the master was configured with --binlog-format=mixed or --binlog-format=row. --- mysql-test/suite/rpl/r/rpl_row_to_stmt.result | 28 +++++++++++++++++++ .../suite/rpl/t/rpl_row_to_stmt-master.opt | 1 + .../suite/rpl/t/rpl_row_to_stmt-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_to_stmt.test | 23 +++++++++++++++ sql/sql_class.cc | 15 ++++------ 5 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_row_to_stmt.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt.test diff --git a/mysql-test/suite/rpl/r/rpl_row_to_stmt.result b/mysql-test/suite/rpl/r/rpl_row_to_stmt.result new file mode 100644 index 0000000000000..2dfa82b030551 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_to_stmt.result @@ -0,0 +1,28 @@ +include/master-slave.inc +[connection master] +use test; +create table t1 (a int primary key); +insert into t1 values (1),(2),(3),(4),(5); +update t1 set a=a*10; +use test; +select * from t1; +a +10 +20 +30 +40 +50 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (a int primary key) +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Update_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt b/mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt new file mode 100644 index 0000000000000..83ed8522e7298 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt @@ -0,0 +1 @@ +--binlog-format=row diff --git a/mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt b/mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt new file mode 100644 index 0000000000000..af3a211967b07 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt @@ -0,0 +1 @@ +--binlog-format=statement diff --git a/mysql-test/suite/rpl/t/rpl_row_to_stmt.test b/mysql-test/suite/rpl/t/rpl_row_to_stmt.test new file mode 100644 index 0000000000000..5ca583d881f7d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_to_stmt.test @@ -0,0 +1,23 @@ +# +# check that master starterd with log-format=ROW replication can replicate to +# slave started with log-format=STATEMENT +# + +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +use test; + +create table t1 (a int primary key); +insert into t1 values (1),(2),(3),(4),(5); +update t1 set a=a*10; + +sync_slave_with_master; +use test; +select * from t1; +source include/show_binlog_events.inc; + +connection master; +drop table t1; + +--source include/rpl_end.inc diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d2221d210e093..978adf6a353e5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5156,16 +5156,13 @@ void xid_cache_delete(XID_STATE *xid_state) BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-logging. - 6. Error: Cannot execute row injection: binlogging impossible since - BINLOG_FORMAT = STATEMENT. - - 7. Warning: Unsafe statement binlogged in statement format since + 6. Warning: Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. In addition, we can produce the following error (not depending on the variables of the decision diagram): - 8. Error: Cannot execute statement: binlogging impossible since more + 7. Error: Cannot execute statement: binlogging impossible since more than one engine is involved and at least one engine is self-logging. @@ -5444,10 +5441,10 @@ int THD::decide_logging_format(TABLE_LIST *tables) if (lex->is_stmt_row_injection()) { /* - 6. Error: Cannot execute row injection since - BINLOG_FORMAT = STATEMENT + We have to log the statement as row or give an error. + Better to accept what master gives us than stopping replication. */ - my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0)); + set_current_stmt_binlog_format_row(); } else if ((flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0 && sqlcom_can_generate_row_events(this)) @@ -5472,7 +5469,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_PRINT("info", ("binlog_unsafe_warning_flags: 0x%x", binlog_unsafe_warning_flags)); } - /* log in statement format! */ + /* log in statement format (or row if row event)! */ } /* No statement-only engines and binlog_format != STATEMENT. I.e., nothing prevents us from row logging if needed. */