#At file:///home/lsoares/Workspace/bzr/work/bugfixing/12428494/mysql-5.1/ based on revid:alexander.nozdrin@stripped
3682 Luis Soares 2011-05-26
BUG#12428494
If setting slave-skip-errors=all and using RBR, then slave
will not skip errors returned while:
1. opening tables that do not exist on the slave;
2. checking that table definitions on the slave match
the ones on the master.
On SBR, however, the slave will properly skip the errors
as instructed by the slave-skip-errors option setting.
We fix this by checking if the error returned on
simple_open_n_lock_tables and on m_tabledef.compatible_with
should be ignored or not before actually reporting/returning
the error.
added:
mysql-test/suite/rpl/r/rpl_skip_error_all.result
mysql-test/suite/rpl/t/rpl_skip_error_all-slave.opt
mysql-test/suite/rpl/t/rpl_skip_error_all.test
modified:
sql/log_event.cc
=== added file 'mysql-test/suite/rpl/r/rpl_skip_error_all.result'
--- a/mysql-test/suite/rpl/r/rpl_skip_error_all.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_skip_error_all.result 2011-05-26 22:57:20 +0000
@@ -0,0 +1,16 @@
+include/master-slave.inc
+[connection master]
+include/rpl_reset.inc
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (a CHAR) ENGINE=InnoDB;
+SET SQL_LOG_BIN=1;
+call mtr.add_suppression ("Slave SQL: Table definition on master and slave does not match: Column 0 type mismatch.*");
+CREATE TABLE t1 (a DATE) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('a'), ('b');
+DROP TABLE t1;
+include/rpl_reset.inc
+CREATE TABLE t1 (id INT) ENGINE=MyISAM;
+DROP TABLE t1;
+INSERT INTO t1 VALUES(1);
+DROP TABLE t1;
+include/rpl_end.inc
=== added file 'mysql-test/suite/rpl/t/rpl_skip_error_all-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_skip_error_all-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skip_error_all-slave.opt 2011-05-26 22:57:20 +0000
@@ -0,0 +1 @@
+--slave-skip-errors=all
=== added file 'mysql-test/suite/rpl/t/rpl_skip_error_all.test'
--- a/mysql-test/suite/rpl/t/rpl_skip_error_all.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skip_error_all.test 2011-05-26 22:57:20 +0000
@@ -0,0 +1,47 @@
+--source include/master-slave.inc
+--source include/have_innodb.inc
+
+#
+# BUG#12428494: IN ROW-BASED REPLICATION SLAVE-SKIP-ERRORS=ALL DOES NOT SKIP ALL ERRORS
+#
+
+# Test 1
+#
+# Test that different table definitions error
+# will be skipped when slave-skip-errors=all
+--source include/rpl_reset.inc
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (a CHAR) ENGINE=InnoDB;
+SET SQL_LOG_BIN=1;
+
+--connection slave
+call mtr.add_suppression ("Slave SQL: Table definition on master and slave does not match: Column 0 type mismatch.*");
+
+CREATE TABLE t1 (a DATE) ENGINE=InnoDB;
+
+--connection master
+INSERT INTO t1 VALUES ('a'), ('b');
+--sync_slave_with_master
+--connection master
+DROP TABLE t1;
+--sync_slave_with_master
+
+# Test 2
+#
+# Test that when there is no table at the slave and if
+# slave-skil-errors=all the slave will skip it
+--source include/rpl_reset.inc
+
+--connection master
+
+CREATE TABLE t1 (id INT) ENGINE=MyISAM;
+--sync_slave_with_master
+DROP TABLE t1;
+
+--connection master
+INSERT INTO t1 VALUES(1);
+DROP TABLE t1;
+--sync_slave_with_master
+
+--source include/rpl_end.inc
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2011-03-24 10:52:40 +0000
+++ b/sql/log_event.cc 2011-05-26 22:57:20 +0000
@@ -7362,6 +7362,7 @@ int Rows_log_event::do_apply_event(Relay
{
DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
int error= 0;
+ TABLE *table= NULL;
/*
If m_table_id == ~0UL, then we have a dummy event that does not
contain any data. In that case, we just remove all tables in the
@@ -7446,13 +7447,18 @@ int Rows_log_event::do_apply_event(Relay
if (simple_open_n_lock_tables(thd, rli->tables_to_lock))
{
uint actual_error= thd->main_da.sql_errno();
- if (thd->is_slave_error || thd->is_fatal_error)
+ if (ignored_error_code(actual_error))
+ {
+ clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
+ error= 0;
+ actual_error= 0;
+ goto end;
+ }
+ else if (thd->is_slave_error || thd->is_fatal_error)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications.
- We should not honour --slave-skip-errors at this point as we are
- having severe errors which should not be skiped.
*/
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on opening tables",
@@ -7478,14 +7484,21 @@ int Rows_log_event::do_apply_event(Relay
{
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
{
- /*
- We should not honour --slave-skip-errors at this point as we are
- having severe errors which should not be skiped.
- */
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
+
+ // skip the error if the slave is instructed to do it.
+ uint actual_error= const_cast<Relay_log_info*>(rli)->last_error().number;
+ if (ignored_error_code(actual_error))
+ {
+ clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
+ error= 0;
+ actual_error= 0;
+ goto end;
+ }
+
DBUG_RETURN(ERR_BAD_TABLE_DEF);
}
}
@@ -7514,9 +7527,7 @@ int Rows_log_event::do_apply_event(Relay
#endif
}
- TABLE*
- table=
- m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
+ table= m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %lu", (ulong) m_table, m_table_id));
@@ -7666,6 +7677,8 @@ int Rows_log_event::do_apply_event(Relay
}
} // if (table)
+end:
+
/*
We need to delay this clear until here bacause unpack_current_row() uses
master-side table definitions stored in rli.
Attachment: [text/bzr-bundle] bzr/luis.soares@oracle.com-20110526225720-fv0kkquv4ez6li1a.bundle