List:Commits« Previous MessageNext Message »
From:Luis Soares Date:March 4 2010 10:18am
Subject:bzr commit into mysql-5.1-bugteam branch (luis.soares:3352) Bug#51055
View as plain text  
#At file:///home/lsoares/Workspace/bzr/work/bugfixing/51055/mysql-5.1-bugteam/ based on revid:timothy.smith@stripped

 3352 Luis Soares	2010-03-04
      BUG#51055: Replication failure on duplicate key + traditional SQL
      mode
      
      When the master was executing in sql_mode='traditional' (which
      implies that really_abort_on_warning returns TRUE - because of
      MODE_STRICT_ALL_TABLES), the error code (ER_DUP_ENTRY in the
      reported case) was not being set in the
      Query_log_event. Therefore, even if a failure was to be expected
      when replaying the statement on the slave, a failure would occur,
      because the Query_log_event was not transporting the expected
      error code, but 0 instead.
      
      This was because when the master was getting the error code to
      set it in the Query_log_event, the executing thread would be
      assumed to have been killed:
      THD::killed==THD::KILL_BAD_DATA. This would make the error code
      fetch routine not to check thd->main_da.sql_errno(), but instead
      the thd->killed value. What's more, is that the server would
      thd->killed value if thd->killed == THD::KILL_BAD_DATA and return
      0 instead. So this is a double inconsistency, as the we should
      not even check thd->killed but rather thd->main_da.sql_errno().
      
      We fix this by extending the condition used to choose whether to
      check the thd->main_da.sql_errno() or thd->killed, so that it
      takes into consideration the case when:
      thd->killed==THD::KILL_BAD_DATA.

    added:
      mysql-test/suite/rpl/r/rpl_stm_sql_mode.result
      mysql-test/suite/rpl/t/rpl_stm_sql_mode.test
    modified:
      sql/log.cc
=== added file 'mysql-test/suite/rpl/r/rpl_stm_sql_mode.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_sql_mode.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_sql_mode.result	2010-03-04 10:18:06 +0000
@@ -0,0 +1,18 @@
+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;
+CREATE TABLE t1 (pk integer auto_increment , primary key (pk));
+SET SESSION SQL_MODE='traditional';
+# **** [MASTER] *****
+# action: raise DUP KEY error (error code should be set in the 
+#                              query log event)
+INSERT INTO t1 (`pk`) VALUES (1), (1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+DROP TABLE t1;
+# **** [ sync slave with master ] ****
+# assertion: sync slave with master makes slave not to stop with
+#            duplicate key error (because it has received event
+#            with expected error code).

=== added file 'mysql-test/suite/rpl/t/rpl_stm_sql_mode.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_sql_mode.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_sql_mode.test	2010-03-04 10:18:06 +0000
@@ -0,0 +1,24 @@
+-- source include/master-slave.inc
+-- source include/have_binlog_format_statement.inc
+
+#
+# Bug #51055    Replication failure on duplicate key + traditional SQL mode
+#
+
+CREATE TABLE t1 (pk integer auto_increment , primary key (pk));
+
+SET SESSION SQL_MODE='traditional';
+
+-- echo # **** [MASTER] *****
+-- echo # action: raise DUP KEY error (error code should be set in the 
+-- echo #                              query log event)
+-- error ER_DUP_ENTRY
+INSERT INTO t1 (`pk`) VALUES (1), (1);
+
+DROP TABLE t1;
+
+-- echo # **** [ sync slave with master ] ****
+-- echo # assertion: sync slave with master makes slave not to stop with
+-- echo #            duplicate key error (because it has received event
+-- echo #            with expected error code).
+-- sync_slave_with_master

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-02-05 17:01:09 +0000
+++ b/sql/log.cc	2010-03-04 10:18:06 +0000
@@ -4679,7 +4679,7 @@ int query_error_code(THD *thd, bool not_
 {
   int error;
   
-  if (not_killed)
+  if (not_killed || (thd->killed == THD::KILL_BAD_DATA))
   {
     error= thd->is_error() ? thd->main_da.sql_errno() : 0;
 


Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100304101806-1apjice8nv785ams.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (luis.soares:3352) Bug#51055Luis Soares4 Mar