#At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-39393/mysql-5.1-bugteam/ based on revid:sergey.glukhov@stripped
2802 Alfranio Correia 2009-03-28
BUG#39393 slave-skip-errors does not work when using ROW based replication
RBR was not considering the option --slave-skip-errors.
To fix the problem, we are reporting the ignored ERROR(s) as warnings thus avoiding
stopping the SQL Thread. Besides, it fixes the output of "SHOW VARIABLES LIKE
'slave_skip_errors'" which was showing nothing when the value "all" was assigned
to --slave-skip-errors.
@sql/log_event.cc
skipped rbr errors when the option skip-slave-errors is set.
@sql/slave.cc
fixed the output of for SHOW VARIABLES LIKE 'slave_skip_errors'"
@test-cases
fixed the output of rpl.rpl_idempotency
create a test case rpl_skiperrors_rbr
added:
mysql-test/suite/rpl/r/rpl_skiperrors_rbr.result
mysql-test/suite/rpl/t/rpl_skiperrors_rbr-slave.opt
mysql-test/suite/rpl/t/rpl_skiperrors_rbr.test
modified:
mysql-test/suite/rpl/r/rpl_idempotency.result
mysql-test/suite/rpl/t/rpl_idempotency.test
sql/log_event.cc
sql/slave.cc
=== modified file 'mysql-test/suite/rpl/r/rpl_idempotency.result'
--- a/mysql-test/suite/rpl/r/rpl_idempotency.result 2008-11-13 19:19:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_idempotency.result 2009-03-28 11:32:15 +0000
@@ -141,9 +141,9 @@ select * from ti1 order by b /* must be
b
2
3
-*** slave must stop
+*** slave must stop (Trying to delete a referenced foreing key)
Last_SQL_Error
-0
+1451
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
b
1
@@ -159,7 +159,7 @@ set global slave_exec_mode='STRICT';
*** conspire future problem
delete from ti1 where b=3;
insert into ti2 set a=3, b=3 /* offending write event */;
-*** slave must stop
+*** slave must stop (Trying to insert an invalid foreign key)
Last_SQL_Error
1452
select * from ti2 order by b /* must be (2,2) */;
@@ -179,7 +179,7 @@ a b
*** conspiring query
insert into ti1 set b=1;
insert into ti1 set b=1 /* offending write event */;
-*** slave must stop
+*** slave must stop (Trying to insert a dupliacte key)
Last_SQL_Error
1062
set foreign_key_checks= 0;
@@ -195,32 +195,32 @@ INSERT INTO t2 VALUES (-1),(-2),(-3);
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
DELETE FROM t1 WHERE a = -2;
-*** slave must stop
+*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
DELETE FROM t2 WHERE a = -2;
-*** slave must stop
+*** slave must stop (Key was not found)
Last_SQL_Error
-0
+1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t1 SET a = 1 WHERE a = -1;
UPDATE t2 SET a = 1 WHERE a = -1;
UPDATE t1 SET a = 1 WHERE a = -1;
-*** slave must stop
+*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t2 SET a = 1 WHERE a = -1;
-*** slave must stop
+*** slave must stop (Key was not found)
Last_SQL_Error
-0
+1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
=== added file 'mysql-test/suite/rpl/r/rpl_skiperrors_rbr.result'
--- a/mysql-test/suite/rpl/r/rpl_skiperrors_rbr.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_skiperrors_rbr.result 2009-03-28 11:32:15 +0000
@@ -0,0 +1,105 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `data` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SET SQL_LOG_BIN=1;
+CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `data` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+start transaction;
+INSERT INTO t1 VALUES(1, 1);
+INSERT INTO t1 VALUES(10, 1);
+SET SQL_LOG_BIN=0;
+DELETE FROM t1 WHERE id = 10;
+SET SQL_LOG_BIN=1;
+INSERT INTO t1 VALUES(10, 2);
+INSERT INTO t1 VALUES(3, 2);
+commit;
+
+SELECT *, "INNODB SLAVE DATA" FROM t1 ORDER BY id;
+id data INNODB SLAVE DATA
+1 1 INNODB SLAVE DATA
+3 2 INNODB SLAVE DATA
+10 1 INNODB SLAVE DATA
+SELECT *, "INNODB MASTER DATA" FROM t1 ORDER BY id;
+id data INNODB MASTER DATA
+1 1 INNODB MASTER DATA
+3 2 INNODB MASTER DATA
+10 2 INNODB MASTER DATA
+DELETE FROM t1;
+INSERT INTO t1 VALUES(1, 1);
+INSERT INTO t1 VALUES(2, 1);
+INSERT INTO t1 VALUES(3, 1);
+INSERT INTO t1 VALUES(4, 1);
+SET SQL_LOG_BIN=0;
+DELETE FROM t1 WHERE id = 4;
+SET SQL_LOG_BIN=1;
+UPDATE t1 SET id= id + 3, data = 2;
+
+SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id;
+id data INNODB SET SLAVE DATA
+1 1 INNODB SET SLAVE DATA
+2 1 INNODB SET SLAVE DATA
+3 1 INNODB SET SLAVE DATA
+4 1 INNODB SET SLAVE DATA
+SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id;
+id data INNODB SET MASTER DATA
+4 2 INNODB SET MASTER DATA
+5 2 INNODB SET MASTER DATA
+6 2 INNODB SET MASTER DATA
+SET SQL_LOG_BIN=0;
+CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `data` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SET SQL_LOG_BIN=1;
+CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `data` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t2 VALUES(1, 1);
+INSERT INTO t2 VALUES(2, 1);
+INSERT INTO t2 VALUES(3, 1);
+INSERT INTO t2 VALUES(5, 1);
+SET SQL_LOG_BIN=0;
+DELETE FROM t2 WHERE id = 5;
+SET SQL_LOG_BIN=1;
+UPDATE t2 SET id= id + 3, data = 2;
+
+SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id;
+id data MYISAM SET SLAVE DATA
+2 1 MYISAM SET SLAVE DATA
+3 1 MYISAM SET SLAVE DATA
+4 2 MYISAM SET SLAVE DATA
+5 1 MYISAM SET SLAVE DATA
+SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id;
+id data MYISAM SET MASTER DATA
+4 2 MYISAM SET MASTER DATA
+5 2 MYISAM SET MASTER DATA
+6 2 MYISAM SET MASTER DATA
+DROP TABLE t1;
+DROP TABLE t2;
=== modified file 'mysql-test/suite/rpl/t/rpl_idempotency.test'
--- a/mysql-test/suite/rpl/t/rpl_idempotency.test 2008-11-13 19:19:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_idempotency.test 2009-03-28 11:32:15 +0000
@@ -208,7 +208,7 @@ select * from ti1 order by b /* must be
# foreign key: row is referenced
---echo *** slave must stop
+--echo *** slave must stop (Trying to delete a referenced foreing key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -242,7 +242,7 @@ delete from ti1 where b=3;
connection master;
insert into ti2 set a=3, b=3 /* offending write event */;
---echo *** slave must stop
+--echo *** slave must stop (Trying to insert an invalid foreign key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -281,7 +281,7 @@ insert into ti1 set b=1;
connection master;
insert into ti1 set b=1 /* offending write event */;
---echo *** slave must stop
+--echo *** slave must stop (Trying to insert a dupliacte key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -316,7 +316,7 @@ DELETE FROM t2 WHERE a = -2;
connection master;
DELETE FROM t1 WHERE a = -2;
---echo *** slave must stop
+--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -333,8 +333,8 @@ sync_slave_with_master;
set global slave_exec_mode='STRICT';
connection master;
-DELETE FROM t2 WHERE a = -2;
---echo *** slave must stop
+DELETE FROM t2 WHERE a = -2;
+--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -356,7 +356,7 @@ UPDATE t2 SET a = 1 WHERE a = -1;
connection master;
UPDATE t1 SET a = 1 WHERE a = -1;
---echo *** slave must stop
+--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
@@ -376,7 +376,7 @@ set global slave_exec_mode='STRICT';
connection master;
UPDATE t2 SET a = 1 WHERE a = -1;
---echo *** slave must stop
+--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
=== added file 'mysql-test/suite/rpl/t/rpl_skiperrors_rbr-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_skiperrors_rbr-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skiperrors_rbr-slave.opt 2009-03-28 11:32:15 +0000
@@ -0,0 +1 @@
+--slave_skip_errors=all
=== added file 'mysql-test/suite/rpl/t/rpl_skiperrors_rbr.test'
--- a/mysql-test/suite/rpl/t/rpl_skiperrors_rbr.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skiperrors_rbr.test 2009-03-28 11:32:15 +0000
@@ -0,0 +1,132 @@
+#################################################################
+# This test cases checks if slave-skip-errors works when
+# using ROW based by generating forcing duplicate keys
+# in the SLAVE.
+#
+# The following scenarios are checked:
+#
+# 1 - InnoDB with transactions, both commit and rollback.
+# 2 - InnoDB with an UPDATE on a SET of rows.
+# 3 - MyIsam with an UPDATE on a SET of rows.
+#
+#################################################################
+
+--source include/have_innodb.inc
+--source include/master-slave.inc
+
+#################################################################
+# 1 - (InnoDB with Transaction) Duplicate key
+#################################################################
+connection master;
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+SET SQL_LOG_BIN=1;
+
+connection slave;
+CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+
+connection master;
+
+start transaction;
+INSERT INTO t1 VALUES(1, 1);
+INSERT INTO t1 VALUES(10, 1);
+SET SQL_LOG_BIN=0;
+DELETE FROM t1 WHERE id = 10;
+SET SQL_LOG_BIN=1;
+INSERT INTO t1 VALUES(10, 2);
+INSERT INTO t1 VALUES(3, 2);
+commit;
+
+sync_slave_with_master;
+
+let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+echo $error;
+
+connection slave;
+
+SELECT *, "INNODB SLAVE DATA" FROM t1 ORDER BY id;
+
+connection master;
+
+SELECT *, "INNODB MASTER DATA" FROM t1 ORDER BY id;
+
+#################################################################
+# 2 - (InnoDB with sets) Duplicate key
+#################################################################
+connection master;
+
+DELETE FROM t1;
+
+INSERT INTO t1 VALUES(1, 1);
+INSERT INTO t1 VALUES(2, 1);
+INSERT INTO t1 VALUES(3, 1);
+INSERT INTO t1 VALUES(4, 1);
+
+SET SQL_LOG_BIN=0;
+DELETE FROM t1 WHERE id = 4;
+SET SQL_LOG_BIN=1;
+UPDATE t1 SET id= id + 3, data = 2;
+
+sync_slave_with_master;
+
+let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+echo $error;
+
+connection slave;
+
+SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id;
+
+connection master;
+
+SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id;
+
+#################################################################
+# 3 - (MyIsam with sets) Duplicate key
+#################################################################
+connection master;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam;
+SHOW CREATE TABLE t2;
+SET SQL_LOG_BIN=1;
+
+connection slave;
+CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam;
+SHOW CREATE TABLE t2;
+
+connection master;
+
+INSERT INTO t2 VALUES(1, 1);
+INSERT INTO t2 VALUES(2, 1);
+INSERT INTO t2 VALUES(3, 1);
+INSERT INTO t2 VALUES(5, 1);
+
+SET SQL_LOG_BIN=0;
+DELETE FROM t2 WHERE id = 5;
+SET SQL_LOG_BIN=1;
+UPDATE t2 SET id= id + 3, data = 2;
+
+sync_slave_with_master;
+
+let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+echo $error;
+
+connection slave;
+
+SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id;
+
+connection master;
+
+SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id;
+
+#################################################################
+# Clean up
+#################################################################
+connection master;
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+sync_slave_with_master;
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2009-02-04 11:08:27 +0000
+++ b/sql/log_event.cc 2009-03-28 11:32:15 +0000
@@ -277,6 +277,47 @@ static void clear_all_errors(THD *thd, R
rli->clear_error();
}
+inline int idempotent_error_code(int err_code)
+{
+ int ret= 0;
+
+ switch (err_code)
+ {
+ case 0:
+ ret= 1;
+ break;
+ /*
+ The following list of "idempotent" errors
+ means that an error from the list might happen
+ because of idempotent (more than once)
+ applying of a binlog file.
+ Notice, that binlog has a ddl operation its
+ second applying may cause
+
+ case HA_ERR_TABLE_DEF_CHANGED:
+ case HA_ERR_CANNOT_ADD_FOREIGN:
+
+ which are not included into to the list.
+
+ Note that HA_ERR_RECORD_DELETED is not in the list since
+ do_exec_row() should not return that error code.
+ */
+ case HA_ERR_RECORD_CHANGED:
+ case HA_ERR_KEY_NOT_FOUND:
+ case HA_ERR_END_OF_FILE:
+ case HA_ERR_FOUND_DUPP_KEY:
+ case HA_ERR_FOUND_DUPP_UNIQUE:
+ case HA_ERR_FOREIGN_DUPLICATE_KEY:
+ case HA_ERR_NO_REFERENCED_ROW:
+ case HA_ERR_ROW_IS_REFERENCED:
+ ret= 1;
+ break;
+ default:
+ ret= 0;
+ break;
+ }
+ return (ret);
+}
/**
Ignore error code specified on command line.
@@ -301,14 +342,37 @@ inline int ignored_error_code(int err_co
return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
(use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
}
-#endif
+/*
+ This function converts an engine's error to a server error.
+
+ If the thread does not have an error already reported, it tries to
+ define it by calling the engine's method print_error. However, if a
+ mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
+ warning message.
+*/
+int convert_row_error(int error, THD* thd, TABLE *table)
+{
+ uint actual_error= (thd->is_error() ? thd->main_da.sql_errno() :
+ 0);
+
+ if (actual_error == 0)
+ {
+ table->file->print_error(error, MYF(0));
+ actual_error= (thd->is_error() ? thd->main_da.sql_errno() :
+ ER_UNKNOWN_ERROR);
+ if (actual_error == ER_UNKNOWN_ERROR)
+ if (global_system_variables.log_warnings)
+ sql_print_warning("Unmapped error detected %d in RBR", error);
+ }
+
+ return (actual_error);
+}
/*
pretty_print_str()
*/
-#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
static char *pretty_print_str(char *packet, const char *str, int len)
{
const char *end= str + len;
@@ -7151,7 +7215,9 @@ int Rows_log_event::do_apply_event(Relay
{
/*
Error reporting borrowed from Query_log_event with many excessive
- simplifications (we don't honour --slave-skip-errors)
+ 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",
@@ -7177,6 +7243,10 @@ 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;
@@ -7214,7 +7284,7 @@ int Rows_log_event::do_apply_event(Relay
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));
-
+
if (table)
{
/*
@@ -7267,10 +7337,18 @@ int Rows_log_event::do_apply_event(Relay
this->slave_exec_mode= slave_exec_mode_options; // fix the mode
// Do event specific preparations
- error= do_before_row_operations(rli);
+ if ((error= do_before_row_operations(rli)) &&
+ ignored_error_code(convert_row_error(error, thd, table)))
+ {
+ if (global_system_variables.log_warnings)
+ slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
+ get_type_str(),
+ RPL_LOG_NAME, (ulong) log_pos);
+ clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
+ error= 0;
+ }
// row processing loop
-
while (error == 0 && m_curr_row < m_rows_end)
{
/* in_use can have been set to NULL in close_tables_for_reopen */
@@ -7284,48 +7362,26 @@ int Rows_log_event::do_apply_event(Relay
DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
table->in_use = old_thd;
- switch (error)
- {
- case 0:
- break;
- /*
- The following list of "idempotent" errors
- means that an error from the list might happen
- because of idempotent (more than once)
- applying of a binlog file.
- Notice, that binlog has a ddl operation its
- second applying may cause
-
- case HA_ERR_TABLE_DEF_CHANGED:
- case HA_ERR_CANNOT_ADD_FOREIGN:
-
- which are not included into to the list.
- Note that HA_ERR_RECORD_DELETED is not in the list since
- do_exec_row() should not return that error code.
- */
- case HA_ERR_RECORD_CHANGED:
- case HA_ERR_KEY_NOT_FOUND:
- case HA_ERR_END_OF_FILE:
- case HA_ERR_FOUND_DUPP_KEY:
- case HA_ERR_FOUND_DUPP_UNIQUE:
- case HA_ERR_FOREIGN_DUPLICATE_KEY:
- case HA_ERR_NO_REFERENCED_ROW:
- case HA_ERR_ROW_IS_REFERENCED:
+ if (error)
+ {
+ bool ignored_error= ignored_error_code(
+ convert_row_error(error, thd, table));
+ bool idempotent_error= (idempotent_error_code(error) &&
+ bit_is_set(slave_exec_mode,
+ SLAVE_EXEC_MODE_IDEMPOTENT));
- if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (ignored_error || idempotent_error)
{
if (global_system_variables.log_warnings)
slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
get_type_str(),
RPL_LOG_NAME, (ulong) log_pos);
+ clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
error= 0;
+ if (idempotent_error == 0)
+ break;
}
- break;
-
- default:
- thd->is_slave_error= 1;
- break;
}
/*
@@ -7352,7 +7408,19 @@ int Rows_log_event::do_apply_event(Relay
DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
- error= do_after_row_operations(rli, error);
+
+ if ((error= do_after_row_operations(rli, error)) &&
+ ignored_error_code(convert_row_error(error, thd, table)))
+ {
+
+ if (global_system_variables.log_warnings)
+ slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
+ get_type_str(),
+ RPL_LOG_NAME, (ulong) log_pos);
+ clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
+ error= 0;
+ }
+
if (!cache_stmt)
{
DBUG_PRINT("info", ("Marked that we need to keep log"));
@@ -7366,29 +7434,15 @@ int Rows_log_event::do_apply_event(Relay
*/
if (rli->tables_to_lock && get_flags(STMT_END_F))
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
-
- if (error)
- { /* error has occured during the transaction */
- slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
- get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
- }
+
if (error)
{
- /*
- If one day we honour --skip-slave-errors in row-based replication, and
- the error should be skipped, then we would clear mappings, rollback,
- close tables, but the slave SQL thread would not stop and then may
- assume the mapping is still available, the tables are still open...
- So then we should clear mappings/rollback/close here only if this is a
- STMT_END_F.
- For now we code, knowing that error is not skippable and so slave SQL
- thread is certainly going to stop.
- rollback at the caller along with sbr.
- */
+ slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
+ get_type_str(),
+ RPL_LOG_NAME, (ulong) log_pos);
thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
thd->is_slave_error= 1;
- DBUG_RETURN(error);
}
/*
@@ -7396,7 +7450,8 @@ int Rows_log_event::do_apply_event(Relay
since we have no access to table there, we do the setting of
last_event_start_time here instead.
*/
- if (table && (table->s->primary_key == MAX_KEY) &&
+ if (error == 0 &&
+ table && (table->s->primary_key == MAX_KEY) &&
!cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS)
{
/*
@@ -7418,7 +7473,7 @@ int Rows_log_event::do_apply_event(Relay
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
Log_event::enum_skip_reason
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2009-01-09 12:49:24 +0000
+++ b/sql/slave.cc 2009-03-28 11:32:15 +0000
@@ -361,6 +361,7 @@ void init_slave_skip_errors(const char*
if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4))
{
bitmap_set_all(&slave_error_mask);
+ print_slave_skip_errors();
DBUG_VOID_RETURN;
}
for (p= arg ; *p; )