diff options
author | Alfranio Correia <alfranio.correia@sun.com> | 2010-04-26 10:02:29 +0100 |
---|---|---|
committer | Alfranio Correia <alfranio.correia@sun.com> | 2010-04-26 10:02:29 +0100 |
commit | 68598c479bec557e22621678596fde95e0e5ee13 (patch) | |
tree | 7be6c5ebc708fc83a35cbbb9dd7f99f19c59149b | |
parent | 17aa4173a4a4dd71a64ab1f1eb9d9dd1b2405fc4 (diff) | |
download | mariadb-git-68598c479bec557e22621678596fde95e0e5ee13.tar.gz |
BUG#53075 SBR: Strange warning around CONNECTION_ID
Statements with CONNECTION_ID were forced to be kept in the transactional
cache and by consequence non-transactional changes that were supposed to
be flushed ahead of the transaction were kept in the transactional cache.
This happened because after BUG#51894 any statement whose thd's
thread_specific_used was set was kept in the transactional cache. The idea
was to keep changes on temporary tables in the transactional cache. However,
the thread_specific_used was set not only for statements that accessed
temporary tables but also when the CONNECTION_ID was used.
To fix the problem, we created a new variable to keep track of updates
to temporary tables.
mysql-test/suite/rpl/r/rpl_temp_temporary.result:
Added a test case.
mysql-test/suite/rpl/t/rpl_temp_temporary.test:
Added a test case.
sql/log_event.cc:
Uses the thread_temporary_used to decide if a statement should
be kept in the transactional cache or not.
sql/sql_class.cc:
Sets the thread_temporary_used while calling the decide_logging_format.
sql/sql_class.h:
Defines the thread_temporary_used.
sql/sql_parse.cc:
Resets the thread_temporary_used.
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_temp_temporary.result | 42 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_temp_temporary.test | 29 | ||||
-rw-r--r-- | sql/log_event.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 |
6 files changed, 80 insertions, 3 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_temp_temporary.result b/mysql-test/suite/rpl/r/rpl_temp_temporary.result index e5a6bcd21e8..1f3a58fe25a 100644 --- a/mysql-test/suite/rpl/r/rpl_temp_temporary.result +++ b/mysql-test/suite/rpl/r/rpl_temp_temporary.result @@ -174,6 +174,48 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp2` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp3` /* generated by server */ master-bin.000001 # Query # # ROLLBACK +######################################################################## +# VERIFY ITEM 7 +######################################################################## +SET BINLOG_FORMAT=STATEMENT; +CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam; +CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM; +CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb; +BEGIN; +INSERT INTO t_myisam VALUES(CONNECTION_ID()); +INSERT INTO tmp1 VALUES(1); +INSERT INTO t_myisam VALUES(1); +Warnings: +Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction. +INSERT INTO t_innodb VALUES(1); +INSERT INTO t_myisam VALUES(CONNECTION_ID()); +Warnings: +Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction. +INSERT INTO t_innodb VALUES(1); +COMMIT; +DROP TABLE t_myisam; +DROP TABLE t_innodb; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam +master-bin.000001 # Query # # use `test`; CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM +master-bin.000001 # Query # # use `test`; CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(CONNECTION_ID()) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(1) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(CONNECTION_ID()) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tmp1 VALUES(1) +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1) +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; DROP TABLE t_myisam +master-bin.000001 # Query # # use `test`; DROP TABLE t_innodb ################################################################################### # CHECK CONSISTENCY ################################################################################### diff --git a/mysql-test/suite/rpl/t/rpl_temp_temporary.test b/mysql-test/suite/rpl/t/rpl_temp_temporary.test index fcc55e6fbff..393a5131352 100644 --- a/mysql-test/suite/rpl/t/rpl_temp_temporary.test +++ b/mysql-test/suite/rpl/t/rpl_temp_temporary.test @@ -34,6 +34,10 @@ # the CREATE TEMPORARY is not logged and the DROP TEMPORARY is extended with # the IF EXISTS clause. # +# 7 - It also verifies if the CONNECTION_ID along with a non-transactional +# table is written outside the transaction boundaries and is not classified +# as unsafe. See BUG#53075. +# ################################################################################ source include/master-slave.inc; @@ -163,6 +167,29 @@ DROP TEMPORARY TABLE tmp3; ROLLBACK; source include/show_binlog_events.inc; +--echo ######################################################################## +--echo # VERIFY ITEM 7 +--echo ######################################################################## + +SET BINLOG_FORMAT=STATEMENT; +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); + +CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam; +CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM; +CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb; + +BEGIN; +INSERT INTO t_myisam VALUES(CONNECTION_ID()); +INSERT INTO tmp1 VALUES(1); +INSERT INTO t_myisam VALUES(1); +INSERT INTO t_innodb VALUES(1); +INSERT INTO t_myisam VALUES(CONNECTION_ID()); +INSERT INTO t_innodb VALUES(1); +COMMIT; +DROP TABLE t_myisam; +DROP TABLE t_innodb; +source include/show_binlog_events.inc; + --echo ################################################################################### --echo # CHECK CONSISTENCY --echo ################################################################################### @@ -172,3 +199,5 @@ sync_slave_with_master; --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql --diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql + + diff --git a/sql/log_event.cc b/sql/log_event.cc index 3a52b72909a..7e01d956615 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) server_id= thd->server_id; when= thd->start_time; cache_type= (using_trans || stmt_has_updated_trans_table(thd) - || thd->thread_specific_used + || thd->thread_temporary_used ? Log_event::EVENT_TRANSACTIONAL_CACHE : Log_event::EVENT_STMT_CACHE); } @@ -2553,7 +2553,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, else { cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || - force_trans || thd->thread_specific_used) + force_trans || thd->thread_temporary_used) ? Log_event::EVENT_TRANSACTIONAL_CACHE : Log_event::EVENT_STMT_CACHE); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 88f67175d02..ef6dc6cf209 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3736,6 +3736,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) trans_non_trans_access_engines= (prev_trans != act_trans); multi_access_engine= TRUE; } + thread_temporary_used |= table->table->s->tmp_table; prev_access_table= table->table; } diff --git a/sql/sql_class.h b/sql/sql_class.h index c75d91baada..0a098fc8492 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2108,6 +2108,11 @@ public: /** is set if some thread specific value(s) used in a statement. */ bool thread_specific_used; + /** + is set if a statement accesses a temporary table created through + CREATE TEMPORARY TABLE. + */ + bool thread_temporary_used; bool charset_is_system_charset, charset_is_collation_connection; bool charset_is_character_set_filesystem; bool enable_slow_log; /* enable slow log for current statement */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 85e6866f3db..1f53a7c7337 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5530,7 +5530,7 @@ void THD::reset_for_next_command() thd->transaction.all.modified_non_trans_table= FALSE; } DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx); - thd->thread_specific_used= FALSE; + thd->thread_specific_used= thd->thread_temporary_used= FALSE; if (opt_bin_log) { |