summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2010-04-26 10:02:29 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2010-04-26 10:02:29 +0100
commit68598c479bec557e22621678596fde95e0e5ee13 (patch)
tree7be6c5ebc708fc83a35cbbb9dd7f99f19c59149b
parent17aa4173a4a4dd71a64ab1f1eb9d9dd1b2405fc4 (diff)
downloadmariadb-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.result42
-rw-r--r--mysql-test/suite/rpl/t/rpl_temp_temporary.test29
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h5
-rw-r--r--sql/sql_parse.cc2
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)
{