Andrei Elkin wrote:
> Sven, hello.
>
> I have some small remarks and one concern for Problem 3 solution.
> Without implementing it the patch looks okay. Please find my point in
> lines below.
>
> cheers,
>
> Andrei
>
>
>> #At file:///home/sven/bzr/b37718-rpl_stm_mystery22/5.1-rpl/ based on
> revid:zhenxing.he@stripped
>>
>> 2709 Sven Sandberg 2009-01-05
>> BUG#37718: rpl.rpl_stm_mystery22 fails sporadically on pushbuild
>
>> Problem 1: The test waits for an error in the slave sql thread,
>> then resolves the error and issues 'start slave'. However, there
>> is a gap between when the error is reported and the slave sql
>> thread stops. If this gap was long, the slave would still be
>> running when 'start slave' happened, so 'start slave' would fail
>> and cause a test failure.
>> Fix 1: make wait_for_slave_sql_error wait for the slave to stop.
>> Updated wait_for_slave_sql_error_and_skip accordingly.
>
> Agreed.
>
>> Problem 2: rpl_stm_mystery22 is a horrible name, the comments in
>> the file didn't explain anything useful, the test was generally
>> hard to follow, and the test was essentially duplicated between
>> rpl_stm_mystery22 and rpl_row_mystery22.
>> Fix 2: The test is about conflicts in the slave SQL thread,
>> hence I renamed the tests to rpl_{stm,row}_conflicts. Refactored
>> the test so that the work is done in
>> extra/rpl_tests/rpl_conflicts.inc, and
>> rpl.rpl_{row,stm}_conflicts merely sets some variables and then
>> sourced extra/rpl_tests/rpl_conflicts.inc.
>> The tests have been rewritten and comments added.
>
> ok
>
>> Problem 3: When calling wait_for_slave_sql_error.inc, you always
>> want to verify that the sql thread stops because of the expected
>> error and not because of some other error. Currently,
>> wait_for_slave_sql_error.inc allows the caller to omit the error
>> code, in which case all error codes are accepted.
>> Fix 3: Made wait_for_slave_sql_error.inc fail if no error code
>> is given. Updated rpl_filter_tables_not_exist accordingly.
>
> Although I think the idea is worth of it, please find my comments below.
>
>> Problem 4: rpl_filter_tables_not_exist had a typo, the dollar
>> sign was missing in a 'let' statement.
>> Fix 4: Added dollar sign.
>
> ok
>
> I started reviewing not the latest commit, sorry. I hope my comments
> are relevant. In the lastest patch there is
>
> Problem 5: When replicating from other servers than the one named
> 'master', the wait_for_slave_* macros were unable to print debug
> info on the master.
> Fix 5: Remove parameter $slave_keep_connection by
> $master_connection.
>
> where I would suggest s/Remove/Replace/.
Right, fixed.
> Code changes to this part is okay.
>
>
>> removed:
>> mysql-test/suite/rpl/t/rpl_row_mystery22.test
>> added:
>> mysql-test/suite/rpl/t/rpl_row_conflicts.test
>> mysql-test/suite/rpl/t/rpl_stm_conflicts.test
>> renamed:
>> mysql-test/suite/rpl/r/rpl_row_mystery22.result =>
> mysql-test/suite/rpl/r/rpl_row_conflicts.result
>> mysql-test/suite/rpl/r/rpl_stm_mystery22.result =>
> mysql-test/suite/rpl/r/rpl_stm_conflicts.result
>> mysql-test/suite/rpl/t/rpl_stm_mystery22.test =>
> mysql-test/extra/rpl_tests/rpl_conflicts.test
>> modified:
>> mysql-test/include/wait_for_slave_sql_error.inc
>> mysql-test/include/wait_for_slave_sql_error_and_skip.inc
>> mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test
>> mysql-test/suite/rpl/r/rpl_row_conflicts.result
>> mysql-test/suite/rpl/r/rpl_stm_conflicts.result
>> mysql-test/extra/rpl_tests/rpl_conflicts.test
>>
>> per-file messages:
>> mysql-test/extra/rpl_tests/rpl_conflicts.test
>> rpl_stm_mystery22 and rpl_row_mystery22 have now been refactored and
> renamed:
>> The two test cases rpl.rpl_stm_conflicts.test and rpl.rpl_row_conflicts.test
>> just set some parameters, and then source
> include/rpl_tests/rpl_conflicts.test.
>> Also, cleaned up the test case a bit, and fixed BUG#37718.
>> mysql-test/include/wait_for_slave_sql_error.inc
>> Made it wait until the slave sql thread has stopped. This
>> takes very short time and avoids race condition bugs in
>> test cases (e.g., fixes BUG#37718).
>> mysql-test/include/wait_for_slave_sql_error_and_skip.inc
>> Since wait_for_slave_sql_error now waits for the slave sql
>> thread to stop too, wait_for_slave_sql_error_and_skip does not
>> have to wait for the slave sql thread to stop.
>> Also, since wait_for_slave_sql_error now requires the parameter
>> $slave_sql_errno to be set, wait_for_slave_sql_error_and_skip
>> requires that as well: updated the usage instructions.
>> mysql-test/suite/rpl/r/rpl_row_conflicts.result
>> update result file
>> mysql-test/suite/rpl/r/rpl_stm_conflicts.result
>> update result file
>> mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test
>> Set $slave_sql_errno, since it is now required.
>> Add dollar sign to $show_sql_error (without dollar sign,
>> mtr makes it an environment variable).
>> mysql-test/suite/rpl/t/rpl_row_conflicts.test
>> rpl_stm_mystery22 and rpl_row_mystery22 have now been refactored and
> renamed:
>> The two test cases rpl.rpl_stm_conflicts.test and rpl.rpl_row_conflicts.test
>> just set some parameters, and then source
> include/rpl_tests/rpl_conflicts.test.
>> Also, cleaned up the test case a bit, and fixed BUG#37718.
>> mysql-test/suite/rpl/t/rpl_row_mystery22.test
>> rpl_stm_mystery22 and rpl_row_mystery22 have now been refactored and
> renamed:
>> The two test cases rpl.rpl_stm_conflicts.test and rpl.rpl_row_conflicts.test
>> just set some parameters, and then source
> include/rpl_tests/rpl_conflicts.test.
>> Also, cleaned up the test case a bit, and fixed BUG#37718.
>> mysql-test/suite/rpl/t/rpl_stm_conflicts.test
>> rpl_stm_mystery22 and rpl_row_mystery22 have now been refactored and
> renamed:
>> The two test cases rpl.rpl_stm_conflicts.test and rpl.rpl_row_conflicts.test
>> just set some parameters, and then source
> include/rpl_tests/rpl_conflicts.test.
>> Also, cleaned up the test case a bit, and fixed BUG#37718.
>> === renamed file 'mysql-test/suite/rpl/t/rpl_stm_mystery22.test' =>
> 'mysql-test/extra/rpl_tests/rpl_conflicts.test'
>> --- a/mysql-test/suite/rpl/t/rpl_stm_mystery22.test 2008-12-12 11:40:22 +0000
>> +++ b/mysql-test/extra/rpl_tests/rpl_conflicts.test 2009-01-05 15:36:51 +0000
>> @@ -1,67 +1,145 @@
>> -################################
>> -# Change Author: JBM
>> -# Change Date: 2006-01-12
>> -# Change: Added back have stm binlog
>> -# and added requirments comments
>> -################################
>> -# test case to make slave thread get ahead by 22 bytes
>> -################################
>> -#REQUIREMENT: If there is a faked slave duplicate key insert
>> -#error and the slave is restarted, the replication should
>> -#proceed in a correct way.
>> -################################
>> -#REQUIREMENT: If there is a faked slave non-existing record
>> -#delete error and the slave is restarted, then the replication
>> -#should proceed in a correct way.
>> -#################################
>
>
>> +# ==== Purpose ====
>> +#
>> +# Test that slave behaves well in some conflict situations. The
>> +# following are tested:
>> +#
>> +# - The slave SQL thread sees an 'INSERT' of a row with a key that
>> +# already exists in the table. In this case, the slave behavior
>> +# depends on the binlog format and the value of @@slave_exec_mode on
>> +# the slave:
>> +#
>> +# - If the query is written in statement mode, or
>> +# @@slave_exec_mode!=IDEMPOTENT, the slave should stop. If the
>> +# already existing row is removed from the slave, and the slave
>> +# started again, it should proceed normally.
>> +#
>> +# - If the query is written in row mode, and
>> +# @@slave_exec_mode=IDEMPOTENT, the slave should not try to
>> +# insert the row and proceed normally.
>> +#
>> +# - The slave SQL thread sees a 'DELETE' of a row that does not exist.
>> +# In this case, the slave should ignore the event and proceed
>> +# normally.
>
> actually the DELETE case is a symmetric to INSERT to obey
> @@slave_exec_mode.
> Could you please unite the last paragraph with the 2nd to convert them
> into something like this
>
> sees an 'INSERT'... or a 'DELETE' ... the slave behavior depends ...
>
> ?
>
>> +#
>> +# This test was previously named rpl_stm_mystery22/rpl_row_mystery22.
>> +#
>> +#
>> +# ==== Method ====
>> +#
>> +# Create a table on master and slave, insert a row on slave, and
>> +# insert the same row on master.
>> +#
>> +# Create a table on master and slave, insert a row on master with
>> +# binlogging turned off, and remove the row on master with binlogging
>> +# turned on.
>> +#
>> +#
>> +# ==== Related bugs ====
>> +#
>> +# BUG#31552: Replication breaks when deleting rows from out-of-sync table
> without PK
>> +# BUG#31609: Not all RBR slave errors reported as errors
>> +#
>> +# Bug in this test case:
>> +# BUG#37718: rpl.rpl_stm_mystery22 fails sporadically on pushbuild
>> +#
>> +#
>> +# ==== Usage ====
>> +#
>> +# This file assumes the following:
>> +#
>> +# - The test language variable $expect_slave_error_on_duplicate_key is
>> +# set to 1 if the slave is expected to stop on duplicate key errors
>> +# (i.e., if the binlog is in statement mode or
>> +# @@global.slave_exec_mode=STRICT). It is set to 0 otherwise.
>> +#
>> +# - Replication has been initialized by include/master-slave.inc
>>
>> --- source include/have_binlog_format_mixed_or_statement.inc
>> --- source include/master-slave.inc
>>
>> -# first, cause a duplicate key problem on the slave
>> -create table t1(n int auto_increment primary key, s char(10));
>> +--echo ==== Initialize ====
>> +
>> +--echo [on master]
>> +connection master;
>> +CREATE TABLE t1(n INT AUTO_INCREMENT PRIMARY KEY, s CHAR(10));
>> +--echo [on slave]
>> sync_slave_with_master;
>> -insert into t1 values (2,'old');
>> +
>> +
>> +--echo ==== Test: SQL thread sees 'INSERT' of existing key ====
>> +
>> +--echo ---- Prepare slave so that it will get duplicate key error ----
>> +# This row will be in the way of the row inserted by master.
>> +INSERT INTO t1 VALUES (2,'old');
>> +
>> +--echo ---- Insert rows on master ----
>> +--echo [on master]
>> connection master;
>> -insert into t1 values(NULL,'new');
>> -insert into t1 values(NULL,'new');
>> +# Insert the same row on master
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +INSERT INTO t1 VALUES(NULL,'new');
>> save_master_pos;
>> +SELECT * FROM t1 ORDER BY n;
>> +
>> +--echo [on slave]
>> connection slave;
>> -# wait until the slave tries to run the query, fails and aborts slave thread
>
>> -let $slave_sql_errno= 1062;
>
> could not get it how the line above is marked deleted when it never
> existed... Some feature of procucing diff agaist being deleted file?
> Or you have two commits and the current is the last one?
I moved suite/rpl/t/rpl_stm_mystery22.test to
extra/rpl_tests/rpl_conflicts.test because I wanted to retain version
history in the file most equivalent to the old file. Notice the diff header:
=== renamed file 'mysql-test/suite/rpl/t/rpl_stm_mystery22.test' =>
'mysql-test/extra/rpl_tests/rpl_conflicts.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_mystery22.test 2008-12-12 11:40:22
+0000
+++ b/mysql-test/extra/rpl_tests/rpl_conflicts.test 2009-01-05 15:36:51
+0000
>
>> -source include/wait_for_slave_sql_error.inc;
>> -select * from t1 order by n;
>> -delete from t1 where n = 2;
>> ---disable_warnings
>> -start slave;
>> ---enable_warnings
>> +
>> +# If we are in statement mode or if slave_exec_mode=STRICT, we now
>> +# expect to see an error on the slave. Otherwise, we expect that the
>> +# duplicate row is ignored by the slave and replication continues.
>> +if ($expect_slave_error_on_duplicate_key) {
>> + --echo ---- Wait until slave stops with an error ----
>> + # Wait until the slave tries to run the query, fails with duplicate
>> + # key error, and stops the SQL thread.
>
>> + let $slave_sql_errno= 1062;
>
> I would prefer the code to be in the symbolic form. Not a big deal for
> me, a replicant :-), to adjust a shifted number should it change in a
> (near!) future, but that's not gonna be fun for some.
> They will hunt us down like Harrison Ford's character in Blade Runner.
>
> I can not come up with a clever idea how to make it symbolic though,
> at the moment... Some help from mysqltest that parses --error in symb
> format seems inevitable.
I agree, I'd prefer the symbolic form too, but it seems hard to do since
Slave_SQL_Errno is a number. We would need to augment either the server
or mysqltest to add a feature to convert between the two.
Hmm, mysqltest already knows the mapping internally, so I guess it
wouldn't be too hard to make mysqltest add a table to the mtr database
that contains a mapping between symbolic names and numbers. It's not for
this bug, but you may like to open a bug report for that if you like...
>
>> + source include/wait_for_slave_sql_error.inc;
>> + let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
>> + --echo Last_SQL_Error = $err (expected duplicate key error)
>> + SELECT * FROM t1 ORDER BY n;
>> +
>> + --echo ---- Resolve the problem on the slave and restart SQL thread ----
>> + DELETE FROM t1 WHERE n = 2;
>> + START SLAVE SQL_THREAD;
>> + source include/wait_for_slave_sql_to_start.inc;
>> +}
>> +
>> +--echo ---- Sync slave and verify that there is no error ----
>> sync_with_master;
>> -#now the buggy slave would be confused on the offset but it can replicate
>> -#in order to make it break, we need to stop/start the slave one more time
>> -stop slave;
>> +let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
>> +--echo Last_SQL_Error = '$err' (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +
>> +
>> +--echo ==== Test: SQL thread sees 'DELETE' of non-existing row ====
>> +
>> +--echo ---- On master, insert two rows, the second with binlogging off ----
>> +--echo [on master]
>> connection master;
>> -# to be able to really confuse the slave, we need some non-auto-increment
>> -# events in the log
>> -create table t2(n int);
>> -drop table t2;
>> -insert into t1 values(NULL,'new');
>> -# what happens when we delete a row which does not exist on slave?
>> -set sql_log_bin=0;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=1;
>> -delete from t1 where n=4;
>> +DELETE FROM t1;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=0;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=1;
>> +
>> +--echo ---- On master, remove the row that does not exist on slave ----
>> +DELETE FROM t1 WHERE n=2;
>> +SELECT * FROM t1 ORDER BY n;
>> save_master_pos;
>> +
>> +--echo ---- On slave, verify that no error happened ----
>> +--echo [on slave]
>> connection slave;
>> ---disable_warnings
>> -start slave;
>> ---enable_warnings
>> -#now the truth comes out - if the slave is buggy, it will never sync because
>> -#the slave thread is not able to read events
>> +# The slave should sync ok, and SHOW SLAVE STATUS should give no
>> +# error.
>> sync_with_master;
>> -select * from t1 order by n;
>> -#clean up
>> +let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
>> +--echo Last_SQL_Error = $err (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +
>> +
>> +--echo ==== Clean up ====
>> +
>> +--echo [on master]
>> connection master;
>> -drop table t1;
>> -sync_slave_with_master;
>> +DROP TABLE t1;
>>
>> -# End of 4.1 tests
>> +--echo [on slave]
>> +sync_slave_with_master;
>>
>> === modified file 'mysql-test/include/wait_for_slave_sql_error.inc'
>> --- a/mysql-test/include/wait_for_slave_sql_error.inc 2008-12-12 11:40:22 +0000
>> +++ b/mysql-test/include/wait_for_slave_sql_error.inc 2009-01-05 15:36:51 +0000
>> @@ -1,7 +1,8 @@
>> # ==== Purpose ====
>> #
>> # Waits until the SQL thread of the current connection has got an
>> -# error, or until a timeout is reached.
>> +# error, or until a timeout is reached. Also waits until the SQL
>> +# thread has completely stopped.
>> #
>> # ==== Usage ====
>> #
>> @@ -10,28 +11,31 @@
>> # Parameters:
>> #
>> # $slave_sql_errno
>> -# Number of expected SQL error. If it skipped then any error
>> -# will pass.
>> +# The expected SQL error number. This is required.
>> #
>> -# $slave_timeout and
>> -# See wait_for_slave_param.inc for descriptions.
>> +# $slave_timeout
>> +# See wait_for_slave_param.inc for description.
>> #
>> -# $slave_keep_connection.
>> -# See wait_for_slave_param.inc for descriptions.
>> +# $slave_keep_connection
>> +# See wait_for_slave_param.inc for description.
>> +
>> +if (`SELECT "$slave_sql_errno" = ""`) {
>> + --echo !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing
> wait_fro_slave_sql_error.inc
>> + exit;
>> +}
>>
>> let $old_slave_param_comparison= $slave_param_comparison;
>> +let $slave_param_comparison= =;
>>
>> let $slave_param= Last_SQL_Errno;
>> -let $slave_param_comparison= !=;
>> -let $slave_param_value= 0;
>> -
>> -if ($slave_sql_errno) {
>> - let $slave_param_comparison= =;
>> - let $slave_param_value= $slave_sql_errno;
>> -}
>> -
>> +let $slave_param_value= $slave_sql_errno;
>> let $slave_error_message= Failed while waiting for slave to produce an error in
> its sql thread;
>> source include/wait_for_slave_param.inc;
>> -let $slave_error_message= ;
>>
>> +let $slave_param= Slave_SQL_Running;
>> +let $slave_param_value= No;
>> +let $slave_error_message= Failed while waiting for slave to stop the SQL thread
> after error in the SQL thread;
>> +source include/wait_for_slave_param.inc;
>> +
>> +let $slave_error_message= ;
>> let $slave_param_comparison= $old_slave_param_comparison;
>>
>> === modified file 'mysql-test/include/wait_for_slave_sql_error_and_skip.inc'
>> --- a/mysql-test/include/wait_for_slave_sql_error_and_skip.inc 2008-11-12
> 17:51:47 +0000
>> +++ b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc 2009-01-05
> 15:36:51 +0000
>> @@ -5,7 +5,8 @@
>> #
>> # ==== Usage ====
>> #
>> -# let show_sql_error=0|1;
>> +# let $show_sql_error=0|1;
>> +# let $slave_sql_error=ERRNO
>> # source include/wait_for_slave_sql_error_and_skip.inc;
>>
>> echo --source include/wait_for_slave_sql_error_and_skip.inc;
>> @@ -17,9 +18,6 @@ if ($show_sql_error)
>> echo Last_SQL_Error = $error;
>> }
>>
>> -# wait for SQL thread to stop after the error
>> -source include/wait_for_slave_sql_to_stop.inc;
>> -
>> # skip the erroneous statement
>> set global sql_slave_skip_counter=1;
>> source include/start_slave.inc;
>>
>> === renamed file 'mysql-test/suite/rpl/r/rpl_row_mystery22.result' =>
> 'mysql-test/suite/rpl/r/rpl_row_conflicts.result'
>> --- a/mysql-test/suite/rpl/r/rpl_row_mystery22.result 2007-12-12 10:14:59 +0000
>> +++ b/mysql-test/suite/rpl/r/rpl_row_conflicts.result 2009-01-05 15:36:51 +0000
>> @@ -4,29 +4,108 @@ reset master;
>> reset slave;
>> drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
>> start slave;
>> -create table t1(n int auto_increment primary key, s char(10));
>> +######## Run with slave_exec_mode=STRICT ########
>> +==== Initialize ====
>> +[on master]
>> +CREATE TABLE t1(n INT AUTO_INCREMENT PRIMARY KEY, s CHAR(10));
>> +[on slave]
>> +==== Test: SQL thread sees 'INSERT' of existing key ====
>> +---- Prepare slave so that it will get duplicate key error ----
>> +INSERT INTO t1 VALUES (2,'old');
>> +---- Insert rows on master ----
>> +[on master]
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +1 new
>> +2 new
>> +[on slave]
>> +---- Wait until slave stops with an error ----
>> +Last_SQL_Error = Could not execute Write_rows event on table test.t1; Duplicate
> entry '2' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the
> event's master log master-bin.000001, end_log_pos 599 (expected duplicate key error)
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +1 new
>> +2 old
>> +---- Resolve the problem on the slave and restart SQL thread ----
>> +DELETE FROM t1 WHERE n = 2;
>> +START SLAVE SQL_THREAD;
>> +---- Sync slave and verify that there is no error ----
>> +Last_SQL_Error = '' (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +1 new
>> +2 new
>> +==== Test: SQL thread sees 'DELETE' of non-existing row ====
>> +---- On master, insert two rows, the second with binlogging off ----
>> +[on master]
>> +DELETE FROM t1;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=0;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=1;
>> +---- On master, remove the row that does not exist on slave ----
>> +DELETE FROM t1 WHERE n=2;
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +3 new
>> +4 new
>> +---- On slave, verify that no error happened ----
>> +[on slave]
>> +Last_SQL_Error = (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +3 new
>> +==== Clean up ====
>> +[on master]
>> +DROP TABLE t1;
>> +[on slave]
>> +######## Run with slave_exec_mode=IDEMPOTENT ########
>> set @@global.slave_exec_mode= 'IDEMPOTENT';
>> -insert into t1 values (2,'old');
>> -insert into t1 values(NULL,'new');
>> -insert into t1 values(NULL,'new');
>> -select * from t1 order by n;
>> +==== Initialize ====
>> +[on master]
>> +CREATE TABLE t1(n INT AUTO_INCREMENT PRIMARY KEY, s CHAR(10));
>> +[on slave]
>> +==== Test: SQL thread sees 'INSERT' of existing key ====
>> +---- Prepare slave so that it will get duplicate key error ----
>> +INSERT INTO t1 VALUES (2,'old');
>> +---- Insert rows on master ----
>> +[on master]
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SELECT * FROM t1 ORDER BY n;
>> n s
>> 1 new
>> 2 new
>> -delete from t1 where n = 2;
>> -start slave;
>> -stop slave;
>> -create table t2(n int);
>> -drop table t2;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=0;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=1;
>> -delete from t1 where n=4;
>> -start slave;
>> -select * from t1 order by n;
>> +[on slave]
>> +---- Sync slave and verify that there is no error ----
>> +Last_SQL_Error = '' (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> n s
>> 1 new
>> +2 new
>> +==== Test: SQL thread sees 'DELETE' of non-existing row ====
>> +---- On master, insert two rows, the second with binlogging off ----
>> +[on master]
>> +DELETE FROM t1;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=0;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=1;
>> +---- On master, remove the row that does not exist on slave ----
>> +DELETE FROM t1 WHERE n=2;
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +3 new
>> +4 new
>> +---- On slave, verify that no error happened ----
>> +[on slave]
>> +Last_SQL_Error = (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> 3 new
>> -drop table t1;
>> +==== Clean up ====
>> +[on master]
>> +DROP TABLE t1;
>> +[on slave]
>> set @@global.slave_exec_mode= default;
>>
>> === renamed file 'mysql-test/suite/rpl/r/rpl_stm_mystery22.result' =>
> 'mysql-test/suite/rpl/r/rpl_stm_conflicts.result'
>> --- a/mysql-test/suite/rpl/r/rpl_stm_mystery22.result 2007-06-27 12:28:02 +0000
>> +++ b/mysql-test/suite/rpl/r/rpl_stm_conflicts.result 2009-01-05 15:36:51 +0000
>> @@ -4,28 +4,58 @@ reset master;
>> reset slave;
>> drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
>> start slave;
>> -create table t1(n int auto_increment primary key, s char(10));
>> -insert into t1 values (2,'old');
>> -insert into t1 values(NULL,'new');
>> -insert into t1 values(NULL,'new');
>> -select * from t1 order by n;
>> +==== Initialize ====
>> +[on master]
>> +CREATE TABLE t1(n INT AUTO_INCREMENT PRIMARY KEY, s CHAR(10));
>> +[on slave]
>> +==== Test: SQL thread sees 'INSERT' of existing key ====
>> +---- Prepare slave so that it will get duplicate key error ----
>> +INSERT INTO t1 VALUES (2,'old');
>> +---- Insert rows on master ----
>> +[on master]
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +1 new
>> +2 new
>> +[on slave]
>> +---- Wait until slave stops with an error ----
>> +Last_SQL_Error = Error 'Duplicate entry '2' for key 'PRIMARY'' on query. Default
> database: 'test'. Query: 'INSERT INTO t1 VALUES(NULL,'new')' (expected duplicate key
> error)
>> +SELECT * FROM t1 ORDER BY n;
>> n s
>> 1 new
>> 2 old
>> -delete from t1 where n = 2;
>> -start slave;
>> -stop slave;
>> -create table t2(n int);
>> -drop table t2;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=0;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=1;
>> -delete from t1 where n=4;
>> -start slave;
>> -select * from t1 order by n;
>> +---- Resolve the problem on the slave and restart SQL thread ----
>> +DELETE FROM t1 WHERE n = 2;
>> +START SLAVE SQL_THREAD;
>> +---- Sync slave and verify that there is no error ----
>> +Last_SQL_Error = '' (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> n s
>> 1 new
>> 2 new
>> +==== Test: SQL thread sees 'DELETE' of non-existing row ====
>> +---- On master, insert two rows, the second with binlogging off ----
>> +[on master]
>> +DELETE FROM t1;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=0;
>> +INSERT INTO t1 VALUES(NULL,'new');
>> +SET sql_log_bin=1;
>> +---- On master, remove the row that does not exist on slave ----
>> +DELETE FROM t1 WHERE n=2;
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> +3 new
>> +4 new
>> +---- On slave, verify that no error happened ----
>> +[on slave]
>> +Last_SQL_Error = (expected no error)
>> +SELECT * FROM t1 ORDER BY n;
>> +n s
>> 3 new
>> -drop table t1;
>> +==== Clean up ====
>> +[on master]
>> +DROP TABLE t1;
>> +[on slave]
>>
>> === modified file 'mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test'
>> --- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test 2008-09-06 00:51:17
> +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test 2009-01-05 15:36:51
> +0000
>> @@ -124,9 +124,11 @@ UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.
>> sync_slave_with_master;
>> connection master;
>>
>> -# Parameter for include/wait_for_slave_sql_error_and_skip.inc, ask it
>> -# to show SQL error message
>> -let show_sql_error=1;
>> +# Parameters for include/wait_for_slave_sql_error_and_skip.inc:
>> +# Ask it to show SQL error message.
>> +let $show_sql_error= 1;
>> +# The expected error will always be 1146 (ER_NO_SUCH_TABLE).
>> +let $slave_sql_errno= 1146;
>>
>> #
>> # Only do tables are referenced for update, these statements should
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_row_conflicts.test'
>> --- a/mysql-test/suite/rpl/t/rpl_row_conflicts.test 1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_row_conflicts.test 2009-01-05 15:36:51 +0000
>> @@ -0,0 +1,28 @@
>> +# See the top of mysql-test/extra/rpl_tests/rpl_conflicts.test for
>> +# explanation of what this test does.
>> +#
>> +# This test file is for row mode. It runs the test twice, with
>> +# slave_exec_mode=STRICT and slave_exec_mode=IDEMPOTENT, respectively.
>> +
>> +source include/have_binlog_format_row.inc;
>> +source include/master-slave.inc;
>> +
>> +
>> +--echo ######## Run with slave_exec_mode=STRICT ########
>
> I think we need either to check the default or to assign STRICT
> explicitly. Your opinion?
I agree, I'll make it explicitly set the option.
>
>> +
>> +let $expect_slave_error_on_duplicate_key= 1;
>> +source extra/rpl_tests/rpl_conflicts.test;
>> +
>> +
>> +--echo ######## Run with slave_exec_mode=IDEMPOTENT ########
>> +connection slave;
>> +set @@global.slave_exec_mode= 'IDEMPOTENT';
>> +
>> +let $expect_slave_error_on_duplicate_key= 0;
>> +source extra/rpl_tests/rpl_conflicts.test;
>> +
>> +connection slave;
>> +set @@global.slave_exec_mode= default;
>> +
>> +
>> +source include/master-slave-end.inc;
>>
>> === removed file 'mysql-test/suite/rpl/t/rpl_row_mystery22.test'
>> --- a/mysql-test/suite/rpl/t/rpl_row_mystery22.test 2007-12-12 10:14:59 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_row_mystery22.test 1970-01-01 00:00:00 +0000
>> @@ -1,52 +0,0 @@
>> -# Originally taken from rpl_mystery22.test,
>> -# but this row-based-replication test has a totally different spirit:
>> -# slave will not stop because of dup key,
>> -# instead we test if it does overwrite the dup key
>> -# as expected.
>> --- source include/have_binlog_format_row.inc
>> --- source include/master-slave.inc
>> -
>> -# first, cause a duplicate key problem on the slave
>> -create table t1(n int auto_increment primary key, s char(10));
>> -sync_slave_with_master;
>> -
>> -# bug#31552/31609 idempotency is not default any longer
>> -# so that the declared in heading comments aim of the test
>> -# should be backed up with explicit setting of the slave mode
>> -set @@global.slave_exec_mode= 'IDEMPOTENT';
>> -
>> -insert into t1 values (2,'old');
>> -connection master;
>> -insert into t1 values(NULL,'new');
>> -insert into t1 values(NULL,'new');
>> -save_master_pos;
>> -connection slave;
>> -sync_with_master;
>> -select * from t1 order by n;
>> -delete from t1 where n = 2;
>> ---disable_warnings
>> -start slave;
>> ---enable_warnings
>> -sync_with_master;
>> -stop slave;
>> -connection master;
>> -create table t2(n int);
>> -drop table t2;
>> -insert into t1 values(NULL,'new');
>> -# what happens when we delete a row which does not exist on slave?
>> -set sql_log_bin=0;
>> -insert into t1 values(NULL,'new');
>> -set sql_log_bin=1;
>> -delete from t1 where n=4;
>> -save_master_pos;
>> -connection slave;
>> ---disable_warnings
>> -start slave;
>> ---enable_warnings
>> -sync_with_master;
>> -select * from t1 order by n;
>> -#clean up
>> -connection master;
>> -drop table t1;
>> -sync_slave_with_master;
>> -set @@global.slave_exec_mode= default;
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_stm_conflicts.test'
>> --- a/mysql-test/suite/rpl/t/rpl_stm_conflicts.test 1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_stm_conflicts.test 2009-01-05 15:36:51 +0000
>> @@ -0,0 +1,12 @@
>> +# See the top of mysql-test/extra/rpl_tests/rpl_conflicts.test for an
>> +# explanation of what is going on.
>> +#
>> +# This test file is for statement mode.
>> +
>> +source include/have_binlog_format_mixed_or_statement.inc;
>> +source include/master-slave.inc;
>> +
>> +let $expect_slave_error_on_duplicate_key= 1;
>> +source extra/rpl_tests/rpl_conflicts.test;
>> +
>> +source include/master-slave-end.inc;
>>
>>
>> --
>> MySQL Code Commits Mailing List
>> For list archives: http://lists.mysql.com/commits
>> To unsubscribe: http://lists.mysql.com/commits?unsub=1
>>
--
Sven Sandberg, Software Engineer
MySQL AB, www.mysql.com