List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:March 28 2009 11:32am
Subject:bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)
Bug#39393
View as plain text  
#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; )

Thread
bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)Bug#39393Alfranio Correia28 Mar
  • Re: bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)Bug#39393He Zhenxing31 Mar
    • Re: bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)Bug#39393Alfranio Correia31 Mar
      • Re: bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)Bug#39393He Zhenxing31 Mar
        • Re: bzr commit into mysql-5.1-bugteam branch (alfranio.correia:2802)Bug#39393Alfranio Correia31 Mar