List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:March 24 2009 12:16pm
Subject:Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045
View as plain text  
Hi Luis,

Excellent work!

I have some comments though, see them inline below.

Just my few cents,
Mats Kindahl

Luis Soares wrote:
> #At file:///home/lsoares/Workspace/mysql-server/bugfix/40045/6.0-rpl/ based on
> revid:serge.kozlov@stripped
> 
>  2831 Luis Soares	2009-03-20
>       BUG#40045: Replication failure on RBR + no PK + UPDATE + integer key +
>       char with no key
>       
>       Row based replication would break if updating a row and using a key
>       for searching for the correct row to update. This was observed when
>       using MyISAM storage engine on the slave. Since MyISAM does not
>       provide partial row fetch (HA_PARTIAL_COLUMN_READ) , the comparison
>       between the row fetched on the slave and the before image (BI)
>       replicated from master would fail. This happened because the BI (which
>       sometimes was only part of the row) would always be compared against a
>       complete row.
>       
>       Furthermore, the read set mask was not being properly set when using
>       keys (not unique nor primary) which would lead to partial row matches,
>       thence changes might end up in the wrong row.
>       
>       This patch addresses this by changing the record_compare function for
>       taking into consideration the fields set on the readset and the engine
>       used on the slave. Furthermore, it also changes the construction of
>       the read set on the master by forcing the setting of the appropriate
>       fields (the ones that uniquely identify the row).
>      @ mysql-test/extra/rpl_tests/rpl_row_record_find.test
>         Shared part of the test battery while testing with different engines.
>      @ mysql-test/suite/rpl/r/rpl_row_record_find.result
>         Result file.
>      @ mysql-test/suite/rpl/t/rpl_row_record_find.test
>         Test case that checks for different combinations of engines and
>         updates/deletes.
>      @ sql/log_event.cc
>         Changed the record_compare function to compare the entire record
>         when possible, or just the fields marked in the read_set otherwise.
>      @ sql/log_event_old.cc
>         Changed the record_compare function to compare the entire record
>         when possible, or just the fields marked in the read_set otherwise.
>      @ sql/records.cc
>         Added changes for forcing marking the correct read_set when binlogging.
> 
>     added:
>       mysql-test/extra/rpl_tests/rpl_row_record_find.test
>       mysql-test/suite/rpl/r/rpl_row_record_find.result
>       mysql-test/suite/rpl/t/rpl_row_record_find.test
>     modified:
>       sql/log_event.cc
>       sql/log_event_old.cc
>       sql/records.cc
> === added file 'mysql-test/extra/rpl_tests/rpl_row_record_find.test'
> --- a/mysql-test/extra/rpl_tests/rpl_row_record_find.test	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/extra/rpl_tests/rpl_row_record_find.test	2009-03-20 13:17:10 +0000
> @@ -0,0 +1,161 @@
> +# USAGE:
> +#   Before including this file the following variables should be set:
> +#     * $master_engine
> +#     * slave_engine
> +#
> +#   Example:
> +#
> +#     let $master_engine= Falcon;
> +#     let $slave_engine= MyISAM;
> +#
> +#     -- source extra/rpl_tests/rpl_row_record_find.test
> +# 
> +
> +
> +connection master;
> +
> +--disable_warnings
> +DROP TABLE IF EXISTS t;
> +--enable_warnings
> +
> +sync_slave_with_master;
> +connection master;
> +
> +let $i= 7;
> +while($i)
> +{
> +  connection master;
> +  SET SQL_LOG_BIN=0;
> +
> +  if (`SELECT $i=1`) {
> +    --echo ******* TEST: No keys ($master_engine -> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= $slave_engine;
> +  }
> +  if (`SELECT $i=2`)
> +  { 
> +    --echo ******* TEST: One Key ($master_engine -> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine=
> $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine=
> $slave_engine;
> +  }
> +  if (`SELECT $i=3`)
> +  {
> +    --echo ****** TEST: One Composite Key ($master_engine -> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine=
> $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine=
> $slave_engine;
> +  }  
> +  if (`SELECT $i=4`)
> +  {
> +    --echo ****** TEST: One Unique Key ($master_engine -> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine=
> $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine=
> $slave_engine;
> +  }  
> +  if (`SELECT $i=5`)
> +  {
> +    --echo ****** TEST: One Composite Unique Key ($master_engine ->
> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2))
> engine= $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2))
> engine= $slave_engine;
> +  }  
> +  if (`SELECT $i=6`)
> +  {
> +    --echo ****** TEST: One Primary Key ($master_engine -> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine=
> $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine=
> $slave_engine;
> +  }  
> +  if (`SELECT $i=7`)
> +  {
> +    --echo ****** TEST: One Composite Primary Key ($master_engine ->
> $slave_engine)
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2))
> engine= $master_engine;
> +    connection slave;
> +    --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2))
> engine= $slave_engine;
> +  }

I think you need to test a case where you have "holes" in the keys as well,
e.g., key(c1,c3).

> +
> +  connection master;
> +  SET SQL_LOG_BIN=1;
> +
> +  connection master;
> +  INSERT INTO t VALUES (1, '1', '3' );
> +  INSERT INTO t VALUES (2, '2', '3' );
> +  INSERT INTO t VALUES (3, '9', '9' );
> + 
> +  sync_slave_with_master;
> +
> +  --echo   ** WITHOUT KEY
> +  connection master;
> +  UPDATE t SET c3 = '4';
> +
> +  sync_slave_with_master;
> +
> +  let $diff_table_1=master:test.t;
> +  let $diff_table_2=slave:test.t;
> +  source include/diff_tables.inc;
> +
> +  if (`SELECT $i>1`)
> +  {
> +
> +    if (`SELECT $i=2 or $i=4 or $i=6`)
> +    {
> +      --echo   ** WITH FULL (primary / unique / normal) KEY
> +    }
> +
> +    if (`SELECT $i=3 or $i=5 or $i=7`)
> +    {
> +      --echo   ** WITH HALF (primary / unique / normal) KEY READ
> +    }
> +
> +    connection master;
> +    UPDATE t SET c3 = '5' WHERE c1 = 1;
> +
> +    sync_slave_with_master;
> +
> +    let $diff_table_1=master:test.t;
> +    let $diff_table_2=slave:test.t;
> +    source include/diff_tables.inc;
> +  }
> +  
> +  if (`SELECT $i=3 or $i=5 or $i=7`)
> +  {
> +    --echo   ** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +
> +    connection master;
> +    UPDATE t SET c2 = '3' WHERE c2 = '2';
> +  
> +    sync_slave_with_master;
> +
> +    let $diff_table_1=master:test.t;
> +    let $diff_table_2=slave:test.t;
> +    source include/diff_tables.inc;
> +    
> +    --echo   ** CHANGE PART OF KEY (with no key field in WHERE)
> +    connection master;
> +    UPDATE t SET c2 = '1' WHERE c3 = '9';
> +
> +    sync_slave_with_master;
> +
> +    let $diff_table_1=master:test.t;
> +    let $diff_table_2=slave:test.t;
> +    source include/diff_tables.inc;
> +  }
> +
> +  connection master;
> +  DELETE FROM t WHERE c1 = 1;
> +  DELETE FROM t WHERE c1 = 2;
> +  DELETE FROM t;

You need a sync and a compare between each of these statements, otherwise you
will only make sure that the table is empty after executing the delete.

> +
> +  sync_slave_with_master;
> +
> +  let $diff_table_1=master:test.t;
> +  let $diff_table_2=slave:test.t;
> +  source include/diff_tables.inc;
> +
> +  DROP TABLE t;
> +  sync_slave_with_master;
> +
> +  dec $i;
> +}
> 
> === added file 'mysql-test/suite/rpl/r/rpl_row_record_find.result'
> --- a/mysql-test/suite/rpl/r/rpl_row_record_find.result	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_record_find.result	2009-03-20 13:17:10 +0000
> @@ -0,0 +1,1080 @@
> +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 ( i1 int, c1 char(1), key ( i1 ));
> +INSERT IGNORE INTO t1 VALUES (1, 'a');
> +UPDATE t1 SET c1 = 'b' WHERE i1 = 1;
> +DROP TABLE t1;
> +CREATE TABLE table1_myisam ( `bit_key` bit, `int_key` int, key (`bit_key` ), key
> (`int_key` ));
> +INSERT IGNORE INTO table1_myisam VALUES ('1', '-2146992385');
> +Warnings:
> +Warning	1264	Out of range value for column 'bit_key' at row 1

Do you need this warning for the test to work correct? If not, I would suggest
creating a statement that does not emit a warning (a result mismatch on this
warning would indeed catch an error, but since this is not the objective of this
test, I would leave that to the test that tests for that).

> +UPDATE `table1_myisam` SET `bit_key` = 0 WHERE `bit_key` = 1;
> +DROP TABLE table1_myisam;
> +#################################################################
> +# CASE 1: MyISAM - master, MyISAM - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (MyISAM -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 2: Falcon - master, Falcon - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (Falcon -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 3: Falcon - master, MyISAM - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (Falcon -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 4: InnoDB - master, MyISAM - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (InnoDB -> MyISAM)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 5: InnoDB - master, InnoDB - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (InnoDB -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 6: MyISAM - master, InnoDB - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (MyISAM -> Falcon)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +#################################################################
> +# CASE 7: MyISAM - master, InnoDB - slave
> +#################################################################
> +DROP TABLE IF EXISTS t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Primary Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine=
> InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Primary Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Unique Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Unique Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +****** TEST: One Composite Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique / normal) KEY READ
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +** WITH HALF (primary / unique /normal) KEY READ (changing itself)
> +UPDATE t SET c2 = '3' WHERE c2 = '2';
> +Comparing tables master:test.t and slave:test.t
> +** CHANGE PART OF KEY (with no key field in WHERE)
> +UPDATE t SET c2 = '1' WHERE c3 = '9';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: One Key (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +** WITH FULL (primary / unique / normal) KEY
> +UPDATE t SET c3 = '5' WHERE c1 = 1;
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> +SET SQL_LOG_BIN=0;
> +******* TEST: No keys (MyISAM -> InnoDB)
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
> +CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t VALUES (1, '1', '3' );
> +INSERT INTO t VALUES (2, '2', '3' );
> +INSERT INTO t VALUES (3, '9', '9' );
> +** WITHOUT KEY
> +UPDATE t SET c3 = '4';
> +Comparing tables master:test.t and slave:test.t
> +DELETE FROM t WHERE c1 = 1;
> +DELETE FROM t WHERE c1 = 2;
> +DELETE FROM t;
> +Comparing tables master:test.t and slave:test.t
> +DROP TABLE t;
> 
> === added file 'mysql-test/suite/rpl/t/rpl_row_record_find.test'
> --- a/mysql-test/suite/rpl/t/rpl_row_record_find.test	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_row_record_find.test	2009-03-20 13:17:10 +0000
> @@ -0,0 +1,127 @@
> +#
> +# BUG#40045: Replication failure on RBR + no PK + UPDATE + integer key + char
> +# with no key
> +#
> +# BUG#40007: Replication failure with RBR + no PK + 2 indexed fields 
> +#
> +# TEST DESCRIPTION
> +# ================
> +#
> +#   This test is structure in three cases. In all of them, roughly the same
> +#   update and delete operations are performed, but what changes are the keys
> +#   in the table: 
> +#      no keys, one key, composite key (but only half is used in query),
> +#      unique key, primary key
> +#   
> +#   The three cases are distinct because the engine on both and master and
> +#   slave varies:
> +#      
> +#      CASE 1:  MyISAM - master, MyISAM - slave
> +#         test without HA_PARTIAL_COLUMN_READ engine on master and on slave
> +#      CASE 2:  Falcon - master, Falcon - slave
> +#         test with HA_PARTIAL_COLUMN_READ engine on master and on slave
> +#      CASE 3:  Falcon - master, MyISAM - slave
> +#         test with HA_PARTIAL_COLUMN_READ engine on master but not on slave
> +#      CASE 4:  InnoDB - master, MyISAM - slave
> +#         test with HA_PARTIAL_COLUMN_READ engine on master but not on slave
> +#         (InnoDB)
> +#      CASE 5:  InnoDB - master, InnoDB - slave
> +#         test with HA_PARTIAL_COLUMN_READ engine on master and on slave
> +#         (InnoDB)
> +#      CASE 6:  MyISAM - master, Falcon - slave
> +#         test without HA_PARTIAL_COLUMN_READ engine on master but with it on slave
> +#         (Falcon)
> +#      CASE 7:  MyISAM - master, InnoDB - slave
> +#         test without HA_PARTIAL_COLUMN_READ engine on master but with it on slave
> +#         (InnoDB)
> +#
> +#   NOTE: Before the battery of tests actually takes place, a sanity check is
> +#         performed with the test cases used to verify the BUGS.
> +
> +source include/master-slave.inc;
> +source include/have_binlog_format_row.inc;
> +source include/have_innodb.inc;
> +source include/have_falcon.inc;

This means that you will not execute this test unless all engines are installed.

I think you need to split this test into separate files: one for each storage
engine that you're testing. You can put replication from MyISAM to another
engine (e.g., Falcon) into the test file for that other engine (i.e., Falcon in
the example).

> +
> +### SANITY TESTS for BUG#40045 and BUG#40007
> +
> +# TEST CASE USED for verifying BUG#40045
> +CREATE TABLE t1 ( i1 int, c1 char(1), key ( i1 ));
> +INSERT IGNORE INTO t1 VALUES (1, 'a');
> +UPDATE t1 SET c1 = 'b' WHERE i1 = 1;
> +DROP TABLE t1;
> +sync_slave_with_master;
> +
> +# TEST CASE USED for verifying BUG#40007
> +connection master;
> +CREATE TABLE table1_myisam ( `bit_key` bit, `int_key` int, key (`bit_key` ), key
> (`int_key` ));
> +INSERT IGNORE INTO table1_myisam VALUES ('1', '-2146992385');
> +UPDATE `table1_myisam` SET `bit_key` = 0 WHERE `bit_key` = 1;
> +DROP TABLE table1_myisam;
> +sync_slave_with_master;
> +
> +connection master;
> +
> +--echo #################################################################
> +--echo # CASE 1: MyISAM - master, MyISAM - slave
> +--echo #################################################################
> +
> +let $master_engine= MyISAM;
> +let $slave_engine= MyISAM;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 2: Falcon - master, Falcon - slave
> +--echo #################################################################
> +
> +let $master_engine= Falcon;
> +let $slave_engine= Falcon;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 3: Falcon - master, MyISAM - slave
> +--echo #################################################################
> +
> +let $master_engine= Falcon;
> +let $slave_engine= MyISAM;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 4: InnoDB - master, MyISAM - slave
> +--echo #################################################################
> +
> +let $master_engine= InnoDB;
> +let $slave_engine= MyISAM;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 5: InnoDB - master, InnoDB - slave
> +--echo #################################################################
> +
> +let $master_engine= InnoDB;
> +let $slave_engine= InnoDB;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 6: MyISAM - master, InnoDB - slave
> +--echo #################################################################
> +
> +let $master_engine= MyISAM;
> +let $slave_engine= Falcon;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> +--echo #################################################################
> +--echo # CASE 7: MyISAM - master, InnoDB - slave
> +--echo #################################################################
> +
> +let $master_engine= MyISAM;
> +let $slave_engine= InnoDB;
> +
> +-- source extra/rpl_tests/rpl_row_record_find.test
> +
> 
> === modified file 'sql/log_event.cc'
> --- a/sql/log_event.cc	2009-03-04 13:33:47 +0000
> +++ b/sql/log_event.cc	2009-03-20 13:17:10 +0000
> @@ -8611,7 +8611,7 @@ void Write_rows_log_event::print(FILE *f
>  
>    Returns TRUE if different.
>  */
> -static bool record_compare(TABLE *table)
> +static bool record_compare(TABLE *table, const MY_BITMAP *cols_in_readset)

You have the table already, why are you passing in the readset instead of
reading it from table->read_set?

>  {
>    /*
>      Need to set the X bit and the filler bits in both records since
> @@ -8643,14 +8643,23 @@ static bool record_compare(TABLE *table)
>      }
>    }
>  
> -  if (table->s->blob_fields + table->s->varchar_fields == 0)
> +  /* 
> +     We can compare the record straight away if:
> +      i) there are no blob and varchar fields
> +     ii) all columns were read or the slave SE provides partial reads
> +  */
> +  if ((table->s->blob_fields + table->s->varchar_fields == 0)
> &&
> +      (bitmap_is_set_all(cols_in_readset) || 
> +      (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)))
>    {
>      result= cmp_record(table,record[1]);
>      goto record_compare_exit;
>    }
>  
> -  /* Compare null bits */
> -  if (memcmp(table->null_flags,
> +  /* Compare null bits only if all fields were read or slave SE has partial reads
> */
> +  if ((bitmap_is_set_all(cols_in_readset) || 
> +       (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
> && 
> +      memcmp(table->null_flags,
>  	     table->null_flags+table->s->rec_buff_length,
>  	     table->s->null_bytes))
>    {
> @@ -8661,10 +8670,14 @@ static bool record_compare(TABLE *table)
>    /* Compare updated fields */
>    for (Field **ptr=table->field ; *ptr ; ptr++)
>    {
> -    if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
> -    {
> -      result= TRUE;
> -      goto record_compare_exit;
> +    /* compare field if it is set */
> +    if (bitmap_is_set(cols_in_readset, (*ptr)->field_index))
> +    { 
> +      if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
> +      {
> +        result= TRUE;
> +        goto record_compare_exit;
> +      }
>      }
>    }
>  
> @@ -8875,7 +8888,7 @@ int Rows_log_event::find_row(const Relay
>       */ 
>      DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); 
>  
> -    while (record_compare(table))
> +    while (record_compare(table, &m_cols))

Is it not possible to ensure that table->read_set == m_cols and just set it at
the beginning of the execution of the event (or maybe even only when executing
the table_map_event and opening the table)?

>      {
>        /*
>          We need to set the null bytes to ensure that the filler bit
> @@ -8956,7 +8969,7 @@ int Rows_log_event::find_row(const Relay
>          goto err;
>        }
>      }
> -    while (restart_count < 2 && record_compare(table));
> +    while (restart_count < 2 && record_compare(table, &m_cols));

See above.

>      
>      /* 
>        Note: above record_compare will take into accout all record fields 
> 
> === modified file 'sql/log_event_old.cc'
> --- a/sql/log_event_old.cc	2008-12-10 14:30:52 +0000
> +++ b/sql/log_event_old.cc	2009-03-20 13:17:10 +0000
> @@ -313,7 +313,7 @@ last_uniq_key(TABLE *table, uint keyno)
>  
>    Returns TRUE if different.
>  */
> -static bool record_compare(TABLE *table)
> +static bool record_compare(TABLE *table, const MY_BITMAP *cols_in_readset)
>  {
>    /*
>      Need to set the X bit and the filler bits in both records since
> @@ -342,16 +342,25 @@ static bool record_compare(TABLE *table)
>      }
>    }
>  
> -  if (table->s->blob_fields + table->s->varchar_fields == 0)
> +  /*   
> +     We can compare the record straight away if:
> +       i) there are no blob and varchar fields
> +      ii) all columns were read or the slave SE provides partial reads
> +  */
> +  if ((table->s->blob_fields + table->s->varchar_fields == 0)
> &&
> +      (bitmap_is_set_all(cols_in_readset) || 
> +      (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)))
>    {
>      result= cmp_record(table,record[1]);
>      goto record_compare_exit;
>    }
>  
> -  /* Compare null bits */
> -  if (memcmp(table->null_flags,
> -       table->null_flags+table->s->rec_buff_length,
> -       table->s->null_bytes))
> +  /* Compare null bits only if all fields were read or slave SE has partial reads
> */
> +  if ((bitmap_is_set_all(cols_in_readset) || 
> +        (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
> && 
> +      memcmp(table->null_flags,
> +             table->null_flags+table->s->rec_buff_length,
> +             table->s->null_bytes))
>    {
>      result= TRUE;       // Diff in NULL value
>      goto record_compare_exit;
> @@ -360,10 +369,14 @@ static bool record_compare(TABLE *table)
>    /* Compare updated fields */
>    for (Field **ptr=table->field ; *ptr ; ptr++)
>    {
> -    if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
> -    {
> -      result= TRUE;
> -      goto record_compare_exit;
> +    /* compare field if it is set */
> +    if (bitmap_is_set(cols_in_readset, (*ptr)->field_index))
> +    { 
> +      if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
> +      {
> +        result= TRUE;
> +        goto record_compare_exit;
> +      }
>      }
>    }
>  
> @@ -761,7 +774,7 @@ static int find_and_fetch_row(TABLE *tab
>        DBUG_RETURN(0);
>      }
>  
> -    while (record_compare(table))
> +    while (record_compare(table, table->read_set))
>      {
>        int error;
>  
> @@ -837,7 +850,7 @@ static int find_and_fetch_row(TABLE *tab
>    DBUG_RETURN(error);
>        }
>      }
> -    while (restart_count < 2 && record_compare(table));
> +    while (restart_count < 2 && record_compare(table,
> table->read_set));
>  
>      /*
>        Have to restart the scan to be able to fetch the next row.
> @@ -2387,7 +2400,7 @@ int Old_rows_log_event::find_row(const R
>       */ 
>      DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); 
>  
> -    while (record_compare(table))
> +    while (record_compare(table, &m_cols))
>      {
>        /*
>          We need to set the null bytes to ensure that the filler bit
> @@ -2463,7 +2476,7 @@ int Old_rows_log_event::find_row(const R
>          DBUG_RETURN(error);
>        }
>      }
> -    while (restart_count < 2 && record_compare(table));
> +    while (restart_count < 2 && record_compare(table, &m_cols));
>      
>      /* 
>        Note: above record_compare will take into accout all record fields 
> 
> === modified file 'sql/records.cc'
> --- a/sql/records.cc	2008-08-11 12:40:09 +0000
> +++ b/sql/records.cc	2009-03-20 13:17:10 +0000
> @@ -67,6 +67,27 @@ void init_read_record_idx(READ_RECORD *i
>    info->record= table->record[0];
>    info->print_error= print_error;
>  
> +  /* sets read set needed for RBR */
> +  if (thd->current_stmt_binlog_row_based && mysql_bin_log.is_open())
> +  {
> +    /*
> +      If the handler has no cursor capabilites, or we have row-based
> +      logging active for the current statement, we have to read either
> +      the primary key, the hidden primary key or all columns to be
> +      able to do an update
> +    */
> +    if (table->s->primary_key == MAX_KEY ||
> +        !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
> +      table->file->use_hidden_primary_key();  /* alias for use_all_columns()
> */

Use_hidden_primary_key() is virtual, so it depends on the storage engine whether
this will call use_all_columns() or not. Now, the binary log *always* require
*all* columns to be set, otherwise it will not work correctly, so you need to
somehow make sure that use_all_columns() is called when the binary log is active
(for that table).

One way would be to add a non-virtual ha_use_hidden_primary_key() function that
calls use_all_columns() if the binary log is active, and then calls the virtual
use_hidden_primary_key(). The default use_hidden_primary_key() would then do
nothing.

This will require you to change all calls to use_hidden_primary_key(), so if you
make the virtual function private, it will not compile unless you have fixed all
the calls.

> +    else
> +    {
> +      /* mark the primary key */
> +      table->mark_columns_used_by_index_no_reset(table->s->primary_key, 
> +                                                 table->read_set);
> +      table->file->column_bitmaps_signal();
> +    }
> +  }
> +
>    table->status=0;			/* And it's always found */
>    if (!table->file->inited)
>      table->file->ha_index_init(idx, 1);
> @@ -174,6 +195,27 @@ void init_read_record(READ_RECORD *info,
>    info->file= table->file;
>    info->forms= &info->table;		/* Only one table */
>    
> +  /* sets read set needed for RBR */
> +  if (thd->current_stmt_binlog_row_based && mysql_bin_log.is_open())
> +  {
> +    /*
> +      If the handler has no cursor capabilites, or we have row-based
> +      logging active for the current statement, we have to read either
> +      the primary key, the hidden primary key or all columns to be
> +      able to do an update
> +    */
> +    if (table->s->primary_key == MAX_KEY || 
> +        !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
> +      table->file->use_hidden_primary_key();  /* alias for use_all_columns()
> */

See above.

> +    else
> +    {
> +      /* mark the primary key */
> +      table->mark_columns_used_by_index_no_reset(table->s->primary_key, 
> +                                                 table->read_set);
> +      table->file->column_bitmaps_signal();
> +    }
> +  }
> +
>    if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
>        !table->sort.addon_field)
>      (void) table->file->extra(HA_EXTRA_MMAP);
> 
> 
> 
> ------------------------------------------------------------------------
> 
> 

-- 
Mats Kindahl
Senior Software Engineer
Database Technology Group
Sun Microsystems
Thread
bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Luis Soares20 Mar
  • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Mats Kindahl24 Mar
    • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Luís Soares24 Mar
      • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Mats Kindahl25 Mar
        • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Luís Soares3 Apr
          • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Mats Kindahl3 Apr
  • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Alfranio Correia24 Mar
    • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Luís Soares3 Apr
      • Re: bzr commit into mysql-6.0-rpl branch (luis.soares:2831) Bug#40045Alfranio Correia3 Apr