List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:September 10 2009 10:05am
Subject:bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3117) Bug#45999
View as plain text  
#At file:///home/anders/work/bzrwork/August/bug45999/mysql-5.1-bugteam/ based on revid:sergey.glukhov@stripped

 3117 Li-Bing.Song@stripped	2009-09-10
      BUG#45999 Row based replication fails when auto_increment field = 0
      
      In RBR, There is an inconsistency between slaves and master.
      When INSERT statement which includes an auto_increment field is executed,
      Store engine of master will check the value of the auto_increment field. 
      It will generate a sequence number and then replace the value, if its value is NULL or empty.
      if the field's value is 0, the store engine will do like encountering the NULL values 
      unless NO_AUTO_VALUE_ON_ZERO is set into SQL_MODE.
      In contrast, if the field's value is 0, Store engine of slave always generates a new sequence number 
      whether or not NO_AUTO_VALUE_ON_ZERO is set into SQL_MODE.
      
      SQL MODE of slave sql thread is always consistency with master's.
      Another variable is related to this bug.
      If generateing a sequence number is decided by the values of
      table->auto_increment_field_not_null and SQL_MODE(if includes MODE_NO_AUTO_VALUE_ON_ZERO)
      The table->auto_increment_is_not_null is FALSE, which causes this bug to appear. ..

    modified:
      mysql-test/extra/rpl_tests/rpl_auto_increment.test
      mysql-test/suite/rpl/r/rpl_auto_increment.result
      sql/log_event.cc
=== modified file 'mysql-test/extra/rpl_tests/rpl_auto_increment.test'
--- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test	2009-01-14 08:27:32 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test	2009-09-10 10:05:53 +0000
@@ -163,5 +163,81 @@ show create table t1;
 connection master;
 drop table t1;
 
+#
+# BUG#45999 Row based replication fails when auto_increment field = 0.  
+# Store engine of Slaves auto-generates new sequence numbers for
+# auto_increment fields if the values of them are 0. There is an inconsistency
+# between slave and master. When MODE_NO_AUTO_VALUE_ON_ZERO are masters treat 
+#
+source include/master-slave-reset.inc;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+eval CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type;
+eval CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type2;
+SET SQL_MODE='';
+# Value of the id will be 1;
+INSERT INTO t1 VALUES(NULL);
+INSERT INTO t2 VALUES(NULL);
+SELECT * FROM t1;
+SELECT * FROM t2;
+# Value of the id will be 2;
+INSERT INTO t1 VALUES();
+INSERT INTO t2 VALUES();
+SELECT * FROM t1;
+SELECT * FROM t2;
+# Value of the id will be 3. The master treats 0 as NULL or empty because
+# NO_AUTO_VALUE_ON_ZERO is not assign to SQL_MODE.
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+# Value of the id will be 0. The master does not treat 0 as NULL or empty
+# because NO_AUTO_VALUE_ON_ZERO has assigned to SQL_MODE.
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+INSERT INTO t1 VALUES(4);
+INSERT INTO t2 VALUES(4);
+FLUSH LOGS;
+sync_slave_with_master;
+
+let $diff_table_1= master:test.t1;
+let $diff_table_2= slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_table_1= master:test.t2;
+let $diff_table_2= slave:test.t2;
+source include/diff_tables.inc;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t2;
+sync_slave_with_master;
+
+connection master;
+let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL test
+sync_slave_with_master;
+
+let $diff_table_1= master:test.t1;
+let $diff_table_2= slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_table_1= master:test.t2;
+let $diff_table_2= slave:test.t2;
+source include/diff_tables.inc;
+
 # End cleanup
+DROP TABLE t1;
+DROP TABLE t2;
+SET SQL_MODE='';
 sync_slave_with_master;

=== modified file 'mysql-test/suite/rpl/r/rpl_auto_increment.result'
--- a/mysql-test/suite/rpl/r/rpl_auto_increment.result	2009-01-14 08:27:32 +0000
+++ b/mysql-test/suite/rpl/r/rpl_auto_increment.result	2009-09-10 10:05:53 +0000
@@ -244,3 +244,71 @@ t1	CREATE TABLE `t1` (
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
 drop table t1;
+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;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam;
+SET SQL_MODE='';
+INSERT INTO t1 VALUES(NULL);
+INSERT INTO t2 VALUES(NULL);
+SELECT * FROM t1;
+id
+1
+SELECT * FROM t2;
+id
+1
+INSERT INTO t1 VALUES();
+INSERT INTO t2 VALUES();
+SELECT * FROM t1;
+id
+1
+2
+SELECT * FROM t2;
+id
+1
+2
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+id
+1
+2
+3
+SELECT * FROM t2;
+id
+1
+2
+3
+SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+id
+0
+1
+2
+3
+SELECT * FROM t2;
+id
+0
+1
+2
+3
+INSERT INTO t1 VALUES(4);
+INSERT INTO t2 VALUES(4);
+FLUSH LOGS;
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+DROP TABLE t1;
+DROP TABLE t2;
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+DROP TABLE t1;
+DROP TABLE t2;
+SET SQL_MODE='';

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2009-08-27 12:46:29 +0000
+++ b/sql/log_event.cc	2009-09-10 10:05:53 +0000
@@ -8312,6 +8312,16 @@ Write_rows_log_event::do_before_row_oper
   
   /* Honor next number column if present */
   m_table->next_number_field= m_table->found_next_number_field;
+  /*
+   * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
+   * sequence numbers for auto_increment fields if the values of them are 0.
+   * If generateing a sequence number is decided by the values of
+   * table->auto_increment_field_not_null and SQL_MODE(if includes
+   * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
+   * SQL_MODE of slave sql thread is always consistency with master's.
+   * In RBR, auto_increment fields never are NULL.
+   */
+  m_table->auto_increment_field_not_null= TRUE;
   return error;
 }
 
@@ -8321,6 +8331,7 @@ Write_rows_log_event::do_after_row_opera
 {
   int local_error= 0;
   m_table->next_number_field=0;
+  m_table->auto_increment_field_not_null= FALSE;
   if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
       m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
   {


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20090910100553-g2wt3unebnbg66gr.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3117) Bug#45999Li-Bing.Song10 Sep