List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:March 25 2011 8:16pm
Subject:Re: bzr commit into mysql-trunk branch (andrei.elkin:3311) Bug#11748510
View as plain text  
Hi Andrei,

Patch not approved. See comments in-line.

I think we should define when and how to use the report class and not
directly call my_error or similar function provided by the server.
This is not clear to me and I am not sure if the report class is beeing
used correctly.

Is this class really necessary? We should create a WL to either improve
its usage or get rid of it.

Cheers.


On 03/25/2011 10:29 AM, Andrei Elkin wrote:
> #At file:///home/andrei/MySQL/BZR/2a-23May/FIXES/bug11748510_36524-deadlock_overdram/
> based on revid:magne.mahre@stripped
> 
>  3311 Andrei Elkin	2011-03-25
>       bug#11748510 incident of deadlock on slave is overdramatized
>       
>       In cases of temporary errors in replication event execution (deadlock,
>       timeout) the error log gained an overreacting error message whereas
>       just a warning would be fine.
>       
>       Fixed with checking of the temporary status of the error inside
>       Slave_reporting_capability::report() to demote the error to the
>       warning level if needed. 
>       The warning gets converted into the error
>       whenever number of successive attempts to re-apply the event(s) gets
>       equal to @@global.slave_trans_retries.
>       
>       The patch also changes the slave service error gathering and reporting
>       as the following.
>       Slave_reporting_capability::report() populates 
>       thd->main_da the standard placeholder for the errors and calls the stderr
> writers 
>       for errors and lesser severity levels as specified by
>       @@global_system_variables.log_warnings.
>       That said  report() mimics my_error().
>       Slave_reporting_capability::display() is introduced to display errors 
>       through show-slave-status interfaces.
>       The latter mimics send_error().
>       Overall the changes 
>       a. print out all errors that SQL thread met during a failing execution,
>       b. make Last_SQL_error more informative to list all the errors.
>       
>       Some number of test result files got affected and in some cases the
>       new results revealed issues in the old versions. This patch contains a
>       limited part dealing with the tests. See the following commit that
>       completes the fixes.
>      @ mysql-test/extra/rpl_tests/rpl_deadlock.test
>         regression test is added to prove a temporary failure warning is escalated.
>      @ mysql-test/extra/rpl_tests/rpl_loaddata.test
>         More sensible Unknown error rather than one with code 0 is reported by the
> server.
>      @ mysql-test/extra/rpl_tests/rpl_stm_EE_err2.test
>         More sensible Unknown error rather than one with code 0 is reported by the
> server.
>      @ mysql-test/suite/rpl/r/rpl_binlog_errors.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_checksum.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_deadlock_innodb.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_idempotency.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_init_slave_errors.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_known_bugs_detection.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_loaddata.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_packet.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_row_conflicts.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_stm_EE_err2.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_stm_conflicts.result
>         results get updated.
>      @ mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result
>         More sensible Unknown error rather than one with code 0 is reported by the
> server.
>      @ mysql-test/suite/rpl/t/rpl_idempotency.test
>         the final print-out of SQL thread diag area revealed messages that are
>         benign and needs suppression.
>      @ sql/log_event.cc
>         treating rli->report() as an error reporting similar to my_error().
>         Gathering errors in the diag area should be completed with displaying
>         via rli->display() each time a slave thread breaks the applying loop.
>         Relocating clear_all_errors() definition into rpl_slave.cc.
>      @ sql/rpl_reporting.cc
>         report() method is turned to be a wrapper of functions dealing with
>         the diag area like my_error() and ones with the error log.  One of its
>         use case to register an error and print it out the error log.  A new
>         display() method copies the gathered errors the area of the Show
>         Slave Status when a slave thread is about to exit.
>         
>         A special caution (not perfect, todo is written) is done to not bring in 
>         unreferrable objects to the embedded library.
>      @ sql/rpl_reporting.h
>          a new display() method added as well as comments for report().
>      @ sql/rpl_slave.cc
>         exporting has_temporary_error() to be used in rpl_reporting.cc;
>         docking definition of clear_all_errors() to use in both modules;
>         run-out-of-tries case is finished with raising on the fatal error flag;
>         finalizing the error branch of events execution with display() to
>         make gathered error be saved in show-slave-status area;
>         deploying display() at the end of io-thread and sql-thread.
>         The farewell print-out of the gathered errors at error branch of
> handle_slave_sql() is removed as redundant.
>      @ sql/rpl_slave.h
>         exporting functions shared with slave.cc, rpl_reporting.cc, log_event.cc.
> 
>     modified:
>       mysql-test/extra/rpl_tests/rpl_deadlock.test
>       mysql-test/extra/rpl_tests/rpl_loaddata.test
>       mysql-test/extra/rpl_tests/rpl_stm_EE_err2.test
>       mysql-test/suite/rpl/r/rpl_binlog_errors.result
>       mysql-test/suite/rpl/r/rpl_checksum.result
>       mysql-test/suite/rpl/r/rpl_deadlock_innodb.result
>       mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result
>       mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result
>       mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result
>       mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result
>       mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
>       mysql-test/suite/rpl/r/rpl_idempotency.result
>       mysql-test/suite/rpl/r/rpl_init_slave_errors.result
>       mysql-test/suite/rpl/r/rpl_known_bugs_detection.result
>       mysql-test/suite/rpl/r/rpl_loaddata.result
>       mysql-test/suite/rpl/r/rpl_packet.result
>       mysql-test/suite/rpl/r/rpl_row_conflicts.result
>       mysql-test/suite/rpl/r/rpl_stm_EE_err2.result
>       mysql-test/suite/rpl/r/rpl_stm_conflicts.result
>       mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result
>       mysql-test/suite/rpl/t/rpl_idempotency.test
>       sql/log_event.cc
>       sql/rpl_reporting.cc
>       sql/rpl_reporting.h
>       sql/rpl_slave.cc
>       sql/rpl_slave.h
> === modified file 'mysql-test/extra/rpl_tests/rpl_deadlock.test'
> --- a/mysql-test/extra/rpl_tests/rpl_deadlock.test	2010-12-19 17:07:28 +0000
> +++ b/mysql-test/extra/rpl_tests/rpl_deadlock.test	2011-03-25 10:29:46 +0000
> @@ -10,6 +10,10 @@
>  
>  --source include/master-slave.inc
>  
> +connection slave;
> +call mtr.add_suppression("Could not execute Write_rows event on table
> test.t1,handler error HA_ERR_LOCK_WAIT_TIMEOUT");
> +connection master;
> +
>  # 0) Prepare tables and data
>  --echo *** Prepare tables and data ***
>  
> @@ -123,6 +127,58 @@ SELECT * FROM t3;
>  source include/check_slave_is_running.inc;
>  --echo
>  
> +#
> +# bug#11748510/36524 incident of deadlock on slave is overdramatized
> +#
> +# Observe that the slave stopped when the number of transation retries 
> +# exceeds @@global.slave_transaction_retries
> +#
> +connection master;
> +
> +--echo *** Test the deadlock warning to be escalated into the error ***
> +
> +delete from t1;
> +delete from t2;
> +delete from t3;
> +
> +sync_slave_with_master;
> +
> +# make sure slave's unilateral row gone as well
> +delete from t1;
> +delete from t2;
> +delete from t3;
> +
> +# the first attempt to run a deadlock scenario of p 1) leads to the error
> +set @save.slave_transaction_retries= @@global.slave_transaction_retries;
> +set @@global.slave_transaction_retries= 0;
> +source include/stop_slave.inc;
> +
> +connection master;
> +
> +BEGIN;
> +INSERT INTO t1 VALUES (1);
> +# We make a long transaction here
> +INSERT INTO t2 VALUES (2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
> +INSERT INTO t3 VALUES (3);
> +COMMIT;
> +
> +connection slave;
> +BEGIN;
> +SELECT count(*) as zero FROM t1 FOR UPDATE;
> +
> +start slave;
> +
> +--echo *** Now the slave must be stopped due to deadlock ***
> +
> +# slow slave environment can report ER_LOCK_TIMEOUT
> +let $slave_sql_errno= 1213, 1205; # ER_LOCK_DEADLOCK or TIMEOUT
> +let $show_slave_sql_error= 0;
> +source include/wait_for_slave_sql_error.inc;
> +
> +rollback;
> +
> +set @@global.slave_transaction_retries= @save.slave_transaction_retries;
> +source include/start_slave.inc;
>  # Clean up
>  --echo *** Clean up ***
>  connection master;
> 
> === modified file 'mysql-test/extra/rpl_tests/rpl_loaddata.test'
> --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test	2011-03-25 10:29:46 +0000
> @@ -70,7 +70,7 @@ save_master_pos;
>  connection slave;
>  # 1062 = ER_DUP_ENTRY
>  call mtr.add_suppression("Slave SQL.*Error .Duplicate entry .10. for key .b.. on
> query.* Error_code: 1062");
> -call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 0");
> +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 1105");
>  --let $slave_sql_errno= 1062
>  --source include/wait_for_slave_sql_error_and_skip.inc
>  
> @@ -157,7 +157,7 @@ if (`SELECT @@global.binlog_format != 'R
>  {
>    # Query causes error on master but not on slave. This causes the slave to
>    # stop with error code 0 (which is wrong: see BUG#57287)
> -  --let $slave_sql_errno= 0
> +  --let $slave_sql_errno= 1105
>    --source include/wait_for_slave_sql_error.inc
>    drop table t1, t2;
>  }
> 
> === modified file 'mysql-test/extra/rpl_tests/rpl_stm_EE_err2.test'
> --- a/mysql-test/extra/rpl_tests/rpl_stm_EE_err2.test	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/extra/rpl_tests/rpl_stm_EE_err2.test	2011-03-25 10:29:46 +0000
> @@ -24,9 +24,9 @@ insert into t1 values(1),(2);
>  drop table t1;
>  
>  connection slave;
> -call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.* error code=1062.*Error on slave:.* Error_code: 0");
> +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.* error code=1062.*Error on slave:.* Error_code: 1105");
>  --echo (expect different error codes on master and slave)
> ---let $slave_sql_errno= 0
> +--let $slave_sql_errno= 1105
>  --let $show_slave_sql_error= 1
>  --source include/wait_for_slave_sql_error.inc
>  drop table t1;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_binlog_errors.result'
> --- a/mysql-test/suite/rpl/r/rpl_binlog_errors.result	2010-12-22 09:17:12 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_binlog_errors.result	2011-03-25 10:29:46 +0000
> @@ -234,7 +234,8 @@ include/stop_slave.inc
>  SET GLOBAL debug="+d,error_unique_log_filename";
>  START SLAVE io_thread;
>  include/wait_for_slave_io_error.inc [errno=1595]
> -Last_IO_Error = 'Relay log write failure: could not queue event from master'
> +Last_IO_Error = 'Can't generate a unique log-filename slave-relay-bin.(1-999)
> +, Error_code: 1098; Relay log write failure: could not queue event from master,
> Error_code: 1595; Relay log write failure: could not queue event from master'
>  SET GLOBAL debug="-d,error_unique_log_filename";
>  SET GLOBAL debug=@old_debug;
>  include/rpl_restart_server.inc [server_number=2]
> @@ -244,7 +245,7 @@ include/stop_slave.inc
>  SET GLOBAL debug="+d,fault_injection_new_file_rotate_event";
>  START SLAVE io_thread;
>  include/wait_for_slave_io_error.inc [errno=1595]
> -Last_IO_Error = 'Relay log write failure: could not queue event from master'
> +Last_IO_Error = 'Can't open file: 'slave-relay-bin' (errno: 2), Error_code: 1026;
> Relay log write failure: could not queue event from master, Error_code: 1595; Relay log
> write failure: could not queue event from master'
>  SET GLOBAL debug="-d,fault_injection_new_file_rotate_event";
>  SET GLOBAL debug=@old_debug;
>  include/rpl_restart_server.inc [server_number=2]
> @@ -254,7 +255,7 @@ include/stop_slave.inc
>  SET GLOBAL debug="+d,fault_injection_registering_index";
>  START SLAVE io_thread;
>  include/wait_for_slave_io_error.inc [errno=1595]
> -Last_IO_Error = 'Relay log write failure: could not queue event from master'
> +Last_IO_Error = 'Can't open file: './slave-relay-bin.000006' (errno: 1), Error_code:
> 1016; Relay log write failure: could not queue event from master, Error_code: 1595; Relay
> log write failure: could not queue event from master'
>  SET GLOBAL debug="-d,fault_injection_registering_index";
>  SET GLOBAL debug=@old_debug;
>  include/rpl_restart_server.inc [server_number=2]
> @@ -264,7 +265,7 @@ include/stop_slave.inc
>  SET GLOBAL debug="+d,fault_injection_openning_index";
>  START SLAVE io_thread;
>  include/wait_for_slave_io_error.inc [errno=1595]
> -Last_IO_Error = 'Relay log write failure: could not queue event from master'
> +Last_IO_Error = 'Can't open file: './slave-relay-bin.index' (errno: 1), Error_code:
> 1016; Relay log write failure: could not queue event from master, Error_code: 1595; Relay
> log write failure: could not queue event from master'

I think we also need to avoid printing the last message. Notice that there are three error
messages and the last one
is duplicated. Please, check also with support if this verbose output is ok.


>  SET GLOBAL debug="-d,fault_injection_openning_index";
>  SET GLOBAL debug=@old_debug;
>  include/rpl_restart_server.inc [server_number=2]
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_checksum.result'
> --- a/mysql-test/suite/rpl/r/rpl_checksum.result	2011-03-08 19:12:46 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_checksum.result	2011-03-25 10:29:46 +0000
> @@ -81,7 +81,7 @@ create table t2 (a int);
>  set @@global.debug='d,simulate_checksum_test_failure';
>  start slave io_thread;
>  include/wait_for_slave_io_error.inc [errno=1595]
> -Last_IO_Error = 'Relay log write failure: could not queue event from master'
> +Last_IO_Error = 'Replication event checksum verification failed while reading from
> network., Error_code: 1722; Relay log write failure: could not queue event from master'
>  set @@global.debug='';
>  start slave io_thread;
>  include/wait_for_slave_param.inc [Read_Master_Log_Pos]
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_deadlock_innodb.result'
> --- a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result	2010-12-19 17:22:30 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result	2011-03-25 10:29:46 +0000
> @@ -1,5 +1,6 @@
>  include/master-slave.inc
>  [connection master]
> +call mtr.add_suppression("Could not execute Write_rows event on table
> test.t1,handler error HA_ERR_LOCK_WAIT_TIMEOUT");
>  *** Prepare tables and data ***
>  CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=innodb;
>  CREATE TABLE t2 (a INT) ENGINE=innodb;
> @@ -103,6 +104,31 @@ a
>  3
>  include/check_slave_is_running.inc
>  
> +*** Test the deadlock warning to be escalated into the error ***
> +delete from t1;
> +delete from t2;
> +delete from t3;
> +delete from t1;
> +delete from t2;
> +delete from t3;
> +set @save.slave_transaction_retries= @@global.slave_transaction_retries;
> +set @@global.slave_transaction_retries= 0;
> +include/stop_slave.inc
> +BEGIN;
> +INSERT INTO t1 VALUES (1);
> +INSERT INTO t2 VALUES (2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
> +INSERT INTO t3 VALUES (3);
> +COMMIT;
> +BEGIN;
> +SELECT count(*) as zero FROM t1 FOR UPDATE;
> +zero
> +0
> +start slave;
> +*** Now the slave must be stopped due to deadlock ***
> +include/wait_for_slave_sql_error.inc [errno=1213, 1205]
> +rollback;
> +set @@global.slave_transaction_retries= @save.slave_transaction_retries;
> +include/start_slave.inc
>  *** Clean up ***
>  DROP TABLE t1,t2,t3;
>  SET global max_relay_log_size= @my_max_relay_log_size;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result'
> --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result	2011-03-25 10:29:46
> +0000
> @@ -613,7 +613,7 @@ c1	c3	hex(c4)	c5	c6
>  * Bug30415 *
>  ************
>  include/wait_for_slave_sql_error.inc [errno=1091]
> -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query.
> Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7''
> +Last_SQL_Error = 'Can't DROP 'c7'; check that column/key exists, Error_code: 1091;
> Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'.
> Query: 'ALTER TABLE t14 DROP COLUMN c7''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> @@ -662,7 +662,7 @@ c1	hex(c4)	c5	c6	c7	c2
>  ********************************************
>  
>  include/wait_for_slave_sql_error.inc [errno=1054]
> -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database:
> 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7''
> +Last_SQL_Error = 'Unknown column 'c7' in 't15', Error_code: 1054; Error 'Unknown
> column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD
> COLUMN c2 DECIMAL(8,2) AFTER c7''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> @@ -711,7 +711,7 @@ c1	hex(c4)	c5	c6	c7
>  *****************
>  
>  include/wait_for_slave_sql_error.inc [errno=1072]
> -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default
> database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)''
> +Last_SQL_Error = 'Key column 'c6' doesn't exist in table, Error_code: 1072; Error
> 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query:
> 'CREATE INDEX part_of_c6 ON t16 (c6)''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result'
> --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result	2011-03-25 10:29:46
> +0000
> @@ -613,7 +613,7 @@ c1	c3	hex(c4)	c5	c6
>  * Bug30415 *
>  ************
>  include/wait_for_slave_sql_error.inc [errno=1091]
> -Last_SQL_Error = 'Error 'Can't DROP 'c7'; check that column/key exists' on query.
> Default database: 'test'. Query: 'ALTER TABLE t14 DROP COLUMN c7''
> +Last_SQL_Error = 'Can't DROP 'c7'; check that column/key exists, Error_code: 1091;
> Error 'Can't DROP 'c7'; check that column/key exists' on query. Default database: 'test'.
> Query: 'ALTER TABLE t14 DROP COLUMN c7''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> @@ -662,7 +662,7 @@ c1	hex(c4)	c5	c6	c7	c2
>  ********************************************
>  
>  include/wait_for_slave_sql_error.inc [errno=1054]
> -Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default database:
> 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7''
> +Last_SQL_Error = 'Unknown column 'c7' in 't15', Error_code: 1054; Error 'Unknown
> column 'c7' in 't15'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD
> COLUMN c2 DECIMAL(8,2) AFTER c7''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> @@ -711,7 +711,7 @@ c1	hex(c4)	c5	c6	c7
>  *****************
>  
>  include/wait_for_slave_sql_error.inc [errno=1072]
> -Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Default
> database: 'test'. Query: 'CREATE INDEX part_of_c6 ON t16 (c6)''
> +Last_SQL_Error = 'Key column 'c6' doesn't exist in table, Error_code: 1072; Error
> 'Key column 'c6' doesn't exist in table' on query. Default database: 'test'. Query:
> 'CREATE INDEX part_of_c6 ON t16 (c6)''
>  STOP SLAVE;
>  RESET SLAVE;
>  
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result'
> --- a/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result	2011-03-25 10:29:46
> +0000
> @@ -488,7 +488,7 @@ ALTER TABLE t15 ADD COLUMN c6 INT AFTER 
>  *** Expect slave to fail with Error 1060 ***
>  ********************************************
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1060]
> -Last_SQL_Error = 'Error 'Duplicate column name 'c6'' on query. Default database:
> 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5''
> +Last_SQL_Error = 'Duplicate column name 'c6', Error_code: 1060; Error 'Duplicate
> column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN
> c6 INT AFTER c5''
>  *** Try to insert in master ****
>  INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
>  SELECT * FROM t15 ORDER BY c1;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result'
> --- a/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result	2011-03-25 10:29:46
> +0000
> @@ -488,7 +488,7 @@ ALTER TABLE t15 ADD COLUMN c6 INT AFTER 
>  *** Expect slave to fail with Error 1060 ***
>  ********************************************
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1060]
> -Last_SQL_Error = 'Error 'Duplicate column name 'c6'' on query. Default database:
> 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5''
> +Last_SQL_Error = 'Duplicate column name 'c6', Error_code: 1060; Error 'Duplicate
> column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN
> c6 INT AFTER c5''
>  *** Try to insert in master ****
>  INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
>  SELECT * FROM t15 ORDER BY c1;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result'
> --- a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	2011-02-23 09:31:37
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	2011-03-25 10:29:46
> +0000
> @@ -45,52 +45,52 @@ UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.
>  call mtr.add_suppression("Slave SQL.*Error .Table .test.t[47]. doesn.t exist. on
> query.* Error_code: 1146");
>  UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> t4 ON (t1.id=t4.id) SET a=0 where t1.id=1''
>  UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where
> t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0
> where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1''
>  UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id)
> SET a=0, b=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and
> t1.id=t7.id) SET a=0, b=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where
> t1.id=1''
>  UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id)
> SET a=0, b=0, c=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and
> t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where
> t1.id=1''
>  UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1''
>  UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN
> t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1''
>  UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id)
> SET a=0, g=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and
> t1.id=t7.id) SET a=0, g=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where
> t1.id=1''
>  UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id)
> SET a=0, g=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and
> t1.id=t8.id) SET a=0, g=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where
> t1.id=1''
>  UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id)
> SET a=0, g=0, h=0, i=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and
> t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where
> t1.id=1''
>  UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id)
> SET g=0, a=0, b=0, c=0 where t7.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and
> t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN
> (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where
> t7.id=1''
>  UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id)
> SET g=0, c=0 where t7.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and
> t7.id=t3.id) SET g=0, c=0 where t7.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN
> (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where
> t7.id=1''
>  UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id)
> SET g=0, h=0, i=0, c=0 where t7.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and
> t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN
> (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where
> t7.id=1''
>  UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1''
>  UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id)
> SET a=0, d=0, e=0, f=0 where t1.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and
> t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN
> (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where
> t1.id=1''
>  UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id)
> SET a=0, e=0, f=0 where t4.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t4' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and
> t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1''
> +Last_SQL_Error = 'Table 'test.t4' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t4 LEFT JOIN
> (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where
> t4.id=1''
>  UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id)
> SET a=0, b=0, d=0, g=0 where t7.id=1;
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1146]
> -Last_SQL_Error = 'Error 'Table 'test.t7' doesn't exist' on query. Default database:
> 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and
> t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1''
> +Last_SQL_Error = 'Table 'test.t7' doesn't exist, Error_code: 1146; Error 'Table
> 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN
> (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where
> t7.id=1''
>  [on slave]
>  show tables like 't%';
>  Tables_in_test (t%)
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_idempotency.result'
> --- a/mysql-test/suite/rpl/r/rpl_idempotency.result	2011-02-23 11:54:58 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result	2011-03-25 10:29:46 +0000
> @@ -4,6 +4,8 @@ call mtr.add_suppression("Slave SQL.*Can
>  call mtr.add_suppression("Slave SQL.*Cannot delete or update a parent row: a foreign
> key constraint fails .* Error_code: 1451");
>  call mtr.add_suppression("Slave SQL.*Cannot add or update a child row: a foreign key
> constraint fails .* Error_code: 1452");
>  call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table
> test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062");
> +call mtr.add_suppression("Slave SQL: Could not execute Delete_rows event");
> +call mtr.add_suppression("Slave SQL: Could not execute Update_rows event");
>  CREATE TABLE t1 (a INT PRIMARY KEY);
>  CREATE TABLE t2 (a INT);
>  INSERT INTO t1 VALUES (-1),(-2),(-3);
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_init_slave_errors.result'
> --- a/mysql-test/suite/rpl/r/rpl_init_slave_errors.result	2011-02-23 09:31:37 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_init_slave_errors.result	2011-03-25 10:29:46 +0000
> @@ -12,7 +12,7 @@ reset slave;
>  SET GLOBAL init_slave= "garbage";
>  start slave;
>  include/wait_for_slave_sql_error.inc [errno=1064]
> -Last_SQL_Error = 'Slave SQL thread aborted. Can't execute init_slave query'
> +Last_SQL_Error = 'You have an error in your SQL syntax; check the manual that
> corresponds to your MySQL server version for the right syntax to use near 'garbage' at
> line 1, Error_code: 1064; Slave SQL thread aborted. Can't execute init_slave query'
>  SET GLOBAL init_slave= "";
>  include/stop_slave_io.inc
>  RESET SLAVE;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_known_bugs_detection.result'
> --- a/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result	2011-03-25 10:29:46
> +0000
> @@ -9,7 +9,7 @@ a	b
>  2	2
>  call mtr.add_suppression("Slave
> SQL.*suffer.*http:..bugs.mysql.com.bug.php.id=24432");
>  include/wait_for_slave_sql_error.inc [errno=1105]
> -Last_SQL_Error = 'Error 'master may suffer from
> http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more
> info' on query. Default database: 'test'. Query: 'INSERT INTO t1(b) VALUES(1),(1),(2) ON
> DUPLICATE KEY UPDATE t1.b=10''
> +Last_SQL_Error = 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so
> slave stops; check error log on slave for more info, Error_code: 1105; According to the
> master's version ('5.0.34'), it is probable that master suffers from this bug:
> http://bugs.mysql.com/bug.php?id=24432 and thus replicating the current binary log event
> may make the slave's data become different from the master's data. To take no risk, slave
> refuses to replicate this event and stops. We recommend that all updates be stopped on the
> master and slave, that the data of both be manually synchronized, that master's binary
> logs be deleted, that master be upgraded to a version at l, Error_code: 1105; Error
> 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error
> log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1(b)
> VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10''
>  SELECT * FROM t1;
>  a	b
>  stop slave;
> @@ -57,7 +57,7 @@ id	field_1	field_2	field_3
>  5	5	e	5e
>  6	6	f	6f
>  include/wait_for_slave_sql_error.inc [errno=1105]
> -Last_SQL_Error = 'Error 'master may suffer from
> http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more
> info' on query. Default database: 'test'. Query: 'INSERT INTO t1 (field_1, field_2,
> field_3)
> +Last_SQL_Error = 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so
> slave stops; check error log on slave for more info, Error_code: 1105; According to the
> master's version ('5.0.34'), it is probable that master suffers from this bug:
> http://bugs.mysql.com/bug.php?id=24432 and thus replicating the current binary log event
> may make the slave's data become different from the master's data. To take no risk, slave
> refuses to replicate this event and stops. We recommend that all updates be stopped on the
> master and slave, that the data of both be manually synchronized, that master's binary
> logs be deleted, that master be upgraded to a version at l, Error_code: 1105; Error
> 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error
> log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1
> (field_1, field_2, field_3)
>  SELECT t2.field_a, t2.field_b, t2.field_c
>  FROM t2
>  ON DUPLICATE KEY UPDATE
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_loaddata.result'
> --- a/mysql-test/suite/rpl/r/rpl_loaddata.result	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_loaddata.result	2011-03-25 10:29:46 +0000
> @@ -28,7 +28,7 @@ create table t1(a int, b int, unique(b))
>  insert into t1 values(1,10);
>  load data infile '../../std_data/rpl_loaddata.dat' into table t1;
>  call mtr.add_suppression("Slave SQL.*Error .Duplicate entry .10. for key .b.. on
> query.* Error_code: 1062");
> -call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 0");
> +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 1105");
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1062]
>  include/check_slave_no_error.inc
>  set sql_log_bin=0;
> @@ -72,7 +72,7 @@ load data infile '../../std_data/rpl_loa
>  terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
>  '\n##\n' starting by '>' ignore 1 lines;
>  ERROR 23000: Duplicate entry '2003-03-22' for key 'day'
> -include/wait_for_slave_sql_error.inc [errno=0]
> +include/wait_for_slave_sql_error.inc [errno=1105]
>  drop table t1, t2;
>  drop table t1, t2;
>  CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_packet.result'
> --- a/mysql-test/suite/rpl/r/rpl_packet.result	2010-12-19 17:22:30 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_packet.result	2011-03-25 10:29:46 +0000
> @@ -30,7 +30,7 @@ include/start_slave.inc
>  CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
>  INSERT INTO `t1`(`f1`) VALUES
> ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a!
> 
> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a!
>  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
>  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
>  include/wait_for_slave_io_error.inc [errno=1153]
> -Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes'
> +Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes, Error_code:
> 1153; Got a packet bigger than 'max_allowed_packet' bytes'
>  include/stop_slave_sql.inc
>  include/rpl_reset.inc
>  DROP TABLE t1;
> @@ -65,7 +65,7 @@ CREATE TABLE t1 (a TEXT) ENGINE=MyISAM;
>  INSERT INTO t1 VALUES (REPEAT('a', 2048));
>  # 1153 = ER_NET_PACKET_TOO_LARGE
>  include/wait_for_slave_io_error.inc [errno=1153]
> -Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes'
> +Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes, Error_code:
> 1153; Got a packet bigger than 'max_allowed_packet' bytes'
>  # Record Read_Master_Log_Pos for the Table_map_log_event
>  SET @@global.max_allowed_packet=1048576;
>  WARNING: The range of printed events ends with a row event or a table map event that
> does not have the STMT_END_F flag set. This might be because the last statement was not
> fully written to the log, or because you are using a --stop-position or --stop-datetime
> that refers to an event in the middle of a statement. The event(s) from the partial
> statement have not been written to output.
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_row_conflicts.result'
> --- a/mysql-test/suite/rpl/r/rpl_row_conflicts.result	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_conflicts.result	2011-03-25 10:29:46 +0000
> @@ -22,7 +22,7 @@ a
>  ---- Wait until slave stops with an error ----
>  include/wait_for_slave_sql_error.inc [errno=1062]
>  Last_SQL_Error (expected "duplicate key" error)
> -Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key
> 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log
> master-bin.000001, end_log_pos END_LOG_POS
> +Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; Could not execute
> Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code:
> 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log master-bin.000001,
> end_log_pos END_LOG_POS
>  call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.*
> Error_code: 1062");
>  SELECT * FROM t1;
>  a
> @@ -53,7 +53,7 @@ a
>  call mtr.add_suppression("Slave SQL.*Can.t find record in .t1., Error_code: 1032");
>  include/wait_for_slave_sql_error.inc [errno=1032]
>  Last_SQL_Error (expected "duplicate key" error)
> -Could not execute Delete_rows event on table test.t1; Can't find record in 't1',
> Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log
> master-bin.000001, end_log_pos END_LOG_POS
> +Can't find record in 't1', Error_code: 1032; Could not execute Delete_rows event on
> table test.t1; Can't find record in 't1', Error_code: 1032; handler error
> HA_ERR_KEY_NOT_FOUND; the event's master log master-bin.000001, end_log_pos END_LOG_POS
>  SELECT * FROM t1;
>  a
>  ---- Resolve the conflict on the slave and restart SQL thread ----
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_stm_EE_err2.result'
> --- a/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result	2011-03-25 10:29:46 +0000
> @@ -7,9 +7,9 @@ set sql_log_bin=1;
>  insert into t1 values(1),(2);
>  ERROR 23000: Duplicate entry '2' for key 'a'
>  drop table t1;
> -call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.* error code=1062.*Error on slave:.* Error_code: 0");
> +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.* error code=1062.*Error on slave:.* Error_code: 1105");
>  (expect different error codes on master and slave)
> -include/wait_for_slave_sql_error.inc [errno=0]
> +include/wait_for_slave_sql_error.inc [errno=1105]
>  Last_SQL_Error = 'Query caused different errors on master and slave.     Error on
> master: message (format)='Duplicate entry '%-.192s' for key %d' error code=1062 ; Error on
> slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert
> into t1 values(1),(2)''
>  drop table t1;
>  include/stop_slave.inc
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_stm_conflicts.result'
> --- a/mysql-test/suite/rpl/r/rpl_stm_conflicts.result	2011-02-23 20:01:27 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_stm_conflicts.result	2011-03-25 10:29:46 +0000
> @@ -17,7 +17,7 @@ a
>  ---- Wait until slave stops with an error ----
>  include/wait_for_slave_sql_error.inc [errno=1062]
>  Last_SQL_Error (expected "duplicate key" error)
> -Error 'Duplicate entry '1' for key 'PRIMARY'' on query. Default database: 'test'.
> Query: 'INSERT INTO t1 VALUES (1)'
> +Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; Error 'Duplicate entry '1'
> for key 'PRIMARY'' on query. Default database: 'test'. Query: 'INSERT INTO t1 VALUES (1)'
>  call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.*
> Error_code: 1062");
>  SELECT * FROM t1;
>  a
> 
> === modified file 'mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result'
> --- a/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result	2011-02-23 20:01:27
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result	2011-03-25 10:29:46
> +0000
> @@ -44,7 +44,7 @@ create table t1(a int, b int, unique(b))
>  insert into t1 values(1,10);
>  load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1;
>  call mtr.add_suppression("Slave SQL.*Error .Duplicate entry .10. for key .b.. on
> query.* Error_code: 1062");
> -call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 0");
> +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and
> slave.*Error on master:.*error code=1062.*Error on slave:.*Error_code: 1105");
>  include/wait_for_slave_sql_error_and_skip.inc [errno=1062]
>  include/check_slave_no_error.inc
>  set sql_log_bin=0;
> @@ -88,7 +88,7 @@ load data CONCURRENT infile '../../std_d
>  terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
>  '\n##\n' starting by '>' ignore 1 lines;
>  ERROR 23000: Duplicate entry '2003-03-22' for key 'day'
> -include/wait_for_slave_sql_error.inc [errno=0]
> +include/wait_for_slave_sql_error.inc [errno=1105]
>  drop table t1, t2;
>  drop table t1, t2;
>  CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
> 
> === modified file 'mysql-test/suite/rpl/t/rpl_idempotency.test'
> --- a/mysql-test/suite/rpl/t/rpl_idempotency.test	2011-02-23 11:54:58 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test	2011-03-25 10:29:46 +0000
> @@ -8,6 +8,8 @@ call mtr.add_suppression("Slave SQL.*Can
>  call mtr.add_suppression("Slave SQL.*Cannot delete or update a parent row: a foreign
> key constraint fails .* Error_code: 1451");
>  call mtr.add_suppression("Slave SQL.*Cannot add or update a child row: a foreign key
> constraint fails .* Error_code: 1452");
>  call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table
> test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062");
> +call mtr.add_suppression("Slave SQL: Could not execute Delete_rows event");
> +call mtr.add_suppression("Slave SQL: Could not execute Update_rows event");
>  
>  connection master;
>  CREATE TABLE t1 (a INT PRIMARY KEY);
> 
> === modified file 'sql/log_event.cc'
> --- a/sql/log_event.cc	2011-03-14 17:09:16 +0000
> +++ b/sql/log_event.cc	2011-03-25 10:29:46 +0000
> @@ -293,13 +293,6 @@ static void pretty_print_str(IO_CACHE* c
>  
>  #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
>  
> -static void clear_all_errors(THD *thd, Relay_log_info *rli)
> -{
> -  thd->is_slave_error = 0;
> -  thd->clear_error();
> -  rli->clear_error();
> -}
> -
>  inline int idempotent_error_code(int err_code)
>  {
>    int ret= 0;

ok.

> @@ -3700,7 +3693,7 @@ compare_errors:
>          !ignored_error_code(actual_error) &&
>          !ignored_error_code(expected_error))
>      {
> -      rli->report(ERROR_LEVEL, 0,
> +      rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
>                        "\
>  Query caused different errors on master and slave.     \
>  Error on master: message (format)='%s' error code=%d ; \

Is this really unknown? You have the error in the actual_error ;)
However, what happened at this point is that slave failed with
an error that was not expected. Maybe it haven't failed at all.

So I suggest to either use the actual_error which may be zero or
define a new ER_.

> 
> === modified file 'sql/rpl_reporting.cc'
> --- a/sql/rpl_reporting.cc	2010-08-05 17:45:25 +0000
> +++ b/sql/rpl_reporting.cc	2011-03-25 10:29:46 +0000
> @@ -17,6 +17,7 @@
>  #include "rpl_reporting.h"
>  #include "log.h" // sql_print_error, sql_print_warning,
>                   // sql_print_information
> +#include "rpl_slave.h"

I think you should try to get rid of this dependency here.
Include, "sql_class.h" and make has_temporary_error function
part of Slave_reporting_capability. After your changes, I
think this makes sense and will provide a better architecture.

>  
>  Slave_reporting_capability::Slave_reporting_capability(char const *thread_name)
>    : m_thread_name(thread_name)
> @@ -25,54 +26,159 @@ Slave_reporting_capability::Slave_report
>                     &err_lock, MY_MUTEX_INIT_FAST);
>  }
>  
> +/**
> +   The method treats a supplied message depending on the level:
> +
> +       - an error is queued in the diagnostic area 
> +         to be recorded eventually in Show Slave status area and
> +         in the error log.
> +       - a warning or an info level are optinally (log_warnings)
> +         stored into the error log
> +
> +   @param level     severity of the message.
> +   @param err_code  the user level error code
> +   @param msg       the format string of the message,
> +                    can be followed with more arguments
> +                    providing the data for the format string
> +
> +   @note Queueing in the da is protected by @err_lock mutex
> +         to collabote with a concurrent reader from the da.
> +*/
>  void
>  Slave_reporting_capability::report(loglevel level, int err_code,
>                                     const char *msg, ...) const
>  {
> +/* 
> +   todo: sort out embedded building dependencies to avoid this module
> +   to be compiled altogether.


Please, fix this.


> +*/
> +#if !defined(EMBEDDED_LIBRARY)
> +  THD *thd= current_thd;
>    void (*report_function)(const char *, ...);
> -  char buff[MAX_SLAVE_ERRMSG];
> +  char buff[sizeof(m_last_error.message)];
>    char *pbuff= buff;
> -  uint pbuffsize= sizeof(buff);
>    va_list args;
> +
> +  if (level == ERROR_LEVEL && has_temporary_error(thd, err_code))
> +    level= WARNING_LEVEL;
> +
>    va_start(args, msg);
> +  my_vsnprintf(pbuff, sizeof(buff), msg, args);
> +  va_end(args);
>  
>    mysql_mutex_lock(&err_lock);
>    switch (level)
>    {
>    case ERROR_LEVEL:
>      /*
> -      It's an error, it must be reported in Last_error and Last_errno in SHOW
> -      SLAVE STATUS.
> +      It's an error, it goes in a slave thread's main_da.
>      */
> -    pbuff= m_last_error.message;
> -    pbuffsize= sizeof(m_last_error.message);
> -    m_last_error.number = err_code;
> +    m_last_error.number= err_code;
>      m_last_error.update_timestamp();

> +    if (err_code > 0)
> +    {
> +      if (thd->stmt_da->is_set())
> +        thd->stmt_da->can_overwrite_status= TRUE;
> +      my_printf_error(err_code, "%s", MYF(0), pbuff);
> +      if (thd->stmt_da->can_overwrite_status)
> +        thd->stmt_da->can_overwrite_status= FALSE;
> +    }

I have two suggestions in here:
  . I don't think this should be executed if err_code is 0.
  So fix the caller that is trying to through an error when
  error is zero. In such case, error should be set to unknown.

  . Get rid of the if(s).

In other words,

  assert(err_code > 0);
  thd->stmt_da->can_overwrite_status= TRUE;
  my_printf_error(err_code, "%s", MYF(0), pbuff);
  thd->stmt_da->can_overwrite_status= FALSE;


>      report_function= sql_print_error;
>      break;
>    case WARNING_LEVEL:
> -    report_function= sql_print_warning;
> +    report_function= global_system_variables.log_warnings?
> +      sql_print_warning : NULL;
>      break;

Great ;)

>    case INFORMATION_LEVEL:
> -    report_function= sql_print_information;
> +    report_function= global_system_variables.log_warnings?
> +      sql_print_information : NULL;
>      break;
>    default:
>      DBUG_ASSERT(0);                            // should not come here
>      return;          // don't crash production builds, just do nothing
>    }
>  
> -  my_vsnprintf(pbuff, pbuffsize, msg, args);
> -
> +  /* If the msg string ends with '.', do not add a ',' it would be ugly */
> +  if (report_function)
> +    report_function("Slave %s: %s%s Error_code: %d",
> +                    m_thread_name, pbuff,
> +                    (pbuff[0] && *(strend(pbuff) - 1) == '.') ? "" : ",",
> +                    err_code);
>    mysql_mutex_unlock(&err_lock);
> +#endif
> +}
> +

Please, override display to avoid requiring users to write display(0, NULL).
Find a better name to the function, maybe something related to the show slave
status... I don't have a good suggestion but I don't think the current name
is good.


> +/**
> +   compose Last_Error to be shown by SHOW SLAVE STATUS
> +
> +   @param err_code    The summary error code to display. If zero
> +                      the last reported default will be set to Last*Errno
> +
> +   @param msg         The summary message's format string optinally followed
> +                      by arguments. It can be NULL.
> +
> +   @note  The method tries gathering all queued *error-level* messages
> +          into the limited-size buffer and may not compose the whole
> +          list. In that case the rest can be found anyway in the error log.
> +          The Last_Error's code corresponds to the last queued error if
> +          the supplied @c err_code is zero.
> +          
> +          The gathering procedure is protected by @c err_lock
> +          to provide collaboration with a concurrent reader such as
> +          show slave status.
> +*/
> +void
> +Slave_reporting_capability::display(int err_code, const char *msg, ...) const
> +{
> +#if !defined(EMBEDDED_LIBRARY)
> +  THD *thd= current_thd;
> +  uint len, size= sizeof(m_last_error.message);
> +  char *slider, *buff= m_last_error.message, *buff_end= buff + size;
> +  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
> +  MYSQL_ERROR *err;
> +  uint32 err_number;
> +  const char err_code_fmt[]= ", Error_code: %d; ";
> +  va_list args;
> +
> +  va_start(args, msg);
> +  len= msg == NULL? 0 : my_vsnprintf(buff, size, msg, args);
>    va_end(args);
>  
> -  /* If the msg string ends with '.', do not add a ',' it would be ugly */
> -  report_function("Slave %s: %s%s Error_code: %d",
> -                  m_thread_name, pbuff,
> -                  (pbuff[0] && *(strend(pbuff)-1) == '.') ? "" : ",",
> -                  err_code);
> +  if (thd->is_error())
> +  {
> +    mysql_mutex_lock(&err_lock);
> +    /*
> +      In case of multiple errors the error codes are printed along with msgs ...
> +    */
> +    for (err= it++, err_number= 0, slider= buff + len; err;
> +         slider += len, err= it++)
> +    {
> +      if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_ERROR)
> +        continue;

warn_list? Error? Can you write a comment on this?

> +      if (err_number != 0)
> +      {
> +        len= my_snprintf(slider, buff_end - slider, err_code_fmt, err_number);
> +        slider += len;
> +      }
> +      err_number= err->get_sql_errno();    // Last*Errno is of the error level
> +      if (slider < buff_end)
> +        len= my_snprintf(slider, buff_end - slider,"%s",
> err->get_message_text());
> +    }
> +    m_last_error.number= err_code == 0? err_number : err_code;
> +    /*
> +      ... except for the last error if its code is equal to @c err_code
> +      the supplied summary's.
> +    */
> +    if ((err_number != 0 && err_number != m_last_error.number) &&
> +        slider < buff_end)
> +      my_snprintf(slider, buff_end - slider, err_code_fmt, err_number);
> +    
> +    mysql_mutex_unlock(&err_lock);
> +  }
> +#endif
>  }


See comment above on the output.


>  
> +
>  Slave_reporting_capability::~Slave_reporting_capability()
>  {
>    mysql_mutex_destroy(&err_lock);
> 
> === modified file 'sql/rpl_reporting.h'
> --- a/sql/rpl_reporting.h	2010-08-05 17:45:25 +0000
> +++ b/sql/rpl_reporting.h	2011-03-25 10:29:46 +0000
> @@ -43,8 +43,7 @@ public:
>    Slave_reporting_capability(char const *thread_name);
>  
>    /**
> -     Writes a message and, if it's an error message, to Last_Error
> -     (which will be displayed by SHOW SLAVE STATUS).
> +     Writes a message into diag area and/or/either the error log
>  
>       @param level       The severity level
>       @param err_code    The error code
> @@ -56,6 +55,14 @@ public:
>      ATTRIBUTE_FORMAT(printf, 4, 5);
>  
>    /**
> +     compose Last_Error to be shown by SHOW SLAVE STATUS
> +     @param err_code    The summary code to display instead of the last reported
> +     @param msg         A summary message to set afront of the reported errors
> +  */
> +  void display(int err_code, const char *msg, ...) const
> +    ATTRIBUTE_FORMAT(printf, 3, 4);
> +
> +  /**
>       Clear errors. They will not show up under <code>SHOW SLAVE
>       STATUS</code>.
>     */
> 
> === modified file 'sql/rpl_slave.cc'
> --- a/sql/rpl_slave.cc	2011-03-17 13:20:36 +0000
> +++ b/sql/rpl_slave.cc	2011-03-25 10:29:46 +0000
> @@ -2514,15 +2514,23 @@ static ulong read_event(MYSQL* mysql, Ma
>    DBUG_RETURN(len - 1);
>  }
>  
> -/*
> +/**
>    Check if the current error is of temporary nature of not.
>    Some errors are temporary in nature, such as
>    ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT.  Ndb also signals
>    that the error is temporary by pushing a warning with the error code
>    ER_GET_TEMPORARY_ERRMSG, if the originating error is temporary.
> +
> +  @param      thd  a THD instance, typically of the slave SQL thread's.
> +  @error_arg  the error code for assessment. 
> +              defaults to zero which makes the function check the top
> +              of the have been reported errors stack.
> +
> +  @return 1 as the positive and 0 as the negative verdict
>  */
> -static int has_temporary_error(THD *thd)
> +int has_temporary_error(THD *thd, uint error_arg)
>  {
> +  uint error;
>    DBUG_ENTER("has_temporary_error");
>  
>    DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
> @@ -2537,16 +2545,17 @@ static int has_temporary_error(THD *thd)
>      error or not. This is currently the case for Incident_log_event,
>      which sets no message. Return FALSE.
>    */
> -  if (!thd->is_error())
> +  if (thd->is_fatal_error || !thd->is_error())
>      DBUG_RETURN(0);
>  
> +  error= (error_arg == 0)? thd->stmt_da->sql_errno() : error_arg;
> +
>    /*
>      Temporary error codes:
>      currently, InnoDB deadlock detected by InnoDB or lock
>      wait timeout (innodb_lock_wait_timeout exceeded
>    */
> -  if (thd->stmt_da->sql_errno() == ER_LOCK_DEADLOCK ||
> -      thd->stmt_da->sql_errno() == ER_LOCK_WAIT_TIMEOUT)
> +  if (error == ER_LOCK_DEADLOCK || error == ER_LOCK_WAIT_TIMEOUT)
>      DBUG_RETURN(1);
>  
>  #ifdef HAVE_NDB_BINLOG
> @@ -2637,6 +2646,13 @@ static int sql_delay_event(Log_event *ev
>    DBUG_RETURN(0);
>  }
>  
> +void clear_all_errors(THD *thd, Relay_log_info *rli)
> +{
> +  thd->is_slave_error = 0;
> +  thd->clear_error();
> +  rli->clear_error();
> +}
> +
>  
>  /**
>    Applies the given event and advances the relay log position.
> @@ -3007,10 +3023,13 @@ static int exec_relay_log_event(THD* thd
>            }
>          }
>          else
> +        {
>            sql_print_error("Slave SQL thread retried transaction %lu time(s) "
>                            "in vain, giving up. Consider raising the value of "
>                            "the slave_transaction_retries variable.",
>                            slave_trans_retries);
> +          thd->is_fatal_error= 1; // to force has_temporary_error() return 0
> +        }

Please, improve this comment.


>        }
>        else if ((exec_res && !temp_err) ||
>                 (opt_using_transactions &&
> @@ -3049,6 +3068,12 @@ static bool check_io_slave_killed(THD *t
>    {
>      if (info && global_system_variables.log_warnings)
>        sql_print_information("%s", info);
> +    /*
> +      don't expose internal errors such as ER_NET_READ_ERROR 1158.
> +      The thread is gracefully stopped.
> +    */
> +    if (mi->abort_slave)
> +      thd->clear_error();
>      return TRUE;
>    }
>    return FALSE;
> @@ -3240,14 +3265,15 @@ pthread_handler_t handle_slave_io(void *
>  
>  connected:
>  
> -    DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
> -                    {
> -                      const char act[]=
> -                        "now "
> -                        "wait_for signal.io_thread_let_running";
> -                      DBUG_ASSERT(opt_debug_sync_timeout > 0);
> -                      DBUG_ASSERT(!debug_sync_set_action(thd, 
> -                                                         STRING_WITH_LEN(act)));
> +  thd->clear_error();


Please, write a comment that you need to call clear_error at this point to get rid
of any warning or transient error that popep up while connecting to the master.


> +  DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
> +                  {
> +                    const char act[]=
> +                      "now "
> +                      "wait_for signal.io_thread_let_running";
> +                    DBUG_ASSERT(opt_debug_sync_timeout > 0);
> +                    DBUG_ASSERT(!debug_sync_set_action(thd, 
> +                                                       STRING_WITH_LEN(act)));
>                      };);
>    mysql_mutex_lock(&mi->run_lock);
>    mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
> @@ -3491,6 +3517,7 @@ err:
>      mi->mysql=0;
>    }
>    write_ignored_events_info_to_relay_log(thd, mi);
> +  mi->display(0, NULL);

Can you write a comment explaining why you updating the show slave's status
at this point?

>    thd_proc_info(thd, "Waiting for slave mutex on exit");
>    mysql_mutex_lock(&mi->run_lock);
>  
> @@ -3776,53 +3803,22 @@ log '%s' at position %s, relay log '%s' 
>        if (!sql_slave_killed(thd,rli))
>        {
>          /*
> -          retrieve as much info as possible from the thd and, error
> -          codes and warnings and print this to the error log as to
> -          allow the user to locate the error
> +          Reporting all gather errors while executing exec_relay_log_event()
> +          analogously send_error()
> +        */ 
> +        rli->display(0, NULL);
> +
> +        /* 
> +           Any warnings issued has been already printed.
> +           Take a special care of UDF.
>          */

Why don't you handle this inside Slave_reporting_capability?
If there is any hidden problem forbiden this, please write
a comment.


> -        uint32 const last_errno= rli->last_error().number;
> -
> -        if (thd->is_error())
> -        {
> -          char const *const errmsg= thd->stmt_da->message();
> -
> -          DBUG_PRINT("info",
> -                     ("thd->stmt_da->sql_errno()=%d;
> rli->last_error.number=%d",
> -                      thd->stmt_da->sql_errno(), last_errno));
> -          if (last_errno == 0)
> -          {
> -            /*
> - 	      This function is reporting an error which was not reported
> - 	      while executing exec_relay_log_event().
> - 	    */ 
> -            rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "%s",
> errmsg);
> -          }
> -          else if (last_errno != thd->stmt_da->sql_errno())
> -          {
> -            /*
> -             * An error was reported while executing exec_relay_log_event()
> -             * however the error code differs from what is in the thread.
> -             * This function prints out more information to help finding
> -             * what caused the problem.
> -             */  
> -            sql_print_error("Slave (additional info): %s Error_code: %d",
> -                            errmsg, thd->stmt_da->sql_errno());
> -          }
> -        }
> -
> -        /* Print any warnings issued */
>          List_iterator_fast<MYSQL_ERROR>
> it(thd->warning_info->warn_list());
>          MYSQL_ERROR *err;
> -        /*
> -          Added controlled slave thread cancel for replication
> -          of user-defined variables.
> -        */
>          bool udf_error = false;
>          while ((err= it++))
>          {
>            if (err->get_sql_errno() == ER_CANT_OPEN_LIBRARY)
>              udf_error = true;
> -          sql_print_warning("Slave: %s Error_code: %d", err->get_message_text(),
> err->get_sql_errno());
>          }
>          if (udf_error)
>            sql_print_error("Error loading user-defined library, slave SQL "
> @@ -3839,6 +3835,14 @@ llstr(rli->get_group_master_log_pos(), l
>        }
>        goto err;
>      }
> +    else
> +    {
> +      /*
> +        Event applying succeeded, reset errors and diag area status
> +      */
> +      clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
> +      thd->stmt_da->reset_diagnostics_area();

You don't need to explicitly call reset_diagnostics_area(). This is done
insinde clear_all_errors while calling thd->clear_error().

> +    }
>    }
>  
>    /* Thread stopped. Print the current replication position to the log */
> @@ -3849,6 +3853,7 @@ llstr(rli->get_group_master_log_pos(), l
>  
>   err:
>  
> +  rli->display(0, NULL);

Can you write a comment explaining why you updating the show slave's status
at this point?

>    /*
>      Some events set some playgrounds, which won't be cleared because thread
>      stops. Stopping of this thread may not be known to these events ("stop"


> 
> === modified file 'sql/rpl_slave.h'
> --- a/sql/rpl_slave.h	2011-02-16 17:13:30 +0000
> +++ b/sql/rpl_slave.h	2011-03-25 10:29:46 +0000
> @@ -213,6 +213,8 @@ void set_slave_thread_options(THD* thd);
>  void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
>  int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
>  int rotate_relay_log(Master_info* mi);
> +int has_temporary_error(THD *thd, uint err= 0);
> +void clear_all_errors(THD *thd, Relay_log_info *rli);
>  
>  pthread_handler_t handle_slave_io(void *arg);
>  pthread_handler_t handle_slave_sql(void *arg);

ok.

Cheers.
Thread
bzr commit into mysql-trunk branch (andrei.elkin:3311) Bug#11748510Andrei Elkin25 Mar
  • Re: bzr commit into mysql-trunk branch (andrei.elkin:3311) Bug#11748510Alfranio Correia25 Mar