diff --git a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test index 1fb6b3dcb8a..3d97ad10d17 100644 --- a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test +++ b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test @@ -21,9 +21,18 @@ # and slave are diverging. # ######################################################################################## - call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1); +let $old_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_cache_size", Value, 1); + +SET GLOBAL max_binlog_cache_size = 4096; +# Becuase of bug#55377, we have to set binlog_cache_size until the bug is +# fixed. +SET GLOBAL binlog_cache_size = 4096; +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -50,13 +59,9 @@ eval INSERT INTO t2 (a, data) VALUES (2, CONCAT($data, $data, $data, $data, $data, $data)); --enable_query_log -connection slave; ---source include/wait_for_slave_sql_to_stop.inc -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; ---source include/wait_for_slave_sql_to_start.inc - -connection master; +# Incident event +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error_and_skip.inc --disable_query_log eval INSERT INTO t1 (a, data) VALUES (3, $data); @@ -74,23 +79,15 @@ eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data), t1.data = CONCAT($data, $data, $data, $data); --enable_query_log -connection slave; ---source include/wait_for_slave_sql_to_stop.inc - -if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) -{ - SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -} +# Incident event +--let $slave_skip_counter=1 if (`SELECT @@binlog_format = 'ROW'`) { - SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; + --inc $slave_skip_counter } -START SLAVE SQL_THREAD; ---source include/wait_for_slave_sql_to_start.inc -connection master; - -let $diff_statement= SELECT * FROM t1; ---source include/diff_master_slave.inc +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error_and_skip.inc +--let $slave_skip_counter= --echo ######################################################################################## --echo # 2 - BEGIN - IMPLICIT COMMIT by DDL @@ -178,17 +175,6 @@ BEGIN; CREATE TABLE t5 (a int); --enable_query_log -if (`SELECT @@binlog_format = 'ROW'`) -{ - connection slave; - --source include/wait_for_slave_sql_to_stop.inc - - SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; - START SLAVE SQL_THREAD; - --source include/wait_for_slave_sql_to_start.inc - connection master; -} - let $diff_statement= SELECT * FROM t1; --source include/diff_master_slave.inc @@ -373,6 +359,70 @@ COMMIT; let $diff_statement= SELECT * FROM t1; --source include/diff_master_slave.inc +--echo ######################################################################## +--echo # 8 - Bug#55375(Regression Bug) Transaction bigger than +--echo # max_binlog_cache_size crashes slave +--echo ######################################################################## + +--echo # [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; + +source include/stop_slave.inc; +source include/start_slave.inc; +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); + +connection master; +TRUNCATE t1; + +sync_slave_with_master; +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +--let binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) + +connection master; +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + +--let $n=128 +BEGIN; +--disable_query_log +--echo Repeat statement 'INSERT INTO t1 VALUES(\$n, repeat("a", 32))' $n times +while ($n) +{ + --eval INSERT INTO t1 VALUES ($n, repeat("a", 32)) + --dec $n +} +--enable_query_log +COMMIT; + +connection slave; +--let $slave_sql_errno= 1197 +if (`SELECT @@binlog_format = 'ROW'`) +{ + --let $slave_sql_errno= 1534 +} +source include/wait_for_slave_sql_error.inc; + +SELECT count(*) FROM t1; +source include/show_binlog_events.inc; + +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size + +source include/stop_slave.inc; +source include/start_slave.inc; + +connection master; +sync_slave_with_master; +SELECT count(*) FROM t1; + --echo ######################################################################################## --echo # CLEAN --echo ######################################################################################## @@ -385,4 +435,4 @@ DROP TABLE IF EXISTS t4; DROP TABLE IF EXISTS t5; DROP TABLE IF EXISTS t6; DROP PROCEDURE p1; -sync_slave_with_master; +source include/master-slave-end.inc; diff --git a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result index 6e47f747a79..9c1dfebebaf 100644 --- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result @@ -5,6 +5,8 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -15,13 +17,14 @@ CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; Got one of the listed errors *** Single statement on non-transactional table *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +include/start_slave.inc *** Single statement on both transactional and non-transactional tables. *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; -START SLAVE SQL_THREAD; -source include/diff_master_slave.inc; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER= 2; +include/start_slave.inc ######################################################################################## # 2 - BEGIN - IMPLICIT COMMIT by DDL ######################################################################################## @@ -39,8 +42,6 @@ Got one of the listed errors BEGIN; Got one of the listed errors Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; source include/diff_master_slave.inc; ######################################################################################## # 3 - BEGIN - COMMIT @@ -122,6 +123,35 @@ BEGIN; Got one of the listed errors COMMIT; source include/diff_master_slave.inc; +######################################################################## +# 8 - Bug#55375(Regression Bug) Transaction bigger than +# max_binlog_cache_size crashes slave +######################################################################## +# [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +include/stop_slave.inc +include/start_slave.inc +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +TRUNCATE t1; +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +BEGIN; +Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times +COMMIT; +SELECT count(*) FROM t1; +count(*) +0 +show binlog events in 'slave-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +include/stop_slave.inc +include/start_slave.inc +SELECT count(*) FROM t1; +count(*) +128 ######################################################################################## # CLEAN ######################################################################################## diff --git a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result index 1ad34fbe961..479caed8e6b 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result @@ -5,6 +5,8 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -15,13 +17,14 @@ CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; Got one of the listed errors *** Single statement on non-transactional table *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +include/start_slave.inc *** Single statement on both transactional and non-transactional tables. *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; -source include/diff_master_slave.inc; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER= 1; +include/start_slave.inc ######################################################################################## # 2 - BEGIN - IMPLICIT COMMIT by DDL ######################################################################################## @@ -119,6 +122,35 @@ BEGIN; Got one of the listed errors COMMIT; source include/diff_master_slave.inc; +######################################################################## +# 8 - Bug#55375(Regression Bug) Transaction bigger than +# max_binlog_cache_size crashes slave +######################################################################## +# [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +include/stop_slave.inc +include/start_slave.inc +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +TRUNCATE t1; +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +BEGIN; +Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times +COMMIT; +SELECT count(*) FROM t1; +count(*) +0 +show binlog events in 'slave-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +include/stop_slave.inc +include/start_slave.inc +SELECT count(*) FROM t1; +count(*) +128 ######################################################################################## # CLEAN ######################################################################################## diff --git a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt deleted file mode 100644 index eb56e5c0a09..00000000000 --- a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt +++ /dev/null @@ -1 +0,0 @@ ---binlog_cache_size=4096 --max_binlog_cache_size=7680 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size-master.opt deleted file mode 100644 index 45631525481..00000000000 --- a/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size-master.opt +++ /dev/null @@ -1 +0,0 @@ ---binlog_cache_size=4096 --max_binlog_cache_size=7680 diff --git a/sql/log_event.cc b/sql/log_event.cc index 16290c58685..bfcac10e138 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -158,16 +158,21 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, " %s, Error_code: %d;", err->get_message_text(), err->get_sql_errno()); } - - rli->report(level, thd->is_error()? thd->stmt_da->sql_errno() : 0, - "Could not execute %s event on table %s.%s;" - "%s handler error %s; " - "the event's master log %s, end_log_pos %lu", - type, table->s->db.str, - table->s->table_name.str, - buff, - handler_error == NULL? "" : handler_error, - log_name, pos); + + if (ha_error != 0) + rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0, + "Could not execute %s event on table %s.%s;" + "%s handler error %s; " + "the event's master log %s, end_log_pos %lu", + type, table->s->db.str, table->s->table_name.str, + buff, handler_error == NULL ? "" : handler_error, + log_name, pos); + else + rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0, + "Could not execute %s event on table %s.%s;" + "%s the event's master log %s, end_log_pos %lu", + type, table->s->db.str, table->s->table_name.str, + buff, log_name, pos); } #endif @@ -7811,19 +7816,16 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) /Sven */ thd->reset_current_stmt_binlog_format_row(); - const_cast(rli)->cleanup_context(thd, error); thd->is_slave_error= 1; DBUG_RETURN(error); } - if (get_flags(STMT_END_F)) - if ((error= rows_event_stmt_cleanup(rli, thd))) - rli->report(ERROR_LEVEL, error, - "Error in %s event: commit of row events failed, " - "table `%s`.`%s`", - get_type_str(), m_table->s->db.str, - m_table->s->table_name.str); - + if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rli, thd))) + slave_rows_error_report(ERROR_LEVEL, + thd->is_error() ? 0 : error, + rli, thd, table, + get_type_str(), + RPL_LOG_NAME, (ulong) log_pos); DBUG_RETURN(error); } diff --git a/sql/slave.cc b/sql/slave.cc index dff6b6946d4..3e77a5e7516 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2534,9 +2534,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) else { exec_res= 0; - trans_rollback(thd); - close_thread_tables(thd); - thd->mdl_context.release_transactional_locks(); + rli->cleanup_context(thd, 1); /* chance for concurrent connection to get more locks */ safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli); @@ -3385,6 +3383,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ request is detected only by the present function, not by events), so we must "proactively" clear playgrounds: */ + thd->clear_error(); rli->cleanup_context(thd, 1); /* Some extra safety, which should not been needed (normally, event deletion