From 54231e455488d73731a7f300f95da6d70d5d874c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 Dec 2005 12:07:07 +0100 Subject: [PATCH 1/2] Bug#15924 (Core dump in sp_trans): Added code for pending event flush just before executing the function or trigger. mysql-test/t/disabled.def: Enabling sp_trans test. sql/log.cc: Reorganizing/simplifying code. sql/sql_class.cc: Added code to flush pending event before executing a function/trigger. --- mysql-test/t/disabled.def | 2 +- sql/log.cc | 18 +++++++++++------- sql/sql_class.cc | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f32ed667864..5fdc6f6f3dc 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,4 +24,4 @@ subselect : Bug#15706 type_time : Bug#15805 rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite -sp_trans : Bug#15924 Code dump in RBR mode when executing test suite +#sp_trans : Bug#15924 Code dump in RBR mode when executing test suite diff --git a/sql/log.cc b/sql/log.cc index 44d3869e9d5..dd08ca7b9b5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -241,13 +241,15 @@ static int binlog_savepoint_set(THD *thd, void *sv) DBUG_ENTER("binlog_savepoint_set"); binlog_trx_data *const trx_data= (binlog_trx_data*) thd->ha_data[binlog_hton.slot]; - IO_CACHE *trans_log= &trx_data->trans_log; - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(&trx_data->trans_log)); - *(my_off_t *)sv= my_b_tell(trans_log); + *(my_off_t *)sv= my_b_tell(&trx_data->trans_log); /* Write it to the binary log */ - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } static int binlog_savepoint_rollback(THD *thd, void *sv) @@ -265,8 +267,10 @@ static int binlog_savepoint_rollback(THD *thd, void *sv) */ if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE)) { - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0); DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 08d89228a72..2bc0d8d59ab 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1969,6 +1969,23 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, backup->client_capabilities= client_capabilities; backup->savepoints= transaction.savepoints; + /* + For row-based replication and before executing a function/trigger, + the pending rows event has to be flushed. The function/trigger + might execute statement that require the pending event to be + flushed. A simple example: + + CREATE FUNCTION foo() RETURNS INT + BEGIN + SAVEPOINT x; + RETURN 0; + END + + INSERT INTO t1 VALUES (1), (foo()), (2); + */ + if (binlog_row_based) + thd->binlog_flush_pending_rows_event(false); + if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !binlog_row_based) options&= ~OPTION_BIN_LOG; From 84e439923f62c7dac04f09abfa228bb7cd1d46e0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Dec 2005 12:06:48 +0100 Subject: [PATCH 2/2] Bug#15942 (RBR ignored --binlog_ignore_db and tries to map table on slave for writes): Added code to do the filtering (seems to have gone away). sql/handler.cc: Filtering based on the database for the table. --- mysql-test/r/rpl_row_basic_11bugs.result | 45 ++++++++++++++++++++ mysql-test/t/rpl_row_basic_11bugs-master.opt | 1 + mysql-test/t/rpl_row_basic_11bugs.test | 31 ++++++++++++++ sql/handler.cc | 5 ++- 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/rpl_row_basic_11bugs.result create mode 100644 mysql-test/t/rpl_row_basic_11bugs-master.opt create mode 100644 mysql-test/t/rpl_row_basic_11bugs.test diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result new file mode 100644 index 00000000000..9249405ac26 --- /dev/null +++ b/mysql-test/r/rpl_row_basic_11bugs.result @@ -0,0 +1,45 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +CREATE DATABASE test_ignore; +**** On Master **** +SHOW DATABASES; +Database +information_schema +mysql +test +test_ignore +USE test; +CREATE TABLE t1 (a INT, b INT); +SHOW TABLES; +Tables_in_test +t1 +INSERT INTO t1 VALUES (1,1), (2,2); +USE test_ignore; +CREATE TABLE t2 (a INT, b INT); +SHOW TABLES; +Tables_in_test_ignore +t2 +INSERT INTO t2 VALUES (3,3), (4,4); +SHOW BINLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 102 Server ver: 5.1.5-alpha-debug-log, Binlog ver: 4 +master-bin.000001 102 Query 1 195 use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 195 Table_map 1 235 test.t1 +master-bin.000001 235 Write_rows 1 282 +**** On Slave **** +SHOW DATABASES; +Database +information_schema +mysql +test +USE test; +SHOW TABLES; +Tables_in_test +t1 +USE test_ignore; +ERROR 42000: Unknown database 'test_ignore' +DROP DATABASE test_ignore; diff --git a/mysql-test/t/rpl_row_basic_11bugs-master.opt b/mysql-test/t/rpl_row_basic_11bugs-master.opt new file mode 100644 index 00000000000..d5ae999b180 --- /dev/null +++ b/mysql-test/t/rpl_row_basic_11bugs-master.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test_ignore; diff --git a/mysql-test/t/rpl_row_basic_11bugs.test b/mysql-test/t/rpl_row_basic_11bugs.test new file mode 100644 index 00000000000..76ff5a581c9 --- /dev/null +++ b/mysql-test/t/rpl_row_basic_11bugs.test @@ -0,0 +1,31 @@ +--source include/have_row_based.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# Bug#15942 (RBR ignores --binlog_ignore_db and tries to map to table +# on slave for writes) + +CREATE DATABASE test_ignore; # --binlog_ignore_db=mysqltest_ignore + +--echo **** On Master **** +SHOW DATABASES; +USE test; +CREATE TABLE t1 (a INT, b INT); +SHOW TABLES; +INSERT INTO t1 VALUES (1,1), (2,2); +USE test_ignore; +CREATE TABLE t2 (a INT, b INT); +SHOW TABLES; +INSERT INTO t2 VALUES (3,3), (4,4); +SHOW BINLOG EVENTS; +sync_slave_with_master; +--echo **** On Slave **** +SHOW DATABASES; +USE test; +SHOW TABLES; +--error 1049 +USE test_ignore; + +connection master; +DROP DATABASE test_ignore; +sync_slave_with_master; diff --git a/sql/handler.cc b/sql/handler.cc index 59445a1b2f1..70e445dd321 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2797,7 +2797,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) - Row-based replication is on - It is not a temporary table - The binlog is enabled - - The table shall be binlogged (binlog_*_db rules) [Seems disabled /Matz] + - The table shall be binlogged (binlog_*_db rules) */ #ifdef HAVE_ROW_BASED_REPLICATION @@ -2806,7 +2806,8 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table) return binlog_row_based && thd && (thd->options & OPTION_BIN_LOG) && - (table->s->tmp_table == NO_TMP_TABLE); + (table->s->tmp_table == NO_TMP_TABLE) && + binlog_filter->db_ok(table->s->db.str); } template int binlog_log_row(TABLE* table,